python requests 发送中文参数的问题

一句话:python requests发送给中文网站的参数,需要先encode为网站对应的编码。

之前设计了一个[针对朗珈病理查询系统的爬虫](https://chchuj.coding.me/20171202-Hospital-information-system-crawler-for-Gleason-Score/)。设计时向网站提交的刚好是住院号和病理号这些非中文参数,所以当时没有遇到中文参数这个坑。现在开始折腾影像系统的爬虫,就遇到了中文参数的问题。

我先使用一个字典来放post的参数:

post_data = {  # post_data内容直接复制F12大法里面的data
        'keywords_name': '张三'
        'keywords_brbh': '',
        'keywords_zyh': '',
        'keywords_mzh': '',
        'keywords_blh': '',
        'keywords_sjks': '',
        'keywords_rqxz': '', # '%CA%D5%B5%BD%C8%D5%C6%DA'
        'keywords_bgrq1': '',
        'keywords_bgrq2': '',
        'Submit': '' # '%B2%E9%D1%AF'
    }

然后使用request.post来请求数据:

response = requests.post(request_url, data=post_data, headers=headers)

结果发现各种姿势的中文参数都传不对:

直接在查询的网页里面输入中文姓名(如“张三”)并查询,用Fiddler抓包,可以看到上传的中文参数是这样的:keywords_name=%D5%C5%C8%FD,是某种编码

在python里面设置: 'keywords_name': '张三', Run之后看到上传的参数变成 keywords_name=%E5%BC%A0%E4%B8%89。长得和网站的编码貌似不一样。

直接把网站用的编码 'keywords_name': '%D5%C5%C8%FD'POST上去呢?也不行,抓包可以看到这个字符串变了:keywords_name=%25D5%25C5%25C8%25FD。在字符串前面加r 、在py文件加 # coding=utf-8 都不行。

Google第一页的结果也没有直接的解决方法。《python使用requests模块参数编码的不同处理》这篇比较新的博客文章讲了requests编码处理的几种方法,然而没有讲到点子上。但是在它和《关于在 python 中使用 requests 框架传入中文参数问题》的启发下,终于找到了解决方法。

原来 requests.post会把data参数重新编码,字符串中的%也会变(加了转义符也没用),而它编码之后也跟网站的编码对不上,所以才不行。

首先,先获得网站使用的编码。有的网站如某影像查询系统是写在响应头里面 charset=GBK,有的网站如朗珈病理查询系统是写在HTML的META标签时里面 charset=gb2312。找不到还可以用 response.apparent_encoding 来获取网站编码。

然后,在data字典的键值中指定编码:

post_data = {  # post_data内容直接复制F12大法里面的data
        'keywords_name': '张三'.encode('GB2312'),  #charset=gb2312 in response META
        'keywords_brbh': '',
        'keywords_zyh': '',
        'keywords_mzh': '',
        'keywords_blh': '',
        'keywords_sjks': '',
        'keywords_rqxz': '', # '%CA%D5%B5%BD%C8%D5%C6%DA'
        'keywords_bgrq1': '',
        'keywords_bgrq2': '',
        'Submit': '' # '%B2%E9%D1%AF'
    }

使用其他的库如urllib3也能解决这个问题,但貌似也不方便。

原文发表于:python requests 发送中文参数的问题

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。