python爬虫编码问题_python爬虫编码问题

爬虫,新手很容易遇到编码解码方面的问题。在这里总结下。

如果处理不好编码解码的问题,爬虫轻则显示乱码,重则报错UnicodeDecodeError: ‘xxxxxx‘ codec can‘t decode byte 0xc6 in position 1034: invalid continuation byte,这个xxx可能是 ascii utf8  gbk等。

大家一定要选个专门的时间学习下这方面,网上资源很多的。因为编码 解码岁不关程序逻辑功能大局 ,但几乎每个程序中都会遇到这个东西,所以必须专门花时间学习实践下以避免频繁与麻烦。

1.先来两个网址,选个gb2312的和一个utf8的网址。

utf8网站选择  https://www.baidu.com 百度

gb2312的网站选择 http://www.autohome.com.cn/beijing/#pvareaid=100519  汽车之家

url1=‘https://www.baidu.com‘

url2=‘http://www.autohome.com.cn/beijing/#pvareaid=100519‘

contentx=requests.get(url2).content

print unicode(contentx)

print contentx.encode(‘gbk‘)

print contentx.encode(‘utf8‘)

先说请求url1的情况

先上这六行代码,如果是请求url1,那么在py2.7.13上不会报错,在py2.7.12上会报错,但在pycharm的控制台print的结果乱不乱码我就不保证了,pycharm的设置中有project encoding选项,如果你设置的是utf8或者gbk,那么第二个和第三个势必会有一个是乱码的显示。同一个py代码如果你在pychamr编辑器设置的是utf8,结果正常显示,那么在cmd运行python xx.py看到的结果那就必然会乱码了。

0f4fab358fc7d2bceed019e7ec81242d.png

ca47cb62e21243ef9e6682d3e694cdb0.png

上面说的是py2.7.13,如果你是2.7.12,那么结果就不是这样的了,在2.7.12中,上面六行代码不会是显示乱码那么简单了,而是直接报错

在2.7.12中运行下面这句

print requests.get(url1).content.encode(‘gbk‘)

或者运行unicode(requests.get(url1).content)

会提示

9bbc3e12d77e75ef888ad6565b765cd9.png

因为直接从字符串转另一个编码格式格式,先会用默认的编码decode解码,再用指定的encode格式来编码了。

可以在python脚本中运行这句话

import sys

print sys.getdefaultencoding()

2.7.13的

0bab0cf551d7a51249f54becb6eb246c.png

2.7.12的

370db6de96ab886e32bd20de49eef1e4.png

py2.7.13的打印结果是utf8,而py2.7.12的打印结果却是ascii,url1的网页编码是utf8,用ascii解码会出错。

要使py2.7.12中不报这个错误,那么可以加入下面这句经典的代码

69bb232d6c300d696872c83ba12e1242.png

加入后,就不会出现 ascii codec cant decode 的提示了;如果不加入上面这句话,想把得到的内容encode成gbk格式的,可以按下面这么做

print requests.get(url1).content.encode(‘gbk‘)把这个改成print requests.get(url1).content.decode(‘utf8‘).encode(‘gbk‘),这样就不不会按照默认的编码解码了,就可以不需要上面的reload和setdefaultcoding。

import sys

print sys.getdefaultencoding()

reload(sys)

sys.setdefaultencoding(‘utf8‘)

这三行代码不是万金油,不能以为写了这几句就万事大吉不会出编码问题了,如果请求的是url2,汽车之家网页是gbk格式的,

如果用print requests.get(url2).content.encode(‘utf8‘),那一样会报错从content字符串按照指定的utf8来解码成unicode,那就会报错了,这时候就需要sys.setdefaultencoding(‘gbk‘),而不是utf8了。

但你应该程序既要请求url1又要请求url2,那么不管你怎么指定默认的,如果不专门指定content的decode方式,势必会有一个报错。

那么解决这个最需要的做的事情是

print requests.get(url1).content.decode(‘utf8‘).encode(‘xxxx‘) xxx代表你想编码的方式

print requests.get(url2).content.decode(‘gbk‘).encode(‘xxxx‘)

这样做实用性就非常强了,不管你是2.7.12还是2.7.13,不管你写不写sys.setdefaultencoing和默认指定成什么,都不会出现编码问题了。

第二部分:如何知道网页的编码

使用360浏览器的右键很方便有一个编码查看的功能,你们可以试试把gbk改成utf8或者utf8改成gbk,那么浏览器会就出现乱码了。用360浏览器点击右键,99%的情况下就是网页的编码了,我是用360多年很少发现360出这种乱码错误。

2bfb133ea29fb0d19db35e97e27825b5.png

除了浏览器查看外,还有一个方法是,右键点击查看源代码,下图是百度的,可以看到用的是utf8,那么把response的content用utf8 decode是不会出问题的,如果网页源码中charset是gb2312,用gbk deocde就可以。

83be3c6a4bbcd4ef5deed4da32b29811.png

目前我做的事舆情分析,要爬取上万个网站的新闻,用浏览器查看那肯定就不行了,进入什么网页都是未知的,如果是定向爬取,可以代码指定用什么格式decode

可以用下面这句话来获取网页编码格式re.findall(‘

之前同事介绍了一个编码获取的包,名字叫chardet,用法是chardet.detect(content),这个方法非常准确,但是缺点太大了,长时间占用cpu计算,cpu使用率太高,整个爬虫速度被扯下来了。当页面内容比较大的时候,用chardet来,甚至探测一个编码方式需要15秒之久,这方法不好。

为了看到chardet到底在干什么要那么久,把日志打印出来。

代码贴出来,对这个包感兴趣的可以看看。

#coding=utf8

importrequestsimportchardet,logging

logger=logging.getLogger(‘‘)

logger.setLevel(logging.DEBUG)

stream_handler=logging.StreamHandler()

stream_handler.setLevel(logging.DEBUG)

fmt=logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)

stream_handler.setFormatter(fmt)

logger.addHandler(stream_handler)

url1=‘https://www.baidu.com‘url2=‘http://www.autohome.com.cn/beijing/#pvareaid=100519‘contentx=requests.get(url2).content

bianma=chardet.detect(contentx)print bianma

07473165f28328a512b37baed4cc6021.png

看了此篇后,应该不至于遇到编码问题了。

原文:http://www.cnblogs.com/ydf0509/p/7225654.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值