【问题标题】:javascript error: circular reference error while trying to retrieve navigator.plugins using Selenium and Pythonjavascript 错误:尝试使用 Selenium 和 Python 检索 navigator.plugins 时出现循环引用错误
【发布时间】:2020-10-25 06:14:11
【问题描述】:

我正在尝试从Selenium 驱动的ChromeDriver 发起的 中检索navigator.plugins 的值浏览上下文

使用 我可以检索navigator.userAgentnavigator.plugins,如下所示:

但使用 Seleniumexecute_script() 方法我能够提取 navigator.userAgentnavigator.plugins 会引发以下 循环引用 错误:

  • 代码块:

    from selenium import webdriver 
    
    options = webdriver.ChromeOptions() 
    options.add_argument("start-maximized")
    driver = webdriver.Chrome(options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
    driver.get("https://www.google.com/")
    print("userAgent: "+driver.execute_script("return navigator.userAgent;"))
    print("plugins: "+driver.execute_script("return navigator.plugins;"))
    
  • 控制台输出:

    userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
    Traceback (most recent call last):
      File "C:\Users\Soma Bhattacharjee\Desktop\Debanjan\PyPrograms\navigator_properties.py", line 19, in <module>
        print("vendor: "+driver.execute_script("return navigator.plugins;"))
      File "C:\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 636, in execute_script
        'args': converted_args})['value']
      File "C:\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
        self.error_handler.check_response(response)
      File "C:\Python\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
        raise exception_class(message, screen, stacktrace)
    selenium.common.exceptions.JavascriptException: Message: javascript error: circular reference
      (Session info: chrome=83.0.4103.116)
    

我已经就循环参考进行了以下讨论,我理解了这个概念。但我不确定我应该如何解决这里的问题。

有人可以帮我找回navigator.plugins吗?

【问题讨论】:

    标签: google-chrome google-chrome-devtools javascript selenium selenium-webdriver navigator circular-reference


    【解决方案1】:

    当您从浏览器领域查询非原始数据结构时,可能会出现序列化问题。 通过仔细检查单个插件的层次结构,我们可以看到它具有递归结构,这对于序列化程序来说是一个问题。

    如果您需要插件列表,请尝试仅返回一个序列化的、换行符分隔的字符串,然后在 Python 领域中用换行符将其拆分。

    例如:

    plugins = driver.execute_script("return Array.from(navigator.plugins).map(({name}) => name).join('\n');").split('\n')
    

    【讨论】:

    • 使用 print("plugins-&gt;name: "+driver.execute_script("return Array.from(navigator.plugins).map(({name}) =&gt; name);")) 我看到 TypeError: must be str, not list
    • 好的,然后将其作为换行符分隔的字符串返回。例如:return Array.from(navigator.plugins).map(({name}) => name).join('\n');然后在您的 Python 代码中将其除以 \n 以获得搅拌列表。
    • print("plugins-&gt;name: "+driver.execute_script("return Array.from(navigator.plugins).map(({name}) =&gt; name);")[0])我回来了Chrome PDF PluginChrome PDF Viewer等等。
    • 这不是我上面建议的。在您的情况下,您只需返回第一个可用插件的名称。我建议做的是从您对 execute_script 的调用中返回一个以换行符分隔的字符串,然后在 Python 代码中将其分割为“\n”以获取搅拌列表。例如:plugins = driver.execute_script("return Array.from(navigator.plugins).map(({name}) => name).join('\n')").split('\n') print ('plugins->name: ' + 插件)
    • @ViacheslavMoskalenko 您只需要在末尾添加.join(),它将返回一个以逗号分隔的名称字符串return Array.from(navigator.plugins).map(({name}) =&gt; name).join()
    【解决方案2】:

    我假设这与navigator.plugins 返回PluginArray 的事实有关。

    PluginArray 页面列出了可用的方法和属性,我编写了返回名称列表的代码。您可以根据需要对其进行调整。

    print("plugins: " + driver.execute_script("var list = [];for(var i = 0; i < navigator.plugins.length; i++) { list.push(navigator.plugins[i].name); }; return list.join();"))
    

    【讨论】:

    • 这个答案肯定有助于向前迈出一步。不知何故,我需要获取 plugin 值。
    • 您具体寻找哪些插件值?
    • 我希望从 1) Chrome PDF Plugin 2) Chrome PDF Viewer 3) Native Client 中提取值
    • 您在寻找哪些价值观?您是否查看过我在答案中链接的 PluginArray 页面?它链接到插件页面,该页面具有您可以访问的不同属性:描述、文件名和版本。那是你要找的还是?
    • 那么这里的总体目标是什么?您可能应该用它来更新您的问题。您是否正在尝试查找特定插件,确保未安装特定插件等?一旦我们有了这个,我们就可以更好地创建一个答案。
    【解决方案3】:

    循环参考

    如果两个单独的对象相互传递引用,则会出现circular reference。循环引用意味着相互引用的两个对象是紧密耦合的,对一个对象的更改也可能需要对另一个对象进行更改。


    NavigatorPlugins.plugins

    NavigatorPlugins.plugins 返回一个PluginArray 对象,列出描述应用程序中安装的插件的Plugin 对象。 pluginsPluginArray 对象,用于通过名称或作为项目列表访问 Plugin 对象。返回值具有长度属性,并支持使用括号表示法(例如plugins[2])以及通过item(index)namedItem("name") 方法访问单个项目。


    要提取navigator.plugins 属性,您可以使用以下解决方案:

    • 要获取plugins名称列表:

      print(driver.execute_script("return Array.from(navigator.plugins).map(({name}) => name);"))
      
      • 控制台输出:

        ['Chrome PDF Plugin', 'Chrome PDF Viewer', 'Native Client']
        
    • 获取plugins文件名列表:

      print(driver.execute_script("return Array.from(navigator.plugins).map(({filename}) => filename);"))
      
      • 控制台输出:

        ['internal-pdf-viewer', 'mhjfbmdgcfjbbpaeojofohoefgiehjai', 'internal-nacl-plugin']
        
    • 获取plugins描述列表:

      print(driver.execute_script("return Array.from(navigator.plugins).map(({description}) => description);"))
      
      • 控制台输出:

        ['Portable Document Format', '', '']
        

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-22
      • 2017-11-19
      • 2013-07-08
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      相关资源
      最近更新 更多