简体   繁体   中英

javascript error: circular reference error while trying to retrieve navigator.plugins using Selenium and Python

I'm trying to retrieve the value of navigator.plugins from a Selenium driven ChromeDriver initiated Browsing Context .

Using I'm able to retrieve navigator.userAgent and navigator.plugins as follows:

navigator_userAgent_plugins

But using Selenium 's execute_script() method I'm able to extract the navigator.userAgent but navigator.plugins raises the following circular reference error:

  • Code Block:

     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;"))
  • Console Output:

     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)

I've been through the following discussions on circular reference and I understand the concept. But I am not sure how should I address the issue here.

Can someone help me to retrieve the navigator.plugins please?

There might be a serialization issue when you query a non-primitive data structure from a browser realm. By closely inspecting the hierarchy of a single plugin, we can see it has a recursive structure which is an issue for the serializer. 在此处输入图像描述

If you need a list of plugins, try returning just a serialized, newline-separated string and then split it by a newline symbol in the Python realm.

For example:

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

I'm assuming it has something to do with the fact that navigator.plugins returns a PluginArray .

The PluginArray page lists the methods and properties that are available and with that I wrote this code that returns the list of names. You can adapt it to whatever you need.

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();"))

Circular Reference

A circular reference occurs if two separate objects pass references to each other. Circular referencing implies that the 2 objects referencing each other are tightly coupled and changes to one object may need changes in other as well.


NavigatorPlugins.plugins

NavigatorPlugins.plugins returns a PluginArray object, listing the Plugin objects describing the plugins installed in the application. plugins is PluginArray object used to access Plugin objects either by name or as a list of items. The returned value has the length property and supports accessing individual items using bracket notation (eg plugins[2] ), as well as via item(index) and namedItem("name") methods.


To extract the navigator.plugins properties you can use the following solutions:

  • To get the list of names of the plugins :

     print(driver.execute_script("return Array.from(navigator.plugins).map(({name}) => name);"))
    • Console Output:

       ['Chrome PDF Plugin', 'Chrome PDF Viewer', 'Native Client']
  • To get the list of filename of the plugins :

     print(driver.execute_script("return Array.from(navigator.plugins).map(({filename}) => filename);"))
    • Console Output:

       ['internal-pdf-viewer', 'mhjfbmdgcfjbbpaeojofohoefgiehjai', 'internal-nacl-plugin']
  • To get the list of description of the plugins :

     print(driver.execute_script("return Array.from(navigator.plugins).map(({description}) => description);"))
    • Console Output:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM