V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
asus10tu
V2EX  ›  Python

想问 requests 请求库,有没办法在 GET 请求时使用中文明文,不进行 URL 编码

  •  
  •   asus10tu · 2020-02-03 16:37:41 +08:00 · 4610 次点击
    这是一个创建于 1784 天前的主题,其中的信息可能已经有所发展或是发生改变。
    就是 GET 请求的时候,直接以中文形式发出,不变成%E7%B2 之类。

    我在网上查询过,只找到 POST 请求时 body 体以中文明文发出,但是始终没找到 GET 请求的相关方法。

    请问有大哥知道怎么解决么,感谢!
    20 条回复    2020-02-04 18:07:44 +08:00
    kerr92
        1
    kerr92  
       2020-02-03 16:46:58 +08:00 via iPhone
    GET 请求参数是拼在 URL 中的,而 URL 本身只支持 ASCII 字符集,必须进行编码,不可能直接使用中文明文
    qsnow6
        2
    qsnow6  
       2020-02-03 16:53:04 +08:00
    中文是用 UNICODE 存储的
    asus10tu
        3
    asus10tu  
    OP
       2020-02-03 17:02:55 +08:00
    @kerr92 正常好像是先进行 URL 编码转换,再用 ASCII 转换一次,发出请求。
    现在想希望是不进行 URL 编码转换,然后用 gbk 转换一次,发出请求
    wzwwzw
        4
    wzwwzw  
       2020-02-03 17:12:36 +08:00
    get 可以加 body 的,但是有很多不支持。也不建议这样子做。
    momocraft
        5
    momocraft  
       2020-02-03 17:15:58 +08:00
    这样做违反 http 的 RFC
    ClericPy
        6
    ClericPy  
       2020-02-03 17:27:04 +08:00
    直接说最终目的算了, 你上来就问底层可能方向都错了, 何况还是违反协议的
    比如想在什么地方看到原始中文
    Cooky
        7
    Cooky  
       2020-02-03 17:28:41 +08:00 via Android
    不用 requests 直接用标准库看看
    imn1
        8
    imn1  
       2020-02-03 17:40:37 +08:00   ❤️ 1
    不太可能
    写过 socket 应该知道,最终发送是字节,如果不编码、不按标准,发送字节时就可能带上控制符字节,服务器端会产生判断错误
    例如路径符 C5、C7 这样的字节,在 GBK 或东亚字符中很多都有,很容易引起判断错误,导致 404 还是小事
    asus10tu
        9
    asus10tu  
    OP
       2020-02-03 18:05:40 +08:00
    @ClericPy 是这样的,我最近接触一个网站爬虫,里面使用了 YAHOO.util.Connect.asyncRequest,这样的一个库进行 POST 请求,我用抓包软件进行查看,看到他把内容全部拼接在 url 上,body 体为空,但是 url 上的中文部分是乱码,比如粤字,抓包软件上显示的是:ÔÁ,所以我怀疑他是中文直接发送的,无奈也找不到方法。
    xfspace
        10
    xfspace  
       2020-02-03 18:40:23 +08:00 via Android
    @asus10tu 转件 decode 问题
    zhengxiaowai
        11
    zhengxiaowai  
       2020-02-03 19:19:12 +08:00
    不行,目前所有的工具包括命令行,还是 GUI 的软件都会转换,这是客户端。
    对于服务端的解析方式也是这么搞的,要不然他就不认识。

    这样才是 HTTP 协议。

    如果硬要做,你需要写一个 HTTP Extend。。
    ClericPy
        12
    ClericPy  
       2020-02-03 21:44:37 +08:00   ❤️ 1
    @asus10tu #9
    乱码一般是用了默认(但不一定正确)的编码强行解码导致的, 感觉你抓包工具的问题, 毕竟不解码一般没法给用户看

    以前遇到过一种就是阿里巴巴爬虫, 当时他们的 url 是 urlencode 之前先 gbk 编码了一次, 也就是 encode 了两层, 不知道和你这情况类似么

    你的抓包工具有可能为了给用户容易看, 强行 urldecode 了一次, 然后解出来的和阿里巴巴 url 一样少解码一次的情况下, 直接盲目 decode 输出给用户了

    目前因为是盲猜瞎调试, 所以只能排除法, 先换个靠谱点的抓包工具, 尤其是别轻易 decode, 拿到 bytes 自己用一些编码尝试性解码看看

    你的粤逆向 decode 一下就知道了

    print('ÔÁ'.encode('latin-1').decode('gbk'))

    基本可以定位是你抓包工具只认 latin-1 或者 u8, 然而该 api 走了 gbk..... 换个靠谱抓包工具吧
    also24
        13
    also24  
       2020-02-03 22:13:04 +08:00
    说个题外话,真心建议问问题的时候直接说原始问题,不要加太多自己的主观判断。

    根据楼主在 9 楼的补充,很显然这里又是一个血淋淋的 X-Y Problem

    https://coolshell.cn/articles/10804.html
    haozhang
        14
    haozhang  
       2020-02-03 22:41:37 +08:00 via Android
    HTTP 建立在 TCP 之上,而 TCP 是 ASCII 的,所以你不可能这么整,其次,任何 http request message 也就是 http 请求都是有 body 的,无论 post 还是 get。意思就是 get 也能写 body。
    asus10tu
        15
    asus10tu  
    OP
       2020-02-04 11:04:45 +08:00
    @ClericPy 感谢大哥详细的解释,又明白了一点了。

    可是我目前用的抓包软件已经是 httpAnalyzer 和 Fiddler,需要换哪个工具更好用呢。

    但是我自己写请求用上述工具抓自己的包,看到 url 都是以 urldecode 编码方式显示的,比如 ?name=粤 AAA 抓包看到是 ?name=%E7%B2%A4AAA,可是目标网站抓出来的却是?name=??AAA,是不是说明他没有 urldecode 呢,我自己无论先进行一层 utf8 编码或者 gbk 编码,均无法达到这种效果。
    asus10tu
        16
    asus10tu  
    OP
       2020-02-04 11:05:13 +08:00
    @also24 好的,感谢。
    0xZhangKe
        17
    0xZhangKe  
       2020-02-04 14:39:23 +08:00
    HTTP 请求头只能是 ASCII 字符集
    asus10tu
        18
    asus10tu  
    OP
       2020-02-04 14:55:28 +08:00
    @ClericPy 噢问题解决了
    我发现中文参数直接使用 ‘粤’.encode('gbk')这样是不行的,得用 requests.utils.quote("粤",encoding='gbk')这句话才有效果,估计 bytes 格式问题,感谢解答!
    asus10tu
        19
    asus10tu  
    OP
       2020-02-04 14:55:57 +08:00
    @0xZhangKe 问题已经解决啦,感谢各位的回复
    ClericPy
        20
    ClericPy  
       2020-02-04 18:07:44 +08:00
    @asus10tu #15
    工具有的是吧
    早年要抓 TCP, 所以用的 wireshark
    后来基本只抓网站, 所以浏览器的调试工具足够用了
    后来因为要在三个平台抓包, 就用了 Charles
    再后来证书什么的有点问题, 试了 fiddler 的自定义规则, 还是不好使
    然后发现阿里开源了个 AnyProxy, 真香, 用了几天又因为系统洁癖把 node js 删了...
    后来部署生产环境用到 mitmproxy, 比以前随手学的时候香多了, 从那以后基本只用 mitmproxy 了, 在服务器上 nginx 做下域名映射, app 什么的直接挂服务器代理, 还能改流量(比如给某些页面注入点 js)
    再后来看到 utools 有抓包工具, 然而又对爬虫深恶痛绝... 就没有然后了

    requests.utils.quote 其实内置库里也有, 平时更常用的是 quote_plus, 区别一搜就知道了
    你乱码明显就是 fiddler 强行解码的锅, 它想强行解码也是为了用户可读, 你试试在请求上右键 copy 什么的能拿到原始的结果没有

    我后来用 Charles 最舒服的其实还是右键 copy 成 curl, 然后用自己写的 curl parser 转成 Requests 直接用的字典, 什么都不改就可以重发请求了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2906 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 14:07 · PVG 22:07 · LAX 06:07 · JFK 09:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.