python html网页解析错误怎么办_【问题解答】python解析网页源代码返回乱码问题 | 在路上...

【问题】

代码:

输出:

直接print中文是可以的,注释的中文也不会乱码,就解析网页乱码

求有用解决方案!!

【问题解答】

从问题现象到问题本质,一点点帮你分析为何如何,以及如何解决问题

1.首先,根据之前的Python的IDE的经验:

从上述截图,基本上,可以推测出来,其用的是:

2.所以,为了完全重现其问题,专门去PyDev中建立了对应的项目。

代码为:# -*- coding: utf-8 -*-

'''

Created on Oct 18, 2013

@author: CLi

'''

from urllib import urlopen

def getHtml(url):

page = urlopen(url)

html = page.read()

page.close()

return html

if __name__ == "__main__":

url = "http://www.sina.com.cn"

html = getHtml(url)

print html

然后,输出,果然和其一样:

3.对于此现象的原因:

先去确认了所要处理的网页:

中有:

可知,此处的代码处理中,如果需要解码为Unicode,最好用GBK。

而此处得到的sina网页的字符串,是GB2312

对应的,在Eclipse+PyDev中的console中输出,结果却乱码了。

则可以确定:

Eclipse+PyDev的console中,所用字符编码不是GB2312(也不是GBK或GB18030)

猜测:

估计是用的,相对常见的,UTF-8

4.但是不管其用什么编码,将Unicode的字符串输出,则肯定应该是可以的:

5.为了验证上面的PyDev的console是UTF-8的猜测,所以去用代码:# -*- coding: utf-8 -*-

'''

Created on Oct 18, 2013

@author: CLi

'''

from urllib import urlopen

def getHtml(url):

page = urlopen(url)

html = page.read()

page.close()

#uniCodehtml = html.decode("GBK")

#return uniCodehtml

uniCodehtml = html.decode("GBK")

utf8html = uniCodehtml.encode("UTF-8")

return utf8html

if __name__ == "__main__":

url = "http://www.sina.com.cn"

html = getHtml(url)

print html

结果输出果然是所预测的,正常的:

6.接下来,就很明显了:

需要搞清楚,为何此处:

Eclipse+PyDev的Console中,

(不是我们之前所以为的,调用了Windows的cmd,以为是GBK编码)

却是UTF-8编码

然后参考:

而去看看:

结果在Eclipse的Window->Preferences中,找了半天,都没有找到关于console的encoding方面的设置。

最后是在:

选择你的PyDev项目->Run->Run Configuration-> Python Run ->选择你当前的PyDev项目->Common->Encoding

才看到:

当前的,你的PyDev项目,运行期间,所用的console的编码是utf-8

7.对应的,去改为GBK:

然后再点击Run,结果,用之前,将Unicode故意转为UTF-8的话,则输出此时就是,所预料到的,乱码了:

对应的,再去用,最原始的代码,直接输出(得到的GB2312的sina网页),不做任何转换的代码:

8.由此,可以完全明白原因了:

(1)从sina获得的html网页,这个字符串,本身的字符编码为:GB2312

(2)直接print输出到,Eclipse+PyDev,中的console时,由于console默认是UTF-8编码,所以:

将GB2312的sina的html网页字符串输出到UTF-8的Eclipse+PyDev的console中

必然导致乱码。

而由于前面多次的尝试可知,解决办法有多种:

(1)代码不改:from urllib import urlopen

def getHtml(url):

page = urlopen(url)

html = page.read()

page.close()

return html

if __name__ == "__main__":

url = "http://www.sina.com.cn"

html = getHtml(url)

print html

但是去改,Eclipse+PyDev的console的字符编码,从UTF-8改为GBK(或GB2312,或GB18030):

选择你的PyDev项目->Run->Run Configuration-> Python Run ->选择你当前的PyDev项目->Common->Encoding->改为GBK

(2)不改Eclipse+PyDev的console的字符编码,仍保持旧的UTF-8的配置,但是去改代码:from urllib import urlopen

def getHtml(url):

page = urlopen(url)

html = page.read()

page.close()

uniCodehtml = html.decode("GBK")

return uniCodehtml

if __name__ == "__main__":

url = "http://www.sina.com.cn"

html = getHtml(url)

print html

即,获得GB2312的html后,去decode为Unicode,然后直接输出Unicode字符串到UTF-8的Eclipse+PyDev的console中,

则比如也是可以正常显示无乱码的

(内部会自动将输出的Unicode转换为当前console的UTF-8编码的字符串的)

(3)基于上面那种方式,(不改Eclipse+PyDev的console的字符编码,仍保持旧的UTF-8的配置),但是在转换为Unicode后,再故意转为输出目标(此处的Eclipse+PyDev的console)的编码,即UTF-8:from urllib import urlopen

def getHtml(url):

page = urlopen(url)

html = page.read()

page.close()

#uniCodehtml = html.decode("GBK")

#return uniCodehtml

uniCodehtml = html.decode("GBK")

utf8html = uniCodehtml.encode("UTF-8")

return utf8html

if __name__ == "__main__":

url = "http://www.sina.com.cn"

html = getHtml(url)

print html

也是可以保证输出的网页是正常的,中文不是乱码。

关于返回的网页是否要解压缩

另外,有人提到的:

(以为此处获得的网页是压缩的)

所以需要对于抓取回来的网页进行解压缩

此处实际结果证明了:

是不需要的。

其背后的原理和逻辑是:

(正常情况下)只有当你抓取网页所提交的请求,包含了说你支持(即需要)返回压缩的网页

(人家服务器)才返回对应的压缩的网页

详见:

中的:“返回的html内容是二进制的乱码”

进一步分析问题的现象和背后的本质

至此,上面的所有分析,还只是:

和解压代码无关,和字符串编码有关

但是:

此处,才注意到,提问者提问所截的图

看起来,还的确是:

打印出来的乱码

像是二进制级别的字符串乱码

而非之前所讨论的,中文的乱码

此刻,猜测问题最大的可能性是:

提问者,没有给出背后相关的其所用的所有的代码

估计其代码,除了此处截图给出的代码之外

还是在别处,用到了对应的:

中的:“返回的html内容是二进制的乱码”

所提到的:

添加了对应的头信息,其中包含了:

Accept-Encoding设置了gzip,deflate

从而导致:

此处,返回的网页,直接打印出现二进制那种的乱码

(而不是字符编码设置错误的,只会导致中文异常的那种乱码)

所以:

要么是我上述推测错了;

要么是,我推测是对的,而提问者,没有给出错误现象背后的,相关的所有的代码和背景条件

-> 导致上面耗费半天时间分析编码错误导致中文乱码,对于此问题来说,算是白费功夫了

-> 当然对于其他人不熟悉的此方面内容的,肯定还是有参考意义的

无论哪种情况,此种,二进制乱码

的解决办法是:

核心相关代码:#print "---before unzip, len(respHtml)=",len(respHtml);

respInfo = resp.info();

# Server: nginx/1.0.8

# Date: Sun, 08 Apr 2012 12:30:35 GMT

# Content-Type: text/html

# Transfer-Encoding: chunked

# Connection: close

# Vary: Accept-Encoding

# ...

# Content-Encoding: gzip

# sometime, the request use gzip,deflate, but actually returned is un-gzip html

# -> response info not include above "Content-Encoding: gzip"

# eg: http://blog.sina.com.cn/s/comment_730793bf010144j7_3.html

# -> so here only decode when it is indeed is gziped data

#Content-Encoding: deflate

if("Content-Encoding" in respInfo):

if("gzip" == respInfo['Content-Encoding']):

respHtml = zlib.decompress(respHtml, 16+zlib.MAX_WBITS);

elif("deflate" == respInfo['Content-Encoding']):

respHtml = zlib.decompress(respHtml, -zlib.MAX_WBITS);

更详细的解释,参见:

中的:“返回的html内容是二进制的乱码”

对应的,很明显,上面的核心代码,

本来就无需,无法,直接加入到,此处提问者所贴出的那段代码的:

因为:

其所给出的代码,根本就不应该存在此问题才对。

更加,功能丰富的,用于抓取网页的函数,其实我早就帮你们封装好了,只是你们不知道,没去用而已。

感兴趣的,自己去看:

和:

即可。

【总结】

对于:

Eclipse+PyDev的console,默认是UTF-8,而不是GBK

导致让不熟悉的人误以为,输出GBK(或Unicode)的字符串,

会像输出到GBK的Windows的cmd中一样:

中文不会乱码

如此细节:

不熟悉的人,自然很难搞懂背后的逻辑:

所以,对于,Python初学者,尤其是对字符编码不是很清楚的人

-> 也包括对Python字符编码清楚了,但是对于Eclipse不熟悉的人

-> 也包括,对于Eclipse很熟悉,但是对于PyDev中相关的console编码不熟悉的人

建议:

1.对于字符编码相关知识本身不熟悉,可参考:

复杂教程:

简明教程:

2.不熟悉Python的,自己去看:

3.对于初学者,还是建议先习惯和熟悉普通文件加上cmd去开发Python,熟悉了后,再去用各种IDE。

详细解释见:

4.然后对于Python字符编码方面,不了解的话,再去看:

5.字符编码书序了,Python也熟悉了,Python中的字符编码也熟悉了之后,对于PyDev不熟悉,可参考:

中的:

最终:

等所有相关知识都熟悉了后:

你:

爱用啥Python的IDE,就用啥;

爱怎么折腾IDE的配置,就怎么折腾;

爱怎么写代码,去抓取网页,处理网页,就如何折腾,反正都可以搞定

无论干啥,都是:

先要知道背景知识

然后:

折腾东西,出错后,也才知道,错误的原因到底是啥,以及具体如何解决问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值