首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
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
V2EX  ›  Python

request 得到'Windows-1254'这种编码,如何转成'utf-8' or 'gbk'?(提示有\ufffd 无法转换)

  •  
  •   uti6770werty · 28 天前 · 1122 次点击

    无法轻易地做转换

            if codeFormat == 'Windows-1254':
                # htmlStr = r.text.decode('windows-1254').encode('utf8')
                htmlStr = r.text.encode(r.encoding).decode(r.apparent_encoding)
                # htmlStr = r.encode('windows-1254').decode('utf8')
                #tmpStr = r.text.encode(r.encoding).decode('gbk')
                print(htmlStr)
    

    无论是 request 还是 request-html,反正就是怎么转,都提示有些字符无法转...
    理论上.encode(r.encoding).decode(r.apparent_encoding)几乎可以万能了吧
    python 对编码方面的短板?

    Error ''gb2312' codec can't encode character '\ufffd' in position 190: illegal multibyte sequence' happened on line 973
    
    8 回复  |  直到 2019-11-11 18:16:26 +08:00
        1
    sun1991   28 天前
    可能 codeFormat 本身就是错误的, content 并不是 codeFormat 指定的编码. 之前碰到过网页的 charset 错误的情况.
        2
    uti6770werty   28 天前
    @sun1991 确定 codeFormat 是对的,(也做过调试终端,确定是 Windows-1254 无疑)
    难道是反爬的方法?
    ```
    codeFormat = r.apparent_encoding
    tmpStr = ' '
    if codeFormat == 'ISO-8859-1':
    tmpStr = r.text.encode(r.encoding).decode('gbk')
    session.close()
    return tmpStr
    pass
    ```

    如这个就能很好转换
        3
    weyou   27 天前 via Android
    Windows-1254 可能是 requests 猜出的编码,不一定准确。但这也表明 http headers 里面没有提供 body 的编码属性。你要是知道数据的真实编码,直接 r.content.decode(真实编码).encode("utf8 或者 gbk")。注意 gbk 不一定成功,除非你确定所有字符都在 gbk 字符集里。
        4
    ysc3839   27 天前 via Android
    代码中“codeFormat”是哪来的?
    另外如果可以的话发一下网址,或者发 curl/wget 下载的原始数据吧。
        5
    ysc3839   27 天前 via Android
    看到了 codeFormat 是 r.apparent_encoding,这样的话用 r.encoding = r.apparent_encoding 修改当前编码,再通过 r.text 读取即可。
    参考 https://stackoverflow.com/a/52615216
        6
    gwy15   27 天前
    你这个问题是直接用 r.text 包含一个隐式 decode,如果 requests 没有成功猜对编码会直接抛异常。需要手动解码的情况,采用 bytes = r.content.decode('utf8').encode('utf8')

    另外如果 utf8,gbk,Windows-1254 都失败,可以尝试一下 GB18030,或者拷贝出来原值找个猜测解码的网站
        7
    uti6770werty   26 天前
    @sun1991
    @weyou
    @ysc3839
    @gwy15

    谢谢大家,
    琢磨了两天,最后从知识范围内的认知是,只能这样,
    从大集合的编码转过来 utf-8,怎么都会有些字符无法完成转换的,并不是转换方法的问题
    最后在 string 类型里 replace('\ufffd',''),最后 utf-8 写入到文件,内容看起来也不像是不完整的,或者缺失的。
        8
    sohusi   26 天前
    看看响应有没有被压缩,requests 库对付不了 brotli 压缩
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2229 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 24ms · UTC 14:58 · PVG 22:58 · LAX 06:58 · JFK 09:58
    ♥ Do have faith in what you're doing.