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

如果处理不好编码解码的问题,爬虫轻则显示乱码,重则报错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  汽车之家

  1. url1='https://www.baidu.com'
    url2='http://www.autohome.com.cn/beijing/#pvareaid=100519'
    contentx=requests.get(url2).content
  2.  
  3. print unicode(contentx)
  1. print contentx.encode('gbk')
  1. print contentx.encode('utf8')
  1. 先说请求url1的情况
  2.  
  3. 先上这六行代码,如果是请求url1,那么在py2.7.13上不会报错,在py2.7.12上会报错,但在pycharm的控制台print的结果乱不乱码我就不保证了,pycharm的设置中有project encoding选项,如果你设置的是utf8或者gbk,那么第二个和第三个势必会有一个是乱码的显示。同一个py代码如果你在pychamr编辑器设置的是utf8,结果正常显示,那么在cmd运行python xx.py看到的结果那就必然会乱码了。

  1. 上面说的是py2.7.13,如果你是2.7.12,那么结果就不是这样的了,在2.7.12中,上面六行代码不会是显示乱码那么简单了,而是直接报错
  2.  
  3. 2.7.12中运行下面这句
  1. print requests.get(url1).content.encode('gbk')
    或者运行unicode(requests.get(url1).content)
    会提示

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

  1. 可以在python脚本中运行这句话
  1. import sys
    print sys.getdefaultencoding()
  2.  
  3. 2.7.13

2.7.12的

  1.  
  2. py2.7.13的打印结果是utf8,而py2.7.12的打印结果却是asciiurl1的网页编码是utf8,用ascii解码会出错。
  3.  
  4. 要使py2.7.12中不报这个错误,那么可以加入下面这句经典的代码

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

  1. print requests.get(url1).content.encode('gbk')把这个改成print requests.get(url1).content.decode('utf8').encode('gbk'),这样就不不会按照默认的编码解码了,就可以不需要上面的reloadsetdefaultcoding
  1. import sys
    print sys.getdefaultencoding()
    reload(sys)
    sys.setdefaultencoding('utf8')
  2.  
  3. 这三行代码不是万金油,不能以为写了这几句就万事大吉不会出编码问题了,如果请求的是url2,汽车之家网页是gbk格式的,
  1. 如果用print requests.get(url2).content.encode('utf8'),那一样会报错从content字符串按照指定的utf8来解码成unicode,那就会报错了,这时候就需要sys.setdefaultencoding('gbk'),而不是utf8了。
  1. 但你应该程序既要请求url1又要请求url2,那么不管你怎么指定默认的,如果不专门指定contentdecode方式,势必会有一个报错。
    那么解决这个最需要的做的事情是
  1. print requests.get(url1).content.decode('utf8').encode('xxxx') xxx代表你想编码的方式
  1. print requests.get(url2).content.decode('gbk').encode('xxxx')
  1. 这样做实用性就非常强了,不管你是2.7.12还是2.7.13,不管你写不写sys.setdefaultencoing和默认指定成什么,都不会出现编码问题了。
  1.  
  2. 第二部分:如何知道网页的编码
  3.  
  4. 使用360浏览器的右键很方便有一个编码查看的功能,你们可以试试把gbk改成utf8或者utf8改成gbk,那么浏览器会就出现乱码了。用360浏览器点击右键,99%的情况下就是网页的编码了,我是用360多年很少发现360出这种乱码错误。

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

  1. 目前我做的事舆情分析,要爬取上万个网站的新闻,用浏览器查看那肯定就不行了,进入什么网页都是未知的,如果是定向爬取,可以代码指定用什么格式decode
  2.  
  3. 可以用下面这句话来获取网页编码格式re.findall('<meta[\s\S]*?charset="?(.*?)"',content,re.IGNORECASE)[0]
    或者re.search('<meta[\s\S]*?charset="?[a-zA-Z\-]*',content,re.IGNORECASE)

  1. 之前同事介绍了一个编码获取的包,名字叫chardet,用法是chardet.detectcontent),这个方法非常准确,但是缺点太大了,长时间占用cpu计算,cpu使用率太高,整个爬虫速度被扯下来了。当页面内容比较大的时候,用chardet来,甚至探测一个编码方式需要15秒之久,这方法不好。
  2. 为了看到chardet到底在干什么要那么久,把日志打印出来。
    代码贴出来,对这个包感兴趣的可以看看。
  1. #coding=utf8
  2. import requests
  3. import chardet,logging
  4. logger=logging.getLogger('')
  5. logger.setLevel(logging.DEBUG)
  6. stream_handler=logging.StreamHandler()
  7. stream_handler.setLevel(logging.DEBUG)
  8. fmt=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  9. stream_handler.setFormatter(fmt)
  10. logger.addHandler(stream_handler)
  11.  
  12. url1='https://www.baidu.com'
  13. url2='http://www.autohome.com.cn/beijing/#pvareaid=100519'
  14. contentx=requests.get(url2).content
  15. bianma=chardet.detect(contentx)
  16. print bianma

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

  1.  

