Skip to content

[QUESTION] How can i connect to an external active browser while inside a docker container? #255

@uslipeSociiz

Description

@uslipeSociiz

First of all, thanks for just reading

This is my cenario:

I have a docker container containing a python app making some querys
One of those querys must open a browser to make a scraping, which i use zendriver to do so
Locally it works fine, but when i dockerize it, it cant open browsers since its a isolated container, so my wayout was to try to connect to an open browser outside of the container

When i first tried, i used...

import requests

response = requests.get(
    "http://host.docker.internal:9222/json/version",
    headers={"Host": "localhost"}
)

print(response.text)

...to check if i could make a connection with the browser (i used the command "C:\path\to\chrome.exe" --remote-debugging-port=9222 --remote-debugging-address=0.0.0.0 --user-data-dir="C:\chrome-debug")
And i got the response:

{
   "Browser": "Chrome/147.0.7727.56",
   "Protocol-Version": "1.3",
   "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36",
   "V8-Version": "14.7.173.16",
   "WebKit-Version": "537.36 (@b28eac7a1a97ec8d7bc58eca0242958254be494d)",
   "webSocketDebuggerUrl": "ws://localhost:9222/devtools/browser/3625ae4b-1aad-4a94-9910-58530710afe2"
}

So, the docker was able to connect with the browser even being out of the container

But when I tried to actually open/connect to the browser using zendriver, i tried to do this:

# inside of a class
async def start(self, existing_browser_connection=False):
    if existing_browser_connection:
        config = zd.Config(
            host="host.docker.internal",
            port=9222,
            browser_executable_path="/bin/true",
            sandbox=False
        )
        self.browser = await zd.start(config=config)
    else:
        self.browser = await zd.start()

# [...] in beetween code
 
# 'main' running code 
import asyncio

async def app():   
    client = ClientClassExample()
    await client.start(existing_browser_connection=True)
    await client.main_method_of_the_class(browser=client.browser, data_example_one='data_1', data_example_two='data_2')
    await client.stop()   

asyncio.run(app())

and got an error:

Traceback (most recent call last):
  File "/app/teste.py", line 170, in <module>
    asyncio.run(app())
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 654, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/app/teste.py", line 166, in app
    await client.start(existing_browser_connection=True)
  File "/app/teste.py", line 21, in start
    self.browser = await zd.start(config=config)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/zendriver/core/util.py", line 96, in start
    return await Browser.create(config)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/zendriver/core/browser.py", line 102, in create
    await instance.start()
  File "/usr/local/lib/python3.11/site-packages/zendriver/core/browser.py", line 392, in start
    raise Exception(
Exception: 
                ---------------------
                Failed to connect to browser
                ---------------------
                One of the causes could be when you are running as root.
                In that case you need to pass no_sandbox=True

Now, i dont think that the error is related to sandbox somehow since i passed sandbox=False in the config (as in the doc: https://mintlify.wiki/cdpdriver/zendriver/advanced/anti-detection#sandbox)

If I would've guess, I would probably say that when it recieves a webSocketDebuggerUrl, it has the value "webSocketDebuggerUrl": "ws://localhost:9222/devtools/browser/3625ae4b-1aad-4a94-9910-58530710afe2", and then he tries to use localhost inside of the container instead of using host.docker.internal as i tried in the first test

There is a wayaround it or am Iovercomplicating it?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions