Spynner编码错误
我正在尝试下载这个页面 - https://itunes.apple.com/ru/app/farm-story/id367107953?mt=8(在俄罗斯我看到的样子是 - http://screencloud.net/v/6a7o),使用的是 spynner 这个库来实现,因它使用了一些JavaScript检查,所以不能简单地下载,必须模拟完整的浏览器。
我的代码:
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
from StringIO import StringIO
import spynner
def log(str, filename_end):
filename = '/tmp/apple_log_%s.html' % filename_end
print 'logged to %s' % filename
f = open(filename, 'w')
f.write(str)
f.close()
debug_stream = StringIO()
browser = spynner.Browser(debug_level=3, debug_stream=debug_stream)
browser.load("https://itunes.apple.com/ru/app/farm-story/id367107953?mt=8")
ret = browser.contents
log(ret, 'noenc')
print 'content length = %s' % len(ret)
browser.close()
del browser
f=open('/tmp/apple_log_debug', 'w')
f.write(debug_stream.getvalue())
f.close()
print 'log stored in /tmp/debug_log'
问题是:要么是苹果的问题,要么是spynner在处理西里尔字母时出错。我在加载后用 browser.show()
查看时能正常显示,但在代码和日志中,它们的编码仍然是错误的,比如 <meta content="ÐолÑÑиÑÑ Farm Story⢠в App Store. ÐÑоÑмоÑÑеÑÑ ÑкÑинÑоÑÑ Ð¸ ÑейÑинги, пÑоÑиÑаÑÑ Ð¾ÑзÑÐ²Ñ Ð¿Ð¾ÐºÑпаÑелей." property="og:description">
。
http://2cyr.com/ 说这是一个 utf-8
文本,但显示成了 iso-8859-1
的格式...
如你所见,我在请求中没有使用任何头信息,但如果我从Chrome的网络调试控制台获取这些头信息,并传递给 load()
方法,比如 headers=[('Accept-Encoding', 'utf-8'), ('Accept-Language', 'ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4')]
- 结果还是一样。
此外,从同一个网络控制台可以看到,Chrome使用 gzip,deflate,sdch
作为接受编码。我也可以尝试这个,但我无法解码得到的内容:<html><head></head><body>��}ksÇ�g!���4�I/z�O���/)�(yw���é®i��{�<v���:��ٷ�س-?�b�b�� j�...
即使我去掉了结果开头和结尾的标签。
有人能帮忙吗?
2 个回答
str(browser.webframe.toHtml())
帮了我大忙
简单来说,browser.webframe.toHtml() 会返回一个 QTString
,在这种情况下,如果 res 里面有 Unicode 的 非拉丁
字符,使用 str()
是没用的。
如果你想得到一个 Python 的 unicode
字符串,你需要这样做:
ret = unicode(browser.webframe.toHtml().toUtf8(), encoding="UTF-8")
#if you want to get rid of non-latin text
ret = ret.encode("ascii", errors="replace") # encodes to bytestring
如果你怀疑它是 俄语
,你可以通过以下方式将其解码为一个俄语的多字节 OEM 字符串(仍然是字节字符串):
ret = ret.encode("cp1251", errors="replace") # encodes to Win-1251
# or
ret = ret.encode("cp866", errors="replace") # encodes to windows/dos console
只有这样,你才能把它保存到一个 ASCII 文件中。