undetected Selenium
undetected Selenium

Reputation: 193298

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:

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?

Upvotes: 1

Views: 3654

Answers (3)

undetected Selenium
undetected Selenium

Reputation: 193298

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 (e.g. 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', '', '']
      

Upvotes: 1

Viacheslav Moskalenko
Viacheslav Moskalenko

Reputation: 1067

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. enter image description here

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')

Upvotes: 3

JeffC
JeffC

Reputation: 25730

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

Upvotes: 2

Related Questions