Python+Requests抓取中文乱码改进方案

前两天更新了下网址缩短这个项目的requests版本后抓取要缩短的网址title时候乱码的比例大幅上升。但有不想靠降级版本来解决。

之前最早开始用Requests做抓取内容工具时候也碰到过一些中文乱码的情况,最后搜索到的Python中文乱码的最常见的解决方案就是重置页面编码

import sys

reload(sys)

sys.setdefaultencoding('utf-8')

同样的,俺做网址缩短项目时候抓取要缩短网址的Title时候也是采用这样的方式。

但是升级了Requests版本之后出现了大量的GBK编码url的Title无法正常识别的情况。在本地也升级了最新的Requests版本后写了一个函数做了一些测试,发现重置页面默认编码之后虽然抓取到了某些GBK编码的页面内容,抓取后的结果也是unicode格式,但是转换成正常gbk时候出现各种莫名其妙错误。

这时候使用r.encoding输出抓取的页面编码总是iso-8859-1,而不是gbk或者gb2312……各种调试后写了一个简单函数,虽然依然很多中文依然乱码,但相比之前的比例有了很大的提升了……

f = requests.get(url, timeout = 3, allow_redirects = True)

content = f.content

if f.encoding.lower() != 'utf-8':

charset = re.compile(r'content="text/html;.?charset=(.*?)"').findall(content)

print charset, f.encoding.lower(), f.headers['content-type']

try:

if len(charset)>0 and charset[0].lower()!=f.encoding.lower():

content = content.decode('gbk').encode('utf-8')

except:

pass

doc=libxml2dom.parseString(content, html=1)

title_name=doc.xpath('//title')[0].textContent.encode('utf-8')

已有14条评论 »

  1. steff

    html_doc=str(req.content,'utf-8')一句可以搞定

  2. ```python import requests from requests.utils import get_encoding_from_headers, get_encodings_from_content def get_encoding_from_reponse(reponse): encoding = get_encodings_from_content(reponse.content) if encoding: reponse.encoding = encoding[0] else: reponse.encoding = get_encoding_from_headers(reponse.headers) r = requests.get("http://1212.ip138.com/ic.asp") r.encoding = get_encoding_from_reponse(r) print r.text ```

  3. import requests from requests.utils import get_encoding_from_headers, get_encodings_from_content def get_encoding_from_reponse(reponse): encoding = get_encodings_from_content(reponse.content) if encoding: reponse.encoding = encoding[0] else: reponse.encoding = get_encoding_from_headers(reponse.headers) r = requests.get("http://1212.ip138.com/ic.asp") r.encoding = get_encoding_from_reponse(r) print r.text

  4. NA

    设置r.encoding='gbk'或r.encoding='gb2312'即可

  5. 直接设定response.encode=页面的字符编码

  6. MoonXue的解决方法是有效的。O(∩_∩)O谢谢。

  7. 关于此问题我也写了一篇分析文章:http://liguangming.com/python-requests-ge-encoding-from-headers

  8. DFire

    用content解决了,然后自己在去解码或者编码什么的就oK

  9. reverland

    @Chairo 原来是这样……搞跪了……谢谢……

  10. MoonXue

    requests的乱码问题是由于运行环境中缺少一个叫chardet的用于探测字符集的第三库导致的,事实上这个第三方库也不怎么靠谱。解决方案有两种,第一:直接用response.content取没有被解码成unicode的返回值;第二:把requests的models.py给hack一下,写出自己的一套检测字符集的function。

  11. @laodao 用文章中方法处理,有改善,但没全部ok

  12. laodao

    博主为解决了吗?听人说requests强大,结果第二个页面就开始乱码,哎,还是换回urllib2吧

  13. @ushuz 很诡异,有的content-type有编码信息,但依然requests的encoding是iso-8859-1……

  14. ushuz

    貌似当服务器返回的content-type只是text/html而没有编码信息的时候requests就会直接把encoding设为iso-8859-1

添加新评论 »