python编码问题1的更多相关文章

  1. (转载) 浅谈python编码处理

    最近业务中需要用 Python 写一些脚本.尽管脚本的交互只是命令行 + 日志输出,但是为了让界面友好些,我还是决定用中文输出日志信息. 很快,我就遇到了异常: UnicodeEncodeError: ...

  2. Python 编码简单说

    先说说什么是编码. 编码(encoding)就是把一个字符映射到计算机底层使用的二进制码.编码方案(encoding scheme)规定了字符串是如何编码的. python编码,其实就是对python ...

  3. Python之路3【知识点】白话Python编码和文件操作

    Python文件头部模板 先说个小知识点:如何在创建文件的时候自动添加文件的头部信息! 通过:file--settings 每次都通过file--setings打开设置页面太麻烦了!可以通过:View ...

  4. python编码规范

    python编码规范 文件及目录规范 文件保存为 utf-8 格式. 程序首行必须为编码声明:# -*- coding:utf-8 -*- 文件名全部小写. 代码风格 空格 设置用空格符替换TAB符. ...

  5. 【转】python编码的问题

    摘要: 为了在源代码中支持非ASCII字符,必须在源文件的第一行或者第二行显示地指定编码格式: # coding=utf-8 或者是: #!/usr/bin/python # -*- coding: ...

  6. 【转】python编码规范

    http://blog.csdn.net/willhuo/article/details/49300441 决定开始Python之路了,利用业余时间,争取更深入学习Python.编程语言不是艺术,而是 ...

  7. python 编码 UnicodeDecodeError

    将一个py脚本从Centos转到win运行,出错如下: UnicodeDecodeError: 'gbk' codec can't decode byte 0xff in position 0: il ...

  8. Python编码/文件读取/多线程

    Python编码/文件读取/多线程 个人笔记~~记录才有成长   编码/文件读取/多线程 编码 常用的一般是gbk.utf-8,而在python中字符串一般是用Unicode来操作,这样才能按照单个字 ...

  9. 关于Python编码,超诡异的,我也是醉了

    Python的编码问题,真是让人醉了.最近碰到的问题还真不少.比如中文文件名.csv .python对外呈现不一致啊,感觉好不公平. 没图说个JB,下面立马上图.   我早些时候的其他脚本,csv都是 ...

  10. 规范的python编码

    规范的 python 编码令人赏心悦目,令代码的表达逻辑更清晰,使得工程代码更容易被维护和交流: 编码规范包括对于代码书写格式的约束,不良语法的禁用和推荐的编码手法,下面做些简要的描述: 1. 代码规 ...

随机推荐

  1. div设置contentEditable="true"作为文本编辑器,定位光标解决办法

    function set_focus(el) {    el = el[0]; // jquery 对象转dom对象    el.focus();    if ($.browser.msie) {   ...

  2. response.setContentType 与response.setCharacterEncoding

    response.setContentType  设置发送到客户端的响应的内容类型,可以包括字符编码说明.  也就是说在服务器端坐了这个设置,那么他将在浏览器端起到作用,在你打开浏览器时决定编码方式 ...

  3. JavaScript高级 面向对象(2)--调试工具的使用:音乐循环播放

    说明(2017.3.29): 1. 在调试工具console里输入var v = document.createElement("audio"),然后再source的watch里输 ...

  4. 未在本地计算机上注册"Microsoft.Jet.OLEDB.4.0"

    答案一: 因为没有安装64位的Jet40驱动.可以到http://www.microsoft.com/downloads/zh-cn/details.aspx?FamilyID=c06b8369-60 ...

  5. kubernetes 数据持久化

    pod本身是无状态,所以很多有状态的应用,就需要将数据进行持久化. 1:将数据挂在到宿主机.但是pod重启之后有可能到另外一个节点,这样数据虽然不会丢但是还是有可能会找不到 apiVersion: v ...

  6. Android——监听事件OnLongClickListener

    .xml <Button android:layout_width="wrap_content" android:layout_height="wrap_conte ...

  7. AM335x移植linux内核_转

    AM335x移植linux内核 该博客中详细介绍了移植linux内核到AM335x上相关,设备驱动采用设备树(DT)方式加载,包含设备启动.uboot.kernel.driver.rootfs及简单上 ...

  8. Mac下面的SecureCRT(附破解方案) 更新到最新的7.2的破解方案

    继续更新到7.2的破解.只是升级了下secureCRT到7.2,方法还是不变 相信很多人升级到了7.2的SecureCRT之后原来的破解方案失效了,一直也有人问新的破解方案,发现了,不敢独享放上crt ...

  9. 批量改名的多种方法stu_3_finished.jpg 去掉finished,stu_{1..20}_finished.jpg

    方法一:rename修改文件名 rename "finished" "" *.jpg [root@ob1 scripts]# rename "fini ...

  10. 将BAT文件注册为服务的方法

    一.什么是instsrv.exe和srvany.exe instsrv.exe.exe和srvany.exe是Microsoft Windows Resource Kits工具集中 的两个实用工具,这 ...