这里记录的是一个门外汉解决使用 urllib2 抓取网页时遇到乱码、崩溃、求助、解决和涨经验的过程。这类问题,事后看来只是个极小极小的坑,不过竟然花去很多时间,也值得记录一下。过程如下:
目标:

抓取 http://sports.sina.com.cn/g/premierleague/index.shtml

代码:

1
2
3
4
5
6
# coding: u8
import urllib2
url = "http://sports.sina.com.cn/g/premierleague/index.shtml"
response = urllib2.urlopen(url)
html = response.read()
print html

输出:

wױ83’͠L/J
.uVխ[w5;:S煝{7l!Zp8′-y϶=ePUsł;__Zj
::]K챵
eYڕkV%IBUVY”*’)ڤS.
JT>”TTZk+!x*)ld2I,kUUҭ/kXjjkHI U0n2}jUSݲ”>!pj^[LJg’o^=Nqȕ7n|57yy’\ul
j=9T,g/t0ݕ7’^o|v}>8=7흯!tpٹˏgFS?zd~`MuC%U2\ f߉Vqߍ7~2~ɓlE=}M}Xwo}us’>?*zpS:7Oݚ~чb=
HK!sعinQR}@TsY|,#b\d+#yM@qaRTPVNw
?[((tGP,A$O/EXP)oNgA\`Z
4
eL7ȓVn+
ɄeR fT`&WՂbV
f{
j_p@-@[Ib_ͷCZ’!4O1C,کhy b0W(ժZ˨V5-ټX)5{EkvXÝN (PPUCkϫ? j(
V3{Z!LOOP+LP%WPL!\=! @XD8ׯjpT,W+#we~م {CBo@_Y+ijp;^,=(h :NxH|Ar]-|Bkq<
ڻ+}.ܹlt.)cptRXJ4CJЃBv@BXdP&6dógsR^=/fb@s#m} uZh.V80_)$.1W
hS*zQJÑ|ă{nIPa±a#نL<SA
%^yg2*\fxJhQh_FBK(c%cBKwaHeRB 8w6<ϾK @.k*[k|^_¹BV;,pu]24Y
BwԢCm3`>5#FzFG-%Ũ
W0A{TȪ#u4@e24߈*:*6Ђt&XGe@dc%cເh|΀y$HhGv3s$(Y)sYMvE@lC(.tkب6K(E;Op1?:
D6wОƘfO&zqZ3Z>0MC{ڟi#.
tPڻu-u-t38X Wt2h!.>9;TVKrj_$yABZȊ6.ƭI\yK:¬
s#lhsxzb=INse/FUad4H3lnHo0T^”j*]yfrMY!׋-#I(YVaΡ@1kE뗴2=qRtۈh@y@(GX)I-Z$lNX,vg^~cE
/虬&jz=АUdY__\FGA} …

首先想到编码问题,参考了《也谈Python的中文编码处理》一文 ,感觉基本明白怎么回事儿了,按理说

1
isinstance(html, str) == True

并且页面的编码确定为 GBK,那么

1
html.decode('gbk').encode('utf-8')

就可以将机器码以 gbk 解码,再重新以 utf-8 编码,就可以得到正确的文本。可是收到这样的提示:

UnicodeDecodeError: ‘gbk’ codec can’t decode bytes in position 1-2: illegal multibyte sequence

经过在 v2ex 求助,以及反复折腾了一下发现得到的果然是 gzip 过的乱码,于是尝试通过 zlib 解压缩

1
2
import zlib
html = zlib.decompress(html)

可是却得到下面的错误

zlib.error: Error -3 while decompressing data: incorrect header check

无奈,只得用 gzip 库和 StringIO 库绕路解决

1
2
3
import gzip, StringIO
html = gzip.GzipFile(fileobj=StringIO.StringIO(html), mode="r")
html = html.read().decode('gbk').encode('utf-8’)

终于得到了正确的内容和正确的编码~ ^^

问题到这里就解决了,可是对于不能直接使用简洁的 zlib 库表示很不甘心,毕竟根据 python 的文档 gzip 库也是调用 zlib 来解压的,为什么不直接用 zlib 呢?功夫不负有心人,最后终于在 StackOverflow 上找到了答案。于是最终代码如下:

1
2
3
4
5
6
7
8
request = urllib2.Request(url)
request.add_header('Accept-encoding', 'gzip')
opener = urllib2.build_opener()
response = opener.open(request)html = response.read()
gzipped = response.headers.get('Content-Encoding')
if gzipped:
    html = zlib.decompress(html, 16+zlib.MAX_WBITS)
print html

代码里在 request header 中默认加入了接受 gzip,服务器会优先返回 gzip 后的页面,这样极大减少数据流的大小,绝大多数服务器都是支持 gzip 的。之后对于意外情况,也加入了对 response header 的判断,对于不包含“Content-Encoding”的数据流就不会去对其解压缩。这样看上去妥妥的了,但其实还是会有很多意外状况,超出这篇的范围,这里就不涉及了。

后记,后来才知道这是一个很常见的坑,出于对防止抓取的考虑,部分网站采取了各种措施。例如:对于没有指定 Accept-Encoding 的请求也会返回 gzip 过的内容;会验证 Request Header 的 User-Agent 和 Referer 甚至 cookies 之类的。对于抓取感兴趣的可以继续阅读《用Python抓取网页的注意事项》,网页抓取虽然是个很成熟的领域,但门外汉面临诸多未知的挑战,唯有多读多做多积累才好。

转载于:https://www.cnblogs.com/LeeZz/p/5052197.html

使用 python urllib2 抓取网页时出现乱码的解决方案相关推荐

  1. Python 多线程抓取网页 牛人 use raw socket implement http request great

    Python 多线程抓取网页 - 糖拌咸鱼 - 博客园 Python 多线程抓取网页 最近,一直在做网络爬虫相关的东西. 看了一下开源C++写的larbin爬虫,仔细阅读了里面的设计思想和一些关键技术 ...

  2. Python 多线程抓取网页

    Python 多线程抓取网页 - 糖拌咸鱼 - 博客园 Python 多线程抓取网页 最近,一直在做网络爬虫相关的东西. 看了一下开源C++写的larbin爬虫,仔细阅读了里面的设计思想和一些关键技术 ...

  3. python 实时抓取网页数据并进行 筛查

    python 实时抓取网页数据并进行 筛查 爬取数据的两种方法 : 方法 1 : 使用 requests.get() 方法,然后再解码,接着 调用 BeautifulSoup API 首先看 head ...

  4. php取网页内容乱码,如何解决php用file_get_contents方法抓取网页数据出现乱码

    我们都经常碰到在抓取数据时碰到乱码现象,让人崩溃.今天主要和大家探讨如何解决php用file_get_contents方法抓取网页数据出现乱码的问题,需要的朋友可以参考下,希望能帮助到大家.下面跟随小 ...

  5. c post请求网页_Python使用urllib2抓取网页

    使用Python的库urllib2,用到urlopen和Request方法. 方法urlopen原形 ❝ urllib2.urlopen(url[, data][, timeout]) 其中:url表 ...

  6. Python多线程抓取网页图片地址

    mini-spider 功能描述: 多线程网络爬虫,爬取网页图片地址(也可提取其他特征的URL) 使用python开发一个迷你定向抓取器mini_spider.py,实现对种子链接的广度优先抓取,并把 ...

  7. python实现抓取网页上的内容并发送到邮箱

    要达到的目的: 从特定网页中抓取信息,排版后发送到邮箱中 关键点: 下载网页,从网页里抓取出需要的信息 HTML排版 发送到指定邮箱 实现: 1.python下载网页 直接用库函数就可以实现 from ...

  8. Python爬虫抓取数据时怎么防止ip被封

    大数据公司在做数据分析的时候,对目标网站频繁访问很容易触发网站的反爬机制,因此如果想要突破限制只能使用动态ip频繁切换地址模拟真实客户访问网站才能起到防封效果.比如在做数据抓取的时候报错403等限制访 ...

  9. Python爬虫抓取网页图片

    本文通过python 来实现这样一个简单的爬虫功能,把我们想要的图片爬取到本地. 下面就看看如何使用python来实现这样一个功能. # -*- coding: utf-8 -*- import ur ...

最新文章

  1. OpenCV对象检测实例
  2. linux io函数,Linux下普通IO文件操作函数---C语言
  3. lc171. Excel Sheet Column Number
  4. Ribbon_窗体_实现Ribbon风格的窗体
  5. 在js在页面中添加百度统计代码
  6. 李佳琦、薇娅联手“封杀”巴黎欧莱雅:暂停与其一切合作
  7. Spring学习总结(1)- IOC
  8. android 关于Uri.parse和uri.fromFile的区别
  9. Linux -- 以root权限安装QT5.8.0
  10. Oracle分析函数-nulls first/nulls last
  11. Easyui datagrid加载本地Json数据
  12. html5通讯录模板,[应用模板]HTML5+Phonegap通讯录
  13. pcm系统设计及matlab仿真实现,DOC:25页毕业设计PCM系统设计及MATLAB仿真实现.doc文档优秀范文...
  14. 学计算机需要外接显示器吗,还在使用笔电办公吗?是时候给你的笔记本外接一台显示器...
  15. 手机端访问本地编写的html页面【亲测有效】
  16. rc4加密问题漏洞修复_服务器SSL不安全漏洞修复方案
  17. video.js 自定义播放组件
  18. sqlserver2012链接远程服务器,修复︰ 在 SQL Server 2012年链接服务器和远程服务器上的不同排序规则的数据更新时性能降低...
  19. 芯片CP/FT测试的基本概念理解
  20. 服务器定位cpu高占用率代码php,面试官:线上服务器CPU占用率高如何排查定位问题?,...

热门文章

  1. opencv3.0中的无缝克隆图像——seamless_cloning(Poisson Image Editing)
  2. PCB板TG130/TG150/TG170的差别
  3. Linux查看所有对外开放的端口
  4. 钉钉上网课直播出错软件调用冲突简单调试
  5. 【消息队列】面试题及答案整理
  6. 弘辽科技:淘宝新品怎么打标?有哪些作用?
  7. 基于Jsp+Servlet+SQLServer的酒店管理系统
  8. [IE9] IE9 beta版下载链接
  9. 微信如何调用手机QQ在线聊天咨询
  10. (十六) AIGC、AI绘画、SD-WebUI、本地部署、Stable-Diffusion本地模型、最新Controlnet扩展