Selenium解析unicode问题:WebDriverException:消息:未知错误:检查器消息错误

时间:2019-07-04 03:07:42

标签: python-3.x selenium web-scraping selenium-chromedriver

我正在抓取一些HTML内容。

for i, c in enumerate(cards[75:77]):
    print(i)
    a = c.find_element_by_class_name("influencer-stagename")
    print(a.get_attribute('innerHTML'))

对除第76条记录以外的所有记录都适用。错误输出...

0
b'<a class="influencer-analytics-link" href="/influencers/sophiewilling"><h5><span>SOPHIE WILLING</span></h5></a>'
1
b'<a class="influencer-analytics-link" href="/influencers/ferntaylorr"><h5><span>Fern Taylor.</span></h5></a>'
2
b'<a class="influencer-analytics-link" href="/influencers/officialshaniceslatter"><h5><span>Shanice Slatter</span></h5></a>'
3

Stacktrace ...

> -------------------------------------------------------------------------
WebDriverException                        Traceback (most recent call last) <ipython-input-484-0a80d1af1568> in <module>
          3     #print(c.find_element_by_class_name("influencer-stagename").text)
          4     a = c.find_element_by_class_name("influencer-stagename")
    ----> 5     print(a.get_attribute('innerHTML').encode('ascii', 'ignore'))

    ~/anaconda3/envs/py3-env/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py in get_attribute(self, name)
        141                 self, name)
        142         else:
    --> 143             resp = self._execute(Command.GET_ELEMENT_ATTRIBUTE, {'name': name})
        144             attributeValue = resp.get('value')
        145             if attributeValue is not None:

    ~/anaconda3/envs/py3-env/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py in _execute(self, command, params)
        631             params = {}
        632         params['id'] = self._id
    --> 633         return self._parent.execute(command, params)
        634 
        635     def find_element(self, by=By.ID, value=None):

    ~/anaconda3/envs/py3-env/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py in execute(self, driver_command, params)
        319         response = self.command_executor.execute(driver_command, params)
        320         if response:
    --> 321             self.error_handler.check_response(response)
        322             response['value'] = self._unwrap_value(
        323                 response.get('value', None))

    ~/anaconda3/envs/py3-env/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py in check_response(self, response)
        240                 alert_text = value['alert'].get('text')
        241             raise exception_class(message, screen, stacktrace, alert_text)
    --> 242         raise exception_class(message, screen, stacktrace)
        243 
        244     def _value_or_default(self, obj, key, default):

    WebDriverException: Message: unknown error: bad inspector message: {"id":110297,"result":{"result":{"type":"object","value":{"status":0,"value":"<a class=\"influencer-analytics-link\" href=\"/influencers/bookishemily\"><h5><span>Emily | 18 | GB | Student\uD83C...</span></h5></a>"}}}}   (Session info: chrome=75.0.3770.100)   (Driver info: chromedriver=2.40.565386 (45a059dc425e08165f9a10324bd1380cc13ca363),platform=Mac OS X 10.14.0 x86_64)

我怀疑这是一个无效字符

  

value“:” Emily | 18 | GB |学生\ uD83C ...”

我特别怀疑“ \ uD83C”

添加

.encode("utf-8")  OR   .encode('ascii', 'ignore')

第二个打印语句不变。

关于如何解决此问题的任何想法?

更新:问题在于表情符号字符。我到目前为止已找到3个示例,每个示例都有一个表情符号(粉红色的花?,俄罗斯国旗??和旋转的叶子leaves)。如果我使用Chrome检查器将其删除,则我的代码可以正常运行,但这不是大规模解决方案

1 个答案:

答案 0 :(得分:1)

此错误消息...

WebDriverException: Message: unknown error: bad inspector message: {"id":110297,"result":{"result":{"type":"object","value":{"status":0,"value":"<a class=\"influencer-analytics-link\" href=\"/influencers/bookishemily\"><h5><span>Emily | 18 | GB | Student\uD83C...</span></h5></a>"}}}}   (Session info: chrome=75.0.3770.100)   (Driver info: chromedriver=2.40.565386 (45a059dc425e08165f9a10324bd1380cc13ca363),platform=Mac OS X 10.14.0 x86_64)

...表示由于JSON编码/解码问题, ChromeDriver 无法解析某些非UTF-8字符。


深潜

根据Issue 723592: 'Bad inspector message' errors when running URL web-platform-tests via webdriver John Chen(Google Chrome浏览器的WebDriver的所有者)在他的comment中的讨论,提到:

JSON编码/解码问题导致在https://travis-ci.org/w3c/web-platform-tests/jobs/232845351上报告“错误的检查器消息”错误。来自第1部分的错误消息的一部分包含无效的Unicode字符\ uFDD0(来自https://github.com/w3c/web-platform-tests/blob/34435a4/url/urltestdata.json#L3596)。 Chrome中的JSON编码器未检测到此类错误,而是通过发送到ChromeDriver的JSON Blob传递了该错误。 ChromeDriver使用base / json / json_parser.cc解析JSON字符串。该解析器进行更彻底的错误检测,注意到\ uFDD0是无效字符,并报告错误。我认为我们的JSON编码器和解码器应该具有完全相同的错误检查量。编码器可以创建一个被解码器拒绝的斑点是有问题的。


分析

John Chen(Google Chrome浏览器的WebDriver所有者)进一步added

在将结果发送回ChromeDriver之前,JSON编码发生在DevTools的协议布局中。相关代码在https://cs.chromium.org/chromium/src/out/Debug/gen/v8/src/inspector/protocol/Protocol.cpp中。特别是,escapeStringForJSON函数负责编码字符串。实际上,这很保守。高于126的任何内容均以\ uXXXX格式编码。 (请注意,Protocol.cpp是一个生成的文件。真正的来源是https://cs.chromium.org/chromium/src/v8/third_party/inspector_protocol/lib/Values_cpp.template。)

该错误发生在ChromeDriver使用的JSON解析器中。 \ uXXXX序列的解码发生在https://cs.chromium.org/chromium/src/base/json/json_parser.cc?l=564https://cs.chromium.org/chromium/src/base/json/json_parser.cc?l=670。在对转义序列进行解码之后,解码器将拒绝所有无效的Unicode字符。

我注意到最近进行了更改,以防止JSON编码器发出无效的Unicode代码点:https://crrev.com/478900。不幸的是,它不是此错误所涉及的代码使用的JSON编码器,因此它不能直接帮助我们,但这表明我们不是唯一受此类型问题影响的人。


解决方案

此问题已得到解决在chromedriver中解码无效的UTF字符串时,替换了无效的UTF-16转义序列是因为Web平台测试可能会通过此{{3 }} / revision

因此,一种快速的解决方案是确保以下各项并重新执行测试:


替代

作为替代方案,您可以使用 GeckoDriver / Firefox 组合,并且可以在ChromeDriver v79.0 release notes

中找到相关的讨论