在用 python2 抓取网页的时候,常常会遇到抓下来的内容显示出来是乱码。php
发生这种状况的最大可能性就是编码问题: 运行环境的字符编码和网页的字符编码不一致。html
好比,在 windows 的控制台(gbk)里抓取了一个 utf-8 编码的网站。或者,在 Mac / Linux 的终端(utf-8)里抓取了一个 gbk 编码的网站。由于多数网站采用 utf-8 编码,而很多人又是用 windows,全部这种状况至关常见。python
若是你发现你抓下来的内容,看上去英文、数字、符号都是对的,但中间夹杂了一些乱码,那基本能够判定是此状况。web
解决这个问题的办法就是,把结果先按网页的编码方式 decode 解码成 unicode,再输出。若是不肯定网页的编码,可参照如下代码:编程
import urllib req = urllib.urlopen("http://some.web.site") info = req.info() charset = info.getparam('charset') content = req.read() print content.decode(charset, 'ignore')
'ignore' 参数的做用是忽略掉没法解码的字符。windows
不过这种方法不老是有效。还有种方式就是经过正则直接匹配网页代码中的编码设置:浏览器
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
除了编码问题形成乱码以外,还有种常被忽视的状况,就是 目标网页启用了 gzip 压缩 。压缩后的网页传输数据少了,打开速度更快。在浏览器中打开时,浏览器会根据网页的 header 信息自动作解压。但直接用代码抓取则不会。所以极可能就被搞糊涂了,为何明明打开网页地址是对的,但程序抓取就不行。连我本身也曾经被这个问题坑过。网站
这种状况的表现是抓取的内容几乎全是乱码,甚至没法显示。ui
要判断网页是否启用了压缩并对其解压,可参考如下代码:编码
import urllib import gzip from StringIO import StringIO req = urllib.urlopen("http://some.web.site") info = req.info() encoding = info.getheader('Content-Encoding') content = req.read() if encoding == 'gzip': buf = StringIO(content) gf = gzip.GzipFile(fileobj=buf) content = gf.read() print content
在咱们教室的编程实例 查天气系列(点击查看) 中,这两个问题困扰了至关多人。在此特别讲解一下。
最后,还有个“利器”要介绍一下。若是一开始就用它,你甚至不知道还有上述两个问题的存在。
这就是 requests 模块。
一样抓取网页,只须要:
import requests print requests.get("http://some.web.site").text
没有编码问题,没有压缩问题。
This is why I love Python.
至于如何安装 requests 模块,请参考以前的文章:
如何安装 Python 的第三方模块 - Crossin的编程教室 - 知乎专栏
pip install requests
其余文章及回答:
[](http://crossin-forum.b0.upaiy...