• 使用requests爬虫遇到的一个奇葩的问题:UnicodeEncodeError: 'latin1' codec can't encode character


    每一位成功的程序员,背后也许都站着无数的秃头的男人——为其提供各种开发工具&代码库,当然也包括…… 各种玄学bug……

    玄学的开端

    最近在用Python做一个爬虫项目的时候遇到一个很奇怪的问题,而且还不是每次都会触发,实在是令人费解……

    报错信息如下:

    UnicodeEncodeError: 'latin-1' codec can't encode character '\u2026' in position 512: ordinal not in range(256)
    

    把错误信息拿到搜索引擎去查询一番,中文社区上的说法是在请求的body或者headers里有中文数据,

    解决方法是:先encode成UTF-8然后再用latin-1编码decode出来。

    不过我请求的数据里面没有中文啊!

    由此踏上了令人头秃的抓bug之路

    看代码

    (又臭又长不看,建议跳过看后续)

    先看看我提交的数据的格式吧~

    这是身份认证相关的(太长只截取一部分)

    "spider9": {
      "Authorization": "Basic Z2VjZW50ZXJfYWR",
      "Blade-Auth": "bearer eyJhbGciOiJIUzI1NiIsI",
      "cookie": "oauth=eyJhY2Nlc3NfdG"
    }
    

    以下是header部分代码

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0',
        'Accept': 'application/json, text/plain, */*',
        'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        'Accept-Encoding': 'gzip, deflate', 'Content-Type': 'application/json;charset=utf-8',
        'Authorization': config['spider9']['Authorization'],
        'Blade-Auth': config['spider9']['Blade-Auth'].encode('utf-8').decode('latin1'),
        'Content-Length': '60', 'Connection': 'keep-alive',
        'Cookie': config['spider9']['cookie'],
        'Pragma': 'no-cache', 'Cache-Control': 'no-cache',
    }
    

    以下是requests请求代码:

    response = requests.post(
        url, headers=headers, verify=False,
        json={
            'cityCode': '1234',
            'createTimeFrom': None,
            'createTimeTo': None
        }
    )
    

    单纯看这代码,应该是完全没啥问题的,事实上我其他的爬虫也都是这样写的,已经稳定运行一年多了,就最近新写的这个爬虫不行… 有时候代码问题就是这么玄学

    刚才说查到网友说先encode再decode的方法,我试着在headers里的AuthorizationBlade-AuthCookie这三个字段加上:

    'Authorization': config['spider9']['Authorization'].encode('utf-8').decode('latin1')
    

    这样倒是不会报这个UnicodeEncodeError的错误,但是后端服务那边直接报错说没有登录了……

    所以这又是啥问题呢?

    继续Stack Overflow查一下,有毛子网友说也遇到这个问题,下面有回答让设置环境变量试试,ok,那我也跟着试试看:

    export PYTHONUTF8=1
    

    然后在Python里打印一下系统编码和locale:

    import sys
    import locale
    
    print(sys.getfilesystemencoding())
    print(locale.getpreferredencoding())
    

    输出结果

    utf-8
    UTF-8
    

    哦吼~ 再试试能不能跑… 还是不行,醉了,那就根本不是这个问题。

    好吧,我投降了,不想死磕了。在哪里跌倒,就在哪里躺下

    所以是什么问题呢?至今还是未解之谜…

    后续

    心好累,改用C#写爬虫,放弃Python…

    说好的“人生苦短,我用Python”呢?怎么变得这么折腾了 TAT…

    (PS:我之前做了一个爬虫平台,可以对不同语言实现的爬虫程序进行调度,提供统一的配置中心、统一的数据持久化接口~ 所以每个爬虫用什么语言写区别并不大)

    写下这篇文章就当做记录,希望以后的某一天,这个问题能得到解决~ (美好的愿望)

    参考资料

    程序设计实验室专注于互联网热门新技术探索与团队敏捷开发实践, 在公众号「程序设计实验室」后台回复 linux、flutter、c#、netcore、android、kotlin、java、python 等可获取相关技术文章和资料, 同时有任何问题都可以在公众号后台留言~
  • 相关阅读:
    经常出现null错误之tostring
    删除sql计划 调用的目标发生了异常。 (mscorlib) 其他信息: 用户 'sa' 登录失败。
    js打印保存用户输入的内容
    vs调试有时能进去后台,有时不能进去
    vs当前不会命中断点,还没有为该文档加载任何符号
    动软数据库文档生成器 失败错误码HRESULT:0x80010105 解决办法
    关于ckeditor过滤掉html样式标签之我见
    快速批量插入sqlserver方法之我见
    vs找不到svn源代码管理插件之我见
    有关大学,有关爱好,有关学习,有关奋斗,有关理想:大学应该干些什么?我大学三年以来的感悟
  • 原文地址:https://www.cnblogs.com/deali/p/15544973.html
Copyright © 2020-2023  润新知