Urllib2 - 抓取并显示任意语言页面,编码问题

2 投票
4 回答
4816 浏览
提问于 2025-04-16 03:57

我正在使用Python的Google App Engine来简单地获取网页并展示出来。我的目标是能够获取任何语言的网页。不过,我遇到了编码的问题:

Simple

result = urllib2.urlopen(url).read() 

在特殊字符的地方留下了乱码,

urllib2.urlopen(url).read().decode('utf8')

并且出现了错误:

'utf8'编解码器无法解码位置3544-3546的字节:数据无效

那么该怎么解决呢?有没有什么库可以检查网页的编码并转换成可读的格式?

4 个回答

1

是的,看起来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
2

那么,怎么解决这个问题呢?

其实,你需要获取原始的字节数据。一旦你下载了这些原始字节,你可以打印出来,看看具体是什么问题。

有没有什么库可以检查网页的编码并转换成可读的格式呢?

网页本身会说明它的编码方式。你可以假设它是UTF-8,但这并不总是正确的。

如果网页是XML或XHTML格式,开头的<?xml标签里会包含编码信息。

网页还有一个内容类型的头部信息Content-Type: text/plain; charset="UTF-8",里面也有编码的信息。

其实,正确解码一个网页是很简单的。

第一步:不要假设网页是UTF-8编码。

第二步:获取内容,查看头部信息。

第三步:使用头部中指定的编码,而不是假设它是UTF-8。

4

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)

撰写回答