Urllib2 - 抓取并显示任意语言页面,编码问题
我正在使用Python的Google App Engine来简单地获取网页并展示出来。我的目标是能够获取任何语言的网页。不过,我遇到了编码的问题:
Simple
result = urllib2.urlopen(url).read()
在特殊字符的地方留下了乱码,
urllib2.urlopen(url).read().decode('utf8')
并且出现了错误:
'utf8'编解码器无法解码位置3544-3546的字节:数据无效
那么该怎么解决呢?有没有什么库可以检查网页的编码并转换成可读的格式?
4 个回答
是的,看起来urllib2确实忽略了Content-Type
这个属性。
因为现在大多数网页都是用UTF-8编码的,所以我用了一种简单粗暴的方法来处理ISO-8859-1编码的页面。当然,如果你想抓取的中文网页不是UTF-8编码的,这种方法就不管用了。
虽然这个方法不太优雅,但对我来说是有效的:
def read_url(url):
reader_req = urllib2.Request(url)
reader_resp = urllib2.urlopen(reader_req)
reader_resp_content = reader_resp.read()
reader_resp.close()
try:
return reader_resp_content.decode('utf-8')
except:
pass
try:
iso_string = reader_resp_content.decode('iso-8859-1')
print 'UTF-8 decoding failed, but ISO-8859-1 decoding succeeded'
return iso_string
except Exception, e:
print e
raise
补充:我后来意识到这个方法太过于 hack 了,于是开始使用Requests库,它似乎能很好地处理编码问题:http://docs.python-requests.org/
r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
t = r.text
那么,怎么解决这个问题呢?
其实,你需要获取原始的字节数据。一旦你下载了这些原始字节,你可以打印出来,看看具体是什么问题。
有没有什么库可以检查网页的编码并转换成可读的格式呢?
网页本身会说明它的编码方式。你可以假设它是UTF-8,但这并不总是正确的。
如果网页是XML或XHTML格式,开头的<?xml
标签里会包含编码信息。
网页还有一个内容类型的头部信息Content-Type: text/plain; charset="UTF-8"
,里面也有编码的信息。
其实,正确解码一个网页是很简单的。
第一步:不要假设网页是UTF-8编码。
第二步:获取内容,查看头部信息。
第三步:使用头部中指定的编码,而不是假设它是UTF-8。
rajax 在 如何在 Python 中下载任何网页并正确处理字符集? 这个问题中建议使用 chardet 库,地址是 http://chardet.feedparser.org/
这个代码现在看起来可以正常工作:
import urllib2
import chardet
def fetch(url):
try:
result = urllib2.urlopen(url)
rawdata = result.read()
encoding = chardet.detect(rawdata)
return rawdata.decode(encoding['encoding'])
except urllib2.URLError, e:
handleError(e)