Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Nodriver] How to attach nodriver to another existing session/browser? #1895

Open
jwwq opened this issue May 22, 2024 · 3 comments
Open

[Nodriver] How to attach nodriver to another existing session/browser? #1895

jwwq opened this issue May 22, 2024 · 3 comments

Comments

@jwwq
Copy link

jwwq commented May 22, 2024

How can I attach nodriver to another existing nodriver session (or to chrome existing tab/browser?)
In selenium/geckodriver I can do it with session ID:

# Connect to the existing instance
driver = webdriver.Remote(command_executor=url,desired_capabilities={})
driver.session_id = session_id

Maybe there is some CDP hack for it? Please help.

@MattWaller
Copy link
Contributor

MattWaller commented May 28, 2024

I couldn't solve this with the default nodriver setup, I had to modify the underlying config.py in core.config:
Adding the host & port params and inheriting it from the init function instead of hardcode setting it to None.

class Config:
    """
    Config object
    """

    def __init__(
        self,
        user_data_dir: Optional[PathLike] = AUTO,
        headless: Optional[bool] = False,
        browser_executable_path: Optional[PathLike] = AUTO,
        browser_args: Optional[List[str]] = AUTO,
        sandbox: Optional[bool] = True,
        lang: Optional[str] = "en-US",
        host:Optional[str]="127.0.0.1",
        port:Optional[int]=None,
        **kwargs: dict,
    ):
        """
        creates a config object.
        Can be called without any arguments to generate a best-practice config, which is recommended.

        calling the object, eg :  myconfig() , will return the list of arguments which
        are provided to the browser.

        additional arguments can be added using the :py:obj:`~add_argument method`

        Instances of this class are usually not instantiated by end users.

        :param user_data_dir: the data directory to use
        :param headless: set to True for headless mode
        :param browser_executable_path: specify browser executable, instead of using autodetect
        :param browser_args: forwarded to browser executable. eg : ["--some-chromeparam=somevalue", "some-other-param=someval"]
        :param sandbox: disables sandbox
        :param autodiscover_targets: use autodiscovery of targets
        :param lang: language string to use other than the default "en-US,en;q=0.9"
        :param kwargs:
        :type user_data_dir: PathLike
        :type headless: bool
        :type browser_executable_path: PathLike
        :type browser_args: list[str]
        :type sandbox: bool
        :type lang: str
        :type host: str
        :type port: int
        :type kwargs: dict
        """

        if not browser_args:
            browser_args = []

        if not user_data_dir:
            self._user_data_dir = temp_profile_dir()
            self._custom_data_dir = False
        else:
            self.user_data_dir = user_data_dir

        if not browser_executable_path:
            browser_executable_path = find_chrome_executable()

        self._browser_args = browser_args

        self.browser_executable_path = browser_executable_path
        self.headless = headless
        self.sandbox = sandbox
        self.host = host
        self.port = port
        self._extensions = []

Then to use it'd be like this:

        browser = await uc.start(
            headless=False,
            lang="en-US",   # this could set iso-language-code in navigator, not recommended to change
            browser_args=browser_args,
            port=port,
            host=host
        )    

Maybe there's a way to modify uc.config & update the remote-debugging-port that way, but I couldn't figure that out.

@marioeivissa
Copy link

marioeivissa commented Jun 13, 2024

port=9999, host="127.0.0.1" not working for me mate because im in root with chrome and

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

any advice also with core config.py for some solution about problem of sandbox=True when we use headless=False????as root??

@pythonlw
Copy link

pythonlw commented Jun 19, 2024

I couldn't solve this with the default nodriver setup, I had to modify the underlying config.py in core.config: Adding the host & port params and inheriting it from the init function instead of hardcode setting it to None.

class Config:
    """
    Config object
    """

    def __init__(
        self,
        user_data_dir: Optional[PathLike] = AUTO,
        headless: Optional[bool] = False,
        browser_executable_path: Optional[PathLike] = AUTO,
        browser_args: Optional[List[str]] = AUTO,
        sandbox: Optional[bool] = True,
        lang: Optional[str] = "en-US",
        host:Optional[str]="127.0.0.1",
        port:Optional[int]=None,
        **kwargs: dict,
    ):
        """
        creates a config object.
        Can be called without any arguments to generate a best-practice config, which is recommended.

        calling the object, eg :  myconfig() , will return the list of arguments which
        are provided to the browser.

        additional arguments can be added using the :py:obj:`~add_argument method`

        Instances of this class are usually not instantiated by end users.

        :param user_data_dir: the data directory to use
        :param headless: set to True for headless mode
        :param browser_executable_path: specify browser executable, instead of using autodetect
        :param browser_args: forwarded to browser executable. eg : ["--some-chromeparam=somevalue", "some-other-param=someval"]
        :param sandbox: disables sandbox
        :param autodiscover_targets: use autodiscovery of targets
        :param lang: language string to use other than the default "en-US,en;q=0.9"
        :param kwargs:
        :type user_data_dir: PathLike
        :type headless: bool
        :type browser_executable_path: PathLike
        :type browser_args: list[str]
        :type sandbox: bool
        :type lang: str
        :type host: str
        :type port: int
        :type kwargs: dict
        """

        if not browser_args:
            browser_args = []

        if not user_data_dir:
            self._user_data_dir = temp_profile_dir()
            self._custom_data_dir = False
        else:
            self.user_data_dir = user_data_dir

        if not browser_executable_path:
            browser_executable_path = find_chrome_executable()

        self._browser_args = browser_args

        self.browser_executable_path = browser_executable_path
        self.headless = headless
        self.sandbox = sandbox
        self.host = host
        self.port = port
        self._extensions = []

Then to use it'd be like this:

        browser = await uc.start(
            headless=False,
            lang="en-US",   # this could set iso-language-code in navigator, not recommended to change
            browser_args=browser_args,
            port=port,
            host=host
        )    

Maybe there's a way to modify uc.config & update the remote-debugging-port that way, but I couldn't figure that out.

No need to make any modifications。

import nodriver as uc
import os
import requests
import json
import sys
import random
from nodriver.core.config import find_chrome_executable

def cmd_start_brower(chrome_path, port, user_data_dir):
chrome_path_temp = chrome_path.replace('\chrome.exe', '')
start_params = r'cd {} && chrome.exe --remote-debugging-port={} --user-data-dir={} --no-first-run --disable-infobars --allow-file-access-from-files --no-default-browser-check --profile-directory=Profile1'
os.popen(start_params.format(chrome_path_temp, port, user_data_dir))

def get_session_url(chrome_path, port, user_data_dir):
url = f'http://127.0.0.1:{port}/json/version'
try:
res = requests.get(url)
print(res.text)
webSocketDebuggerUrl = json.loads(res.text)['webSocketDebuggerUrl']
except Exception as e:
print('error:', e)
cmd_start_brower(chrome_path, port, user_data_dir)
time.sleep(random.randint(4, 6))

async def main1():
config = uc.Config()
config.host = "127.0.0.1"
config.port = 9315
config.user_data_dir = user_data_dir
driver = await uc.start(config=config)
page = await driver.get('https://www.bing.com')
get_content = await page.get_content()
print(get_content)
await page.scroll_down(150)

port = 9315
chrome_path = find_chrome_executable()
current_path = os.path.dirname(os.path.realpath(sys.argv[0]))
user_data_dir = os.path.join(current_path, "pyppeteer_chrome")

检测浏览器是否已打开

get_session_url(chrome_path, port, user_data_dir)
uc.loop().run_until_complete(main1())

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants