V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
jakeyfly
V2EX  ›  问与答

requests get 下来是乱码 咋解决求大佬

  •  
  •   jakeyfly · 2018-02-20 04:01:29 +08:00 · 5206 次点击
    这是一个创建于 2471 天前的主题,其中的信息可能已经有所发展或是发生改变。

    查����U 是这样的乱码 encoding 显示 None utf-8 也没用 有没有什么办法能变显示正常

    34 条回复    2018-02-21 01:50:16 +08:00
    WillTimeCondense
        1
    WillTimeCondense  
       2018-02-20 04:13:04 +08:00 via Android
    锟斤拷锟斤拷业锟斤拷台锟斤拷锟斤拷锟侥碉拷锟斤拷锟斤拷锟斤拷锟?锟斤拷锟斤拷锟斤拷锟斤拷
    Carseason
        2
    Carseason  
       2018-02-20 04:34:40 +08:00 via iPhone
    你是不是用了 zip 的标头导致文本压缩了
    Sylv
        3
    Sylv  
       2018-02-20 05:41:17 +08:00 via iPhone
    信息不足,请提供 url 和代码,否则只能是瞎猜。
    zyxbcde
        4
    zyxbcde  
       2018-02-20 05:51:28 +08:00 via Android
    中文乱码还是全乱码,还有你们不睡么
    lhx2008
        5
    lhx2008  
       2018-02-20 08:39:31 +08:00 via Android
    可能原来是 gbk 吧?
    rieuse
        6
    rieuse  
       2018-02-20 08:43:19 +08:00 via Android   ❤️ 1
    请提供 url 方便其他人帮你测试
    wisej
        7
    wisej  
       2018-02-20 08:47:18 +08:00 via Android
    @zyxbcde 我滴龟龟 所以你是这么早就起了?
    SakuraKuma
        8
    SakuraKuma  
       2018-02-20 09:01:55 +08:00 via Android
    开了 gzip 结果没 unzip?
    ila
        9
    ila  
       2018-02-20 09:33:26 +08:00 via iPhone
    show we your code
    mcxiaoke
        10
    mcxiaoke  
       2018-02-20 10:02:55 +08:00 via iPhone
    response.encoding=utf8 or gb18030
    seanhuai
        11
    seanhuai  
       2018-02-20 10:48:57 +08:00 via Android
    gbk...
    KKKKKK
        12
    KKKKKK  
       2018-02-20 11:42:20 +08:00 via Android
    1 没代码 2 没能复现错误
    jakeyfly
        13
    jakeyfly  
    OP
       2018-02-20 12:07:04 +08:00
    url = 'http://live.titan007.com/vbsxml/bfdata.js?r=007' + str(int(time.time())) + '000'

    headers = {
    'Accept': '*/*',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7,zh-TW;q=0.6',
    'Cookie':'bfWin007FirstMatchTime=2018,1,19,08,00,00;
    win007BfCookie=0^0^1^1^1^1^1^0^0^0^0^0^1^2^1^1^0^1^1',
    'Host': 'live.titan007.com',
    'Proxy-Connection': 'Proxy-Connection',
    'Referer': 'http://live.titan007.com/',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
    }
    jakeyfly
        14
    jakeyfly  
    OP
       2018-02-20 12:07:43 +08:00
    @rieuse 大佬 贴了 URL 跟 头了 求看看
    jakeyfly
        15
    jakeyfly  
    OP
       2018-02-20 12:09:18 +08:00
    @mcxiaoke 大佬 请问怎么测出来的 用什么方法 跪求
    Carseason
        16
    Carseason  
       2018-02-20 12:11:40 +08:00 via iPhone
    Accept-Encoding': 'gzip, deflate',
    删了这行
    Sylv
        17
    Sylv  
       2018-02-20 12:17:16 +08:00
    r = requests.get(url, headers=headers)
    r.encoding = 'gbk'
    print r.text
    jakeyfly
        18
    jakeyfly  
    OP
       2018-02-20 12:24:25 +08:00
    @Sylv 大佬 请问 再碰到这种问题 要怎么试编码 用什么库 还是什么方法
    jakeyfly
        19
    jakeyfly  
    OP
       2018-02-20 12:24:49 +08:00
    @Carseason 删过了 没用 因为这条不起作用
    jakeyfly
        20
    jakeyfly  
    OP
       2018-02-20 12:26:25 +08:00
    @Sylv 我感觉 目标网止返回的是一个类 json 的数据 我用.json 无法解析 但是复制到 vscoce 用 VSCODE 格式化一下 却变成 JSON 了 不知道在 python 层面有没有办法也这样弄一下 要是可以 就太方便了
    Sylv
        21
    Sylv  
       2018-02-20 12:43:51 +08:00
    @jakeyfly
    一般中文网站出现乱码问题,编码基本都是 GBK (GB18030),特别当服务器是 Windows 的时候。
    更通用点的方法是用 chardet.detect(r.content) 尝试检测下编码。

    我这边返回的是个 js 文件,不是 json 数据,不过这个 js 文件的运行结果貌似是个 json 数据。
    jakeyfly
        22
    jakeyfly  
    OP
       2018-02-20 12:48:26 +08:00
    @Sylv JS 只懂一点点 如何得到 JSON 文件呢 我现在用正则 提取有点麻烦 要好几步
    axlecho
        23
    axlecho  
       2018-02-20 12:53:14 +08:00 via Android
    用 postman 试试 一般都是 gzip 的问题
    rieuse
        24
    rieuse  
       2018-02-20 12:57:07 +08:00 via Android
    @jakeyfly 成功了吗?没成功的话,加微-信,rieuse 免费给你看看 我也是做爬虫的。
    rieuse
        25
    rieuse  
       2018-02-20 12:59:44 +08:00 via Android
    html = requests.get(url,headers=headers).content.decode('gbk')
    这样就可以了
    jakeyfly
        26
    jakeyfly  
    OP
       2018-02-20 13:00:01 +08:00
    @rieuse 大佬 求指导 加微信不
    rieuse
        27
    rieuse  
       2018-02-20 13:01:49 +08:00 via Android
    不是大佬,我目前爬虫实习生~ 微信就是昵称
    flowfire
        28
    flowfire  
       2018-02-20 13:03:05 +08:00 via iPhone
    @ila us
    wisej
        29
    wisej  
       2018-02-20 13:05:08 +08:00   ❤️ 2
    我来梳理一下吧:

    首先 requests 里关于获取编码的几个函数:
    1. `get_encodings_from_content`:utils.py 中定义,譬如从 HTML head 的 meta 中获取 charset
    2. `get_encoding_from_headers`:从响应头的 Content-Type 来猜测
    3. `chardet.detect`: 编码自动检测工具

    然后 requests 处理编码方式的流程是这样的:
    1. 首先看响应头的 Content-Type 里是否包含 charset,有就设置并返回
    2. 若 Content-Type 里没有 charset,但是 MIME 是 text/*,则直接设置编码为 ISO-8859-1 (这一点 requests 是为了遵循 RFC2616/3.7.1 )
    3. 当第 1、2 点都不符合时,encoding 为空,才使用 chardet.detect 自动检测

    **问题所在**:
    第二点导致国内很多网站的编码方式被认为是 ISO-8859-1,在西方国家,没啥大问题。但是在亚洲很多国家,将会出现乱码

    具体讨论可以看: https://github.com/requests/requests/issues/1604

    PS:
    1. 好像 RFC2616 中将默认编码设为 ISO-8859-1 已经被弃用了。然后 requests 上关于这个问题貌似还在讨论...( https://github.com/requests/requests/issues/2086

    2. 很多人可能会疑问,为什么 requests 处理编码问题里没有用`get_encodings_from_content`,Lukasa 解释是这样的:
    > Our position on this has been that we're not a HTML library, we're a HTTP library, and therefore examining the body of the request is outside our remit.

    当然,你可以自行调用嘛:
    ```
    import requests
    from requests.utils import get_encodings_from_content

    r = requests.get('http://baike.baidu.com/view/115789.htm')
    codings = get_encodings_from_content(r.content)
    if codings:
    r.encoding = codings[0]
    ```
    rieuse
        30
    rieuse  
       2018-02-20 13:05:59 +08:00 via Android
    提取方式用 python 去执行 js 代码,js 加入自己的提取逻辑。python 执行 js 代码方式也有很多,可以用 python 开个线程调用 nodejs 来做 或者用 execjs PyExecJS....
    jakeyfly
        31
    jakeyfly  
    OP
       2018-02-20 13:09:43 +08:00
    @wisej 感谢大佬
    jakeyfly
        32
    jakeyfly  
    OP
       2018-02-20 13:10:14 +08:00
    @rieuse js 没学过 只会 JQUERY 这种东西 原生 JS 感觉 好难
    Daniel65536
        33
    Daniel65536  
       2018-02-20 22:57:22 +08:00   ❤️ 1
    爬虫编码这块,推荐用这个:

    encoding = r.encoding
    if encoding in [None, 'ISO-8859-1']:
    ----encodings = requests.utils.get_encodings_from_content(r.text)
    ----if encodings:
    --------encoding = encodings[0]
    ----else:
    --------encoding = r.apparent_encoding
    return r.content.decode(encoding)

    chardet.detect 的调用在 requests 里被包裹了一层,用 r.apparent_encoding 可以调用到。
    dangyuluo
        34
    dangyuluo  
       2018-02-21 01:50:16 +08:00
    gzip?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1439 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 17:33 · PVG 01:33 · LAX 09:33 · JFK 12:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.