还是 Python requests 的字符编码问题,明明已经正确析出真 html 文本内容, str 对象依然含有 gbk 环境不能处理的特殊字符... - V2EX
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
uti6770werty
V2EX    Python

还是 Python requests 的字符编码问题,明明已经正确析出真 html 文本内容, str 对象依然含有 gbk 环境不能处理的特殊字符...

  •  
  •   uti6770werty 2021-03-08 10:50:54 +08:00 2910 次点击
    这是一个创建于 1702 天前的主题,其中的信息可能已经有所发展或是发生改变。

    经过各位高手前几天指点,
    可以确认 http 服务器的通信过程没有指明编码, 网页内容里虽然指定了 cOntent="text/html; charset=",但这个不能影响到 requests 判断。。 被 requests 认为是"ISO-8859-1"了

    r = requests.get(link) print(r..encoding) # <- ISO-8859-1 print(r.apparent_encoding) # <- UTF-8-SIG r.encoding = 'UTF-8-SIG' print(r.text) # <- 不再报编码错误,能正确输出 retrun r.text # 从函数里把 html 文本送出去 # 函数外 htmlString = reguestGeturl(urllink) for i in BeautifulSoup(htmlString ,'lxml').findAll('td'): print(i) 这时候,又有编码错误了。。。 print(i) UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position 282: illegal multibyte sequence 

    为什么还会有\xa0 呢,处理出来的 string,已经没有\xa0 才对呀
    望各位高手指出问题所在,谢谢解答!

    19 条回复    2021-03-10 02:47:03 +08:00
    justseemore
        1
    justseemore  
       2021-03-08 11:17:00 +08:00
    #coding=utf8
    uti6770werty
        2
    uti6770werty  
    OP
       2021-03-08 11:19:22 +08:00
    @zpfhbyx 做了 htmlString = "#coding=utf8\n" + htmlString
    还是老样子,这个应该不行?
    ClutchBear
        3
    ClutchBear  
       2021-0-08 11:21:07 +08:00
    @uti6770werty 意思应该是在 python 代码的第一行加上这个. 不是 html 源码中加..
    uti6770werty
        4
    uti6770werty  
    OP
       2021-03-08 11:21:27 +08:00
    如果是用 replace 的方式,替换完\xa0,还有\xae,\xa***之类的东西,有些担心会替换了很多有用的字符。。。
    uti6770werty
        5
    uti6770werty  
    OP
       2021-03-08 11:22:56 +08:00
    @ClutchBear 每个.py 文件,都加了的。。。。
    renmu123
        6
    renmu123  
       2021-03-08 11:29:17 +08:00 via Android
    utf-8 和 urf-8-sig 可不是一个编码,还有可能是网页头文件是瞎标的,压根不是 utf-8 编码
    uti6770werty
        7
    uti6770werty  
    OP
       2021-03-08 11:32:48 +08:00
    @renmu123 明白,可是我 print(htmlString),已经能看到中文了
    str 对象携带的内容编码是 UTF-8-SIG
    搜了网络,似乎从来没有人做过对 str 对象本身要转编码这种事情。。。。
    wevsty
        8
    wevsty  
       2021-03-08 11:34:02 +08:00
    BeautifulSoup(htmlString, 'lxml', from_encoding="utf-8")

    大概这样就可以了。
    uti6770werty
        9
    uti6770werty  
    OP
       2021-03-08 11:44:28 +08:00
    @wevsty 内容带了一堆\xa0,\r\n 的特殊字符,

    还是想在做 BeautifulSoup 之前,正确地把字符编码转好
    还是根本没办法,必须要对这些\xa0,特殊字符做手动替换吗?
    wevsty
        10
    wevsty  
       2021-03-08 12:07:09 +08:00
    @uti6770werty
    只是要做编码转换的话自己用 decode 和 encode 转就行了。
    GBK->UTF-8
    "string".decode('gbk').encode('utf-8')

    UTF-8->GBK
    "string".decode('utf-8').encode('gbk')
    uti6770werty
        11
    uti6770werty  
    OP
       2021-03-08 12:32:25 +08:00
    @wevsty 明白您的意思,Python 3.66 的 str 已经没有 decode()这个方法了,虽然知道是要转成 gbk,一直都没能找到 utf-8-SIG 转 gbk 的正确方式....
    wevsty
        12
    wevsty  
       2021-03-08 12:47:25 +08:00
    @uti6770werty

    更正一下,写错了.
    string 是没有 decode 方法的,只有 bytes 才有 decode 。

    GBK->UTF-8
    b"GBK string".decode('gbk').encode('utf-8')

    UTF-8->GBK
    "string".encode('gbk')
    shyrock
        13
    shyrock  
       2021-03-08 14:06:10 +08:00
    python3 还有字符串处理和显示问题?这问题真挺恶心的,日志窗口能显示中文,调试窗口就是乱码
    imn1
        14
    imn1  
       2021-03-08 14:26:07 +08:00
    如果你是 windows 平台,cmd 环境也要设成 utf8,windows 对应是 codepage 65001
    Sylv
        15
    Sylv  
       2021-03-08 14:39:41 +08:00 via iPhone
    你这个是中文 Windows 下终端编码导致的 print 问题,print str(unicode) 类型字符串时 Python 要把字符串用终端编码 encode 成 bytes 后才能输出显示,Windows 中文终端默认编码是 gbk,而你的字符串里有 gbk 编码不了的字符,于是就报错了,解决方法是把终端编码改成 utf-8 。
    dier
        16
    dier  
       2021-03-08 14:51:46 +08:00
    我之前也遇到过类似的问题,用的是下面的方法,你参考一下

    r = requests.get(url)
    r.encoding = "gbk"
    html = r.text
    Rhilip
        17
    Rhilip  
       2021-03-08 15:59:29 +08:00
    中文 Windows 下终端编码问题,因为出错在 print 上
    lusi1990
        18
    lusi1990  
       2021-03-08 16:02:03 +08:00
    打印 r.content 看看
    .decode('utf-8',errors='ignore') 添加参数忽略错误
    geebos
        19
    geebos  
    PRO
       2021-03-10 02:47:03 +08:00
    这个问题应该是 windows 的控制台默认编码是 gbk 的问题,改一下控制台编码就行。

    实际你的结果已经没有问题了,只是包含有不能转成 gbk 编码的字符,所以在用 print 输出的时候会报错,保存到文件在看就是正常的了。

    如果实在觉得膈应的话,可以用下面的代码把 gbk 不支持的字符全部过滤掉。

    def encoding_transform(text:'str', target_encoding:'str')->str:
    """
    将字符串转换成目标编码,不能被目标编码编码的字符全部舍弃
    """
    if not isinstance(text, str):
    return text

    text_list = []
    while True:
    try:
    text = text.encode(target_encoding).decode(target_encoding)
    text_list.append(text)
    break
    except UnicodeEncodeError as e:
    position = int(re.findall(r'position (\d+):', str(e))[0])
    text_list.append(text[:position])
    text = text[position+1:]
    return ''.join(text_list)
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     926 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 20:45 PVG 04:45 LAX 12:45 JFK 15:45
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86