爬虫rewquests爬去网页乱码问题

requests在爬取网页时候时候中文显示乱码

import requests
url = 'http://www.neihan8.com/wenzi/index_2.html'
res = requests.get(url)
res.encoding #获取res的编码格式
res.headers #获取Content-Type内容
res.apparent_encoding #获取网页正确的编码格式 html
= res.text# 返回的结果是处理过的Unicode类型的数据 print(res)
print(res.encoding)#获得网页源码的格式 打印显示 ISO-8859-1

第一个问题是,为什么会有ISO-8859-1这样的字符集编码?

iso-8859是什么?  他又被叫做Latin-1或“西欧语言” .  对于我来说,这属于requests的一个bug,在requests库的github里可以看到不只是中国人提交了这个issue.  但官方的回复说是按照http rfc设计的。

下面通过查看requests源代码,看这问题是如何造成的 !

requests会从服务器返回的响应头的 Content-Type 去获取字符集编码,如果content-type有charset字段那么requests才能正确识别编码,否则就使用默认的 ISO-8859-1. 一般那些不规范的页面往往有这样的问题. 现在一般的Content-Type 是'text/html'。所以现在一般读取源码以后都是用‘  html = res.text‘ 格式读取。但是也可用通过html = res.content来获取返回的源码。

第二个问题, 那么如何获取正确的编码? 

requests的返回结果对象里有个apparent_encoding函数, apparent_encoding通过调用chardet.detect()来识别文本编码. 但是需要注意的是,这有些消耗计算资源.
至于为毛,可以看看chardet的源码实现. 

 

第三个问题,requests的text() 跟 content() 有什么区别? 

requests在获取网络资源后,我们可以通过两种模式查看内容。 一个是res.text,另一个是res.content,那他们之间有什么区别呢?

分析requests的源代码发现,res.text返回的是处理过的Unicode型的数据,而使用res.content返回的是bytes型的原始数据。也就是说,res.content相对于res.text来说节省了计算资源,res.content是把内容bytes返回. 而res.text是decode成Unicode. 如果headers没有charset字符集的话,text()会调用chardet来计算字符集,这又是消耗cpu的事情.

requests中文乱码解决方法有这么几种

1、由于content是HTTP相应的原始字节串,可以根据headers头部的charset把content decode为unicode,前提别是ISO-8859-1编码.

r.encoding   # 'gbk'
print r.content.decode(r.encoding)

 2、另外有一种特别粗暴方式,就是直接根据chardet的结果来encode成utf-8格式. 

r  = requests.get('http://item.jd.com/1012551875.html')
r.apparent_encoding     #   'GB2312'
r.encoding   # 'gbk'
r.content.decode(r.encoding).encode('utf-8')# 问题 r.encoding和r.apparent_encoding什么区别????

 如果在确定使用text,并已经得知该站的字符集编码时,可以使用 r.encoding = ‘xxx’ 模式, 当你指定编码后,requests在text时会根据你设定的字符集编码进行转换. 

 

>>> import requests
>>> r = requests.get('https://up.xiaorui.cc')
>>> r.text
>>> r.encoding
'gbk'
>>> r.encoding = 'utf-8'

  

posted on 2017-08-19 17:57  地上的大西瓜  阅读(3217)  评论(0编辑  收藏  举报