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
leisurelylicht
V2EX  ›  Python

关于网页编码的问题

  •  
  •   leisurelylicht · 2015-11-25 13:28:59 +08:00 · 2615 次点击
    这是一个创建于 3075 天前的主题,其中的信息可能已经有所发展或是发生改变。

    用 requests 抓取网页然后用 beautiful soup 处理网页的时候,有几个编码的问题搞不懂.

    1. 为什么 requests.encoding 得到的网页编码经常不准确?

    2. 为什么很多网页都被当成是 ISO-8859-1 编码的了?

    3. 怎么提高 beautiful soup 的识别率?

    4. 有其他更好的网页处理方式吗?

    20 条回复    2015-11-25 14:57:23 +08:00
    est
        1
    est  
       2015-11-25 13:31:49 +08:00
    > 为什么 requests.encoding 得到的网页编码经常不准确?


    不是经常不准,是一定不准。

    https://github.com/kennethreitz/requests/blob/master/requests/utils.py#L345

    if 'text' in content_type:
    return 'ISO-8859-1'


    可以看 issues #2086
    leisurelylicht
        2
    leisurelylicht  
    OP
       2015-11-25 13:34:26 +08:00
    @est orz.有什么好的方法可以获取网页编码吗?为什么浏览器能准确的解析不同编码的网页呢?
    msg7086
        3
    msg7086  
       2015-11-25 13:35:35 +08:00
    @leisurelylicht 浏览器能准确解析不同编码?
    lixia625
        4
    lixia625  
       2015-11-25 13:38:23 +08:00
    最好的方法是使用 python3 ??
    go2sleep
        5
    go2sleep  
       2015-11-25 13:38:43 +08:00
    遇到过类似问题,使用 uchardet 库解决的
    est
        6
    est  
       2015-11-25 13:39:07 +08:00
    @leisurelylicht
    @msg7086

    可以直接使用 .apperant_encoding 而不是 .encoding 。前者使用 chardet 貌似很准。
    go2sleep
        7
    go2sleep  
       2015-11-25 13:41:16 +08:00
    有些网站 Content-Type 的 charset 和实际编码类型不符(很多小网站或政府门户),只好通过 uchardet 来直接根据内容判断。
    est
        8
    est  
       2015-11-25 13:41:46 +08:00
    @msg7086 其实浏览器可以准确解析。 html 里有个 meta 头可以指定。 requests 有个方法叫做 def get_encodings_from_content 。结果作者认为“我们是 http 库不是 html 库”就决心把这个方法从新版本里去掉。。。。。。。。 orz 。。。。。。。。。。。。。老外这死脑筋。

    那个 'ISO-8859-1' 写死的原因是,老外说这是 RFC 规定的。你咬我呀。
    leisurelylicht
        9
    leisurelylicht  
    OP
       2015-11-25 13:42:47 +08:00
    @msg7086 就是觉得比我解析的准确率高多了
    leisurelylicht
        10
    leisurelylicht  
    OP
       2015-11-25 13:44:34 +08:00
    @est orz,但是 html 里的 meta 头的出现方式真是太多变了,特别是很多小网站.有的甚至没有.这话时候怎么准确获取网页编码?
    leisurelylicht
        11
    leisurelylicht  
    OP
       2015-11-25 13:45:34 +08:00
    @est get_encodings_from_content 这个函数的实现方式现在还能看到吗?
    SakuraSa
        12
    SakuraSa  
       2015-11-25 14:11:56 +08:00
    个人经验,似乎将 requests 获得的 content 直接给 bs4 ,让 bs4 解析编码准确性比较高:

    response = requests.get("https://www.baidu.com")
    soup = BeautifulSoup(response.content)

    bs4 就是从 meta 里读取编码的
    iyaozhen
        13
    iyaozhen  
       2015-11-25 14:18:36 +08:00
    可以试试 uchardet ,通过文本内容来判断编码。
    Shieffan
        14
    Shieffan  
       2015-11-25 14:23:46 +08:00
    我的方法: IF http header 里的 charset 跟他 html meta 里的 charset 一致且不为空,则取此 charset , ELSE 使用 chardet 判定
    go2sleep
        15
    go2sleep  
       2015-11-25 14:27:48 +08:00
    @Shieffan meta 中的 charset 如果和 Header 里面的 charset 不一致,按照标准,应该使用 meta 中的 charset
    Kisesy
        16
    Kisesy  
       2015-11-25 14:31:17 +08:00
    @leisurelylicht 看一楼,不就在那函数上面嘛
    Kisesy
        17
    Kisesy  
       2015-11-25 14:44:10 +08:00
    @SakuraSa BS4 用的不是 chardet 吗
    文档中写的是 `如果 Python 中安装了 chardet 或 cchardet 那么编码检测功能的准确率将大大提高`
    Kisesy
        18
    Kisesy  
       2015-11-25 14:49:46 +08:00
    @SakuraSa 哦,也有,也会检测 meta
    leisurelylicht
        19
    leisurelylicht  
    OP
       2015-11-25 14:56:20 +08:00
    @iyaozhen 已用,准确率确实大幅提升了.


    @Kisesy 不好意思,没注意到给略过去了,多谢!
    caomaocao
        20
    caomaocao  
       2015-11-25 14:57:23 +08:00
    chardet 对短字符串判断命中率一般,对这么大个网站编码判断应该蛮准的吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1102 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 23:12 · PVG 07:12 · LAX 16:12 · JFK 19:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.