【问题标题】:UnicodeDecodeError downloading HTML using PythonUnicodeDecodeError 使用 Python 下载 HTML
【发布时间】:2016-01-20 17:11:55
【问题描述】:

我刚开始学习Python,但是当我想写一个工具来帮助我下载在线书籍《Learn Vimscript The Hard Way》时,我遇到了一个问题。

这是我的代码;版本是py3.5:

#coding: utf-8
import urllib.request
import re

url = 'http://learnvimscriptthehardway.stevelosh.com'
name = '/chapters/16.html'
while(len(name) != 0):
    url1 = url + name 
    print(url1)
    response = urllib.request.urlopen(url1)
    vim = response.read().decode('utf-8')
    address = "/Users/zhangzhimin/learnvimthehardway/" + name[-2:] + ".html"
    with open(address, "w") as f:
        f.write(vim)
    print("%s finish" % name)
    x = re.findall('''<a class="next" href="(.+?)"''', vim)
    name = x[0]

这是结果:

:!python3 test.py
http://learnvimscriptthehardway.stevelosh.com/chapters/16.html
/chapters/16.html finish
http://learnvimscriptthehardway.stevelosh.com/chapters/17.html
Traceback (most recent call last):
  File "test.py", line 11, in <module>
    vim = response.read().decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte                                                                                        

我不知道为什么会这样:我可以下载第 16 章并对其进行解码,但我不能为第 17 章做同样的事情。

【问题讨论】:

  • 您下载的网页是否实际编码为 utf-8?
  • 位置 1 中的字节 0x8b 通常表示数据流已被压缩。看看here
  • 为什么要解码?打开文件以写入字节,然后只写入你得到的字节。哦,我明白了,你稍后解析文件..
  • 考虑使用requests:库透明地解码transfer-encoding。是的,an HTML parser to parse HTML

标签: python unicode character-encoding


【解决方案1】:

请查看有效的示例:

import urllib2
import re

name = '/chapters/16.html'
url = 'http://learnvimscriptthehardway.stevelosh.com'
while len(name) > 0:
    url1 = url + name
    response = urllib2.urlopen(url1)
    data = response.read()
    address = './vim/' + name[-7:]
    with open(address, 'w') as fh:
        fh.write(data)
    x = re.findall('''<a class="next" href="(.+?)"''', data)
    if x:
        name = x[0]
    else:
        break

不过,我使用的是 Python 2.7.10。 此代码从您指定的 url 下载 html 格式的所有章节。 注意:替换 './vim/' (current dir + vim) 为你的目录;我使用了 name[-7:],它是最后 7 个字符,例如 '16.html' 等等。条件 'if' (if x: ...) 排除了 'index out of range' 错误。

【讨论】:

  • 这在 Python 2.7 中适用于您,因为您正在获取编码的 HTML 并将其直接写入磁盘而无需解码。你在response.read() 周围的str() 是不必要的。
【解决方案2】:

最后我解决了这个问题,其实我的代码中的一切都ok,除了 考虑到gzip,我应该想到提醒我的那个人:

位置 1 中的字节 0x8b 通常表示数据流已被压缩。

在我的代码中使用 gzip 模块后,一切正常。

【讨论】:

    猜你喜欢
    • 2016-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    相关资源
    最近更新 更多