Skip to content

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

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions