V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
tanteng
V2EX  ›  Python

Python urllib.request 抓取编码问题

  •  
  •   tanteng ·
    tanteng · 2015-05-11 11:21:01 +08:00 · 7461 次点击
    这是一个创建于 3281 天前的主题,其中的信息可能已经有所发展或是发生改变。

    import urllib.request

    res = urllib.request.urlopen('http://www.tantengvip.com').read()
    html = res.decode('utf8')
    print(html)

    但是报错

    D:\learn-python>python zhua_tantengvip.py
    Traceback (most recent call last):
    File "zhua_tantengvip.py", line 5, in <module>
    print(html)
    UnicodeEncodeError: 'gbk' codec can't encode character '\xe6' in position 49945:
    illegal multibyte sequence

    我上网查了,编码问题,说了很多解决办法,都没用。我是python3环境,在windows的cmd运行的代码。

    第 1 条附言  ·  2015-05-11 13:35:24 +08:00
    import requests

    html = requests.get("http://www.tantengvip.com")

    f = open('tt.txt','w',encoding='utf-8')

    f.write(html.text)

    这样就OK了!
    第 2 条附言  ·  2015-05-11 13:45:19 +08:00
    第 3 条附言  ·  2015-05-11 13:49:00 +08:00
    with open('test.txt','w',encoding='utf-8') as f:

    f.write(html.text)

    更好的写法!
    20 条回复    2015-05-11 15:53:43 +08:00
    Septembers
        2
    Septembers  
       2015-05-11 11:27:43 +08:00
    resp = requests.get('http://www.tantengvip.com')
    print(resp.text)
    tanteng
        3
    tanteng  
    OP
       2015-05-11 11:28:32 +08:00
    @Septembers 最好是能用urllib.request
    facat
        4
    facat  
       2015-05-11 11:30:44 +08:00
    html = res.decode('utf8',errors="ignore")
    忽略错误。
    wibile
        5
    wibile  
       2015-05-11 11:31:44 +08:00
    @tanteng 不用requests是一生的遗憾啊~~~
    tanteng
        6
    tanteng  
    OP
       2015-05-11 11:37:50 +08:00
    @wibile 我安装了requests模块,还是提示编码错误!
    @Septembers
    jason52
        7
    jason52  
       2015-05-11 11:43:30 +08:00
    cmd的问题吧,你用idle试试
    tanteng
        8
    tanteng  
    OP
       2015-05-11 11:43:53 +08:00
    @Septembers 我用print(resp.text)形式还是提示编码错误,用print(resp.content)可以打印内容,但是内容没有经过编码,汉字显示的是\xf23这样的
    jason52
        9
    jason52  
       2015-05-11 11:44:00 +08:00
    或者不要print出来,写到文件里面去
    zankard
        10
    zankard  
       2015-05-11 11:49:29 +08:00
    你不要输出到cmd就没问题的,redirect到文件应该不会出错
    python test.py > tmp.txt
    tanteng
        11
    tanteng  
    OP
       2015-05-11 11:49:33 +08:00
    @jason52 Idle里打印确实ok了!但是处理这种抓取中文网站的东西,都要去Idle里跑吗,不习惯Idle,习惯了cmd命令行。。。或者有什么其他的编辑器推荐,写代码我用的是sublime
    Sylv
        12
    Sylv  
       2015-05-11 12:02:21 +08:00 via iPhone
    因为你 cmd 用的编码是 gbk,所以 Python 在 print 时会将 unicode 编码成 gbk 的字符串。
    问题就出在了这网页中有 "æ" 等字符是不在 gbk 编码范围内的,所以用 gbk 进行编码时就出错了。
    解决办法:
    1. 忽略编码错误,跳过这些字符:print(html.encode('gbk', errors='ignore'))
    2. 改用 gb18030 编码,但我不知道 cmd 能不能正常显示:print(html.encode('gb18030'))
    3. 改用 utf-8 编码的终端,或用 utf-8 编码写到文件去而不打印。
    imn1
        13
    imn1  
       2015-05-11 12:50:03 +08:00
    打开cmd,输入'chcp 65001'并回车,再运行你的utf-8程序
    一劳永逸可以修改cmd的默认编码,自行google操作步骤,但这样有可能影响一些gbk的程序,自行斟酌
    flight2006
        14
    flight2006  
       2015-05-11 12:59:54 +08:00 via Android
    中文网页也有用gbk编码的,你可以随便打开一个网页查看源码编码,如果是gbk的话用utf8也会报这个错。另外win下用python太蛋疼,不如搞个虚拟机
    recall704
        15
    recall704  
       2015-05-11 13:36:35 +08:00
    我也曾遇到这个问题,这个问题是由于请求返回的数据使用 gzip 进行了压缩,你可能需要解压.

    参考:http://www.01happy.com/python-request-url-gbk-decode/
    matrix67
        16
    matrix67  
       2015-05-11 13:47:00 +08:00 via Android
    @jason52 胖胖。。。
    matrix67
        17
    matrix67  
       2015-05-11 13:48:39 +08:00 via Android
    别用win。。这是终极
    tanteng
        18
    tanteng  
    OP
       2015-05-11 13:49:32 +08:00
    @matrix67 在公司用windows,回家用mac,哈哈,现在处于学习Python入门阶段
    tanteng
        19
    tanteng  
    OP
       2015-05-11 14:22:39 +08:00
    @wibile urllib.request有个urllib.request.urlretrieve(url, file_name)方法可以保存远程文件到本地,requests包有类似方法吗?
    @Sylv
    Sylv
        20
    Sylv  
       2015-05-11 15:53:43 +08:00 via iPhone
    @tanteng
    http://stackoverflow.com/questions/14114729/save-a-file-using-the-python-requests-library
    没有现成的,自己分装下。或者同时用 urlretrieve 也未尝不可。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2376 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 15:31 · PVG 23:31 · LAX 08:31 · JFK 11:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.