将扩展安装到本地 Python 下的 Selenium Grid(远程 driver) 3 到 docker 下的远程服务器 运行
Installing extensions into Selenium Grid (remote driver) under local Python 3 to a remote server running under docker
我已经更改了这个 post 的标题以便于查找,并且已经解决了这个问题。请参阅下面我的回答。
旧标题 - Selenium Grid 4.0.0.Beta-1 Docker driver 在添加 chrome 扩展时崩溃我的 python 应用程序,而 Selenium local 没有
我到处寻找最近的答案并尝试了大部分旧的答案(所以请不要将其标记为重复)和 google 向我展示的每个网站..目前没有任何效果.我想使用最新版本的 Selenium Grid(Docker 图像),我已经设置好它并可以正常工作,只要我没有安装扩展或定义用户目录,我就可以远程抓取数据,因为跟随...
此代码确实有效,但它在本地浏览器上运行,而不是在 docker Selenium Grid 上运行。
from selenium import webdriver
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
class sgrid:
def init_chrome_with_cookies_local(self):
chrome_options = Options()
chrome_options.add_extension(r'C:\Users\charl\OneDrive\python\vidiqext.41.0_0.crx')
chrome_options.add_argument("user-data-dir=C:/Users/charl/OneDrive/python/userdata")
driver = webdriver.Chrome(options=chrome_options)
return driver
但是当我切换到这个时
def init_chrome_with_cookies_remote(self):
chrome_options = Options()
chrome_options.add_extension(r'C:\Users\charl\OneDrive\python\vidiqext.41.0_0.crx')
chrome_options.add_argument(r'user-data-dir=C:/Users/charl/OneDrive/python/userdata')
driver = webdriver.Remote(command_executor='http://x.x.x.x:4444/wd/hub',options=chrome_options)
return driver
..它崩溃了,如果 add_extension 和 add_argument 都被尝试过,或者一个然后另一个都没有关系,它们都会导致应用程序崩溃。
文件“c:/Users/charl/OneDrive/python/sgrid.py”,第 183 行,迭代
driver.get('about:blank')
UnboundLocalError:赋值前引用的局部变量'driver'
PS C:\Users\charl\OneDrive\dataharvest\visualstudio>
这个错误实际上只是意味着 driver 没有正确配置,因为所有其他代码都是相同的。现在我明白 Whosebug 上的一些解决方案使用 DesiredCapabilities 方式,但我被告知这已被弃用,并且 none 已经工作所以如果有人在 Python 3,Selenium Grid 4 docker,如果知道我将不胜感激。
编辑:可能值得注意的是,我的本地机器是 Windows Anaconda,我的远程机器是 Debian 运行 Docker,它们不在同一台机器上。我需要在本地或远程机器上规定这些 files/directories 的路径吗?
编辑 2:crx 文件或 user-data-dir 的路径应该是远程机器的本地路径,我已经计算出来,在我的情况下是 /dev/shm,两者都必须可用docker 容器的内部和外部,而不是本地机器。它仍然崩溃,但是在远程添加用户数据之后,现在找到了部分解决方案。这并不明显,因为命令 driver.save_screenshot(...) 例如在本地保存文件。
在这种情况下
chrome_options.add_argument("user-data-dir=/dev/shm/vidiq")
似乎可以工作(文件是由 chrome 正常创建的,它不会崩溃,并且因为没有 VidIQ 扩展名而抓取空白数据),但是 ...
chrome_options.add_extension('/dev/shm/3.41.0_0.crx')
立即使 driver 崩溃。我检查了远程权限,分别是777和666。
编辑 3:可以确认 crx 文件和用户数据应该有一个远程路径,但仍然无法启动带有扩展名的远程 Selenium 网格。
首先,让我们澄清一下设置。我的 Windows 笔记本电脑是 运行ning Python 3(使用 Anaconda)并且所有应用程序代码都是本地的。我的 Selenium Grid 运行 在 docker 下的云中安装了一个 VM,其中我有 Selenium Grid、Portainer(用于管理 docker),顺便说一下 mongdb 用于保存抓取的结果。现在一切正常。
objective,将扩展安装到远程 Selenium Grid 上,其本质上无法直接与 chrome 交互。所以你不能只是暂停脚本,手动添加扩展,然后继续。通常我们 运行 chrome 几乎失明了。
这里有一些方法对我不起作用。
训练 Selenium 通过按键添加扩展,例如 send.keys。这不会起作用,因为在安装扩展之前的最后一个弹出窗口有按钮“你想安装扩展”和“取消”。此弹出窗口来自 chrome.exe 和 Windows 之间的交互,并且无法从 chrome 驱动程序自动执行。它在本地 Windows GUI 中,而不是在网页 DOM 中。
在本地创建用户数据配置文件,与 chrome 交互以安装扩展,并将该配置文件复制到远程计算机。 Chromedriver/Selenium 将使用配置文件,但不会显示扩展名。
使用 crx 文件安装扩展是最常引用的方法,但在远程应用于 Selenium Grid 运行ning 时似乎不起作用。它崩溃了。
我不清楚文档是用户数据和扩展的路径应该在本地 python 机器还是远程 Selenium 机器上。奇怪的是,当扩展的路径是本地的时,有一些异常指的是错误的键,答案是两者都应该是远程的。
由于我 运行 在 docker 下,我们需要一个路径,我可以将文件上传到该路径,并且该路径也可供 docker 内的容器使用。通过进入 portainer 并检查绑定到该容器的驱动器,我能够确定该驱动器是 dev/shm/ 并且容器和我的 SSH 连接都将通过相同的路径引用它(并非总是如此)在 docker)。 dev 文件夹位于我的 debian/docker 安装程序的根目录中。
所以这对我有用
from selenium import webdriver
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
import time
chrome_options = Options()
chrome_options.add_argument("user-data-dir=/dev/shm/vidiqa")
unpacked_extension_path = '/dev/shm/vidiqa/Default/Extensions/pachckjkecffpdphbpmfolblodfkgbhl/3.43.1_0'
chrome_options.add_argument('--load-extension={}'.format(unpacked_extension_path))
#chrome_options.headless = True
driver = webdriver.Remote(command_executor='http://x.x.x.x:4444/wd/hub', options=chrome_options)
time.sleep(5)
driver.get("chrome://extensions")
driver.save_screenshot('sdriver.png')
print('driver loaded sucessfully')
但是,还需要执行几个步骤。你会注意到我们没有使用正常的 crx
chrome_options.add_extension(path/to/remote/extension/ext.crx)
但是解压文件夹的方法
unpacked_extension_path = '/dev/shm/vidiqa/Default/Extensions/pachckjkecffpdphbpmfolblodfkgbhl/3.43.1_0'
chrome_options.add_argument('--load-extension={}'.format(unpacked_extension_path))
要获取此文件夹和内容,请在本地用户数据配置文件中识别该文件夹,然后找到并复制该文件夹。我的文件夹在这里....
C:\Users\charl\OneDrive\python\newuserdata\Default\Extensions\pachckjkecffpdphbpmfolblodfkgbhl
...因为这是我在 运行 Selenium 使用此
时选择放置它的地方
chrome_options.add_argument("user-data-dir=C:/Users/charl/OneDrive/python/newuserdata")
但还有其他方法。关键是它来自您在本地安装插件的用户数据,在我的例子中是通过暂停 运行 a time.sleep(120) 行并手动安装它。
然后您需要将其全部内容复制到您的远程服务器。现在,您第一次 运行 上面的代码时,Selenium 将在远程驱动器上创建文件夹...
dev/shm/your_directory_name_for_the_userdata
...它将填充大约 50 兆或更多的数据。什么都不应该崩溃,但它不会加载扩展。所以运行它一次填充用户数据,SSH到远程目录和post你上面复制的目录到
/dev/shm/your_directory_name_for_the_userdata/Default/Extensions/
您将需要创建扩展文件夹。当你研究这些台词时,所有这些都会变得更有意义....
chrome_options.add_argument("user-data-dir=/dev/shm/vidiqa")
unpacked_extension_path = '/dev/shm/vidiqa/Default/Extensions/pachckjkecffpdphbpmfolblodfkgbhl/3.43.1_0'
chrome_options.add_argument('--load-extension={}'.format(unpacked_extension_path))
并弄清楚我们在做什么。
- 正在远程创建文件夹以将用户数据保存到
- 将扩展(第一次 运行)复制到 Extensions 文件夹中,如果您手动安装扩展,该操作会自动完成。
- 加载扩展程序。
所以诀窍是你需要手动将扩展复制到用户数据。
加载扩展代码必须是 运行 每次你想要加载扩展时,它不会像你手动安装时那样记住它。尽管如果扩展需要登录(我的也是如此),这可以使用 selenium 完成,并且在后续加载 driver.My 代码时会记住该 cookie 提供快速屏幕截图以检查它是否正常工作,并保存在本地位置你的 python.
希望所有这一切将节省我花了 10 天的时间来解决所有这些问题。 Selenium Grid 是值得的 顺便说一句,它会根据机器 运行ning 自动增加并发驱动程序的数量 运行ning,每个核心处理器一个。
我已经更改了这个 post 的标题以便于查找,并且已经解决了这个问题。请参阅下面我的回答。
旧标题 - Selenium Grid 4.0.0.Beta-1 Docker driver 在添加 chrome 扩展时崩溃我的 python 应用程序,而 Selenium local 没有
我到处寻找最近的答案并尝试了大部分旧的答案(所以请不要将其标记为重复)和 google 向我展示的每个网站..目前没有任何效果.我想使用最新版本的 Selenium Grid(Docker 图像),我已经设置好它并可以正常工作,只要我没有安装扩展或定义用户目录,我就可以远程抓取数据,因为跟随...
此代码确实有效,但它在本地浏览器上运行,而不是在 docker Selenium Grid 上运行。
from selenium import webdriver
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
class sgrid:
def init_chrome_with_cookies_local(self):
chrome_options = Options()
chrome_options.add_extension(r'C:\Users\charl\OneDrive\python\vidiqext.41.0_0.crx')
chrome_options.add_argument("user-data-dir=C:/Users/charl/OneDrive/python/userdata")
driver = webdriver.Chrome(options=chrome_options)
return driver
但是当我切换到这个时
def init_chrome_with_cookies_remote(self):
chrome_options = Options()
chrome_options.add_extension(r'C:\Users\charl\OneDrive\python\vidiqext.41.0_0.crx')
chrome_options.add_argument(r'user-data-dir=C:/Users/charl/OneDrive/python/userdata')
driver = webdriver.Remote(command_executor='http://x.x.x.x:4444/wd/hub',options=chrome_options)
return driver
..它崩溃了,如果 add_extension 和 add_argument 都被尝试过,或者一个然后另一个都没有关系,它们都会导致应用程序崩溃。
文件“c:/Users/charl/OneDrive/python/sgrid.py”,第 183 行,迭代 driver.get('about:blank') UnboundLocalError:赋值前引用的局部变量'driver' PS C:\Users\charl\OneDrive\dataharvest\visualstudio>
这个错误实际上只是意味着 driver 没有正确配置,因为所有其他代码都是相同的。现在我明白 Whosebug 上的一些解决方案使用 DesiredCapabilities 方式,但我被告知这已被弃用,并且 none 已经工作所以如果有人在 Python 3,Selenium Grid 4 docker,如果知道我将不胜感激。
编辑:可能值得注意的是,我的本地机器是 Windows Anaconda,我的远程机器是 Debian 运行 Docker,它们不在同一台机器上。我需要在本地或远程机器上规定这些 files/directories 的路径吗?
编辑 2:crx 文件或 user-data-dir 的路径应该是远程机器的本地路径,我已经计算出来,在我的情况下是 /dev/shm,两者都必须可用docker 容器的内部和外部,而不是本地机器。它仍然崩溃,但是在远程添加用户数据之后,现在找到了部分解决方案。这并不明显,因为命令 driver.save_screenshot(...) 例如在本地保存文件。
在这种情况下
chrome_options.add_argument("user-data-dir=/dev/shm/vidiq")
似乎可以工作(文件是由 chrome 正常创建的,它不会崩溃,并且因为没有 VidIQ 扩展名而抓取空白数据),但是 ...
chrome_options.add_extension('/dev/shm/3.41.0_0.crx')
立即使 driver 崩溃。我检查了远程权限,分别是777和666。
编辑 3:可以确认 crx 文件和用户数据应该有一个远程路径,但仍然无法启动带有扩展名的远程 Selenium 网格。
首先,让我们澄清一下设置。我的 Windows 笔记本电脑是 运行ning Python 3(使用 Anaconda)并且所有应用程序代码都是本地的。我的 Selenium Grid 运行 在 docker 下的云中安装了一个 VM,其中我有 Selenium Grid、Portainer(用于管理 docker),顺便说一下 mongdb 用于保存抓取的结果。现在一切正常。
objective,将扩展安装到远程 Selenium Grid 上,其本质上无法直接与 chrome 交互。所以你不能只是暂停脚本,手动添加扩展,然后继续。通常我们 运行 chrome 几乎失明了。
这里有一些方法对我不起作用。
训练 Selenium 通过按键添加扩展,例如 send.keys。这不会起作用,因为在安装扩展之前的最后一个弹出窗口有按钮“你想安装扩展”和“取消”。此弹出窗口来自 chrome.exe 和 Windows 之间的交互,并且无法从 chrome 驱动程序自动执行。它在本地 Windows GUI 中,而不是在网页 DOM 中。
在本地创建用户数据配置文件,与 chrome 交互以安装扩展,并将该配置文件复制到远程计算机。 Chromedriver/Selenium 将使用配置文件,但不会显示扩展名。
使用 crx 文件安装扩展是最常引用的方法,但在远程应用于 Selenium Grid 运行ning 时似乎不起作用。它崩溃了。
我不清楚文档是用户数据和扩展的路径应该在本地 python 机器还是远程 Selenium 机器上。奇怪的是,当扩展的路径是本地的时,有一些异常指的是错误的键,答案是两者都应该是远程的。
由于我 运行 在 docker 下,我们需要一个路径,我可以将文件上传到该路径,并且该路径也可供 docker 内的容器使用。通过进入 portainer 并检查绑定到该容器的驱动器,我能够确定该驱动器是 dev/shm/ 并且容器和我的 SSH 连接都将通过相同的路径引用它(并非总是如此)在 docker)。 dev 文件夹位于我的 debian/docker 安装程序的根目录中。
所以这对我有用
from selenium import webdriver
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
import time
chrome_options = Options()
chrome_options.add_argument("user-data-dir=/dev/shm/vidiqa")
unpacked_extension_path = '/dev/shm/vidiqa/Default/Extensions/pachckjkecffpdphbpmfolblodfkgbhl/3.43.1_0'
chrome_options.add_argument('--load-extension={}'.format(unpacked_extension_path))
#chrome_options.headless = True
driver = webdriver.Remote(command_executor='http://x.x.x.x:4444/wd/hub', options=chrome_options)
time.sleep(5)
driver.get("chrome://extensions")
driver.save_screenshot('sdriver.png')
print('driver loaded sucessfully')
但是,还需要执行几个步骤。你会注意到我们没有使用正常的 crx
chrome_options.add_extension(path/to/remote/extension/ext.crx)
但是解压文件夹的方法
unpacked_extension_path = '/dev/shm/vidiqa/Default/Extensions/pachckjkecffpdphbpmfolblodfkgbhl/3.43.1_0'
chrome_options.add_argument('--load-extension={}'.format(unpacked_extension_path))
要获取此文件夹和内容,请在本地用户数据配置文件中识别该文件夹,然后找到并复制该文件夹。我的文件夹在这里....
C:\Users\charl\OneDrive\python\newuserdata\Default\Extensions\pachckjkecffpdphbpmfolblodfkgbhl
...因为这是我在 运行 Selenium 使用此
时选择放置它的地方chrome_options.add_argument("user-data-dir=C:/Users/charl/OneDrive/python/newuserdata")
但还有其他方法。关键是它来自您在本地安装插件的用户数据,在我的例子中是通过暂停 运行 a time.sleep(120) 行并手动安装它。
然后您需要将其全部内容复制到您的远程服务器。现在,您第一次 运行 上面的代码时,Selenium 将在远程驱动器上创建文件夹...
dev/shm/your_directory_name_for_the_userdata
...它将填充大约 50 兆或更多的数据。什么都不应该崩溃,但它不会加载扩展。所以运行它一次填充用户数据,SSH到远程目录和post你上面复制的目录到
/dev/shm/your_directory_name_for_the_userdata/Default/Extensions/
您将需要创建扩展文件夹。当你研究这些台词时,所有这些都会变得更有意义....
chrome_options.add_argument("user-data-dir=/dev/shm/vidiqa")
unpacked_extension_path = '/dev/shm/vidiqa/Default/Extensions/pachckjkecffpdphbpmfolblodfkgbhl/3.43.1_0'
chrome_options.add_argument('--load-extension={}'.format(unpacked_extension_path))
并弄清楚我们在做什么。
- 正在远程创建文件夹以将用户数据保存到
- 将扩展(第一次 运行)复制到 Extensions 文件夹中,如果您手动安装扩展,该操作会自动完成。
- 加载扩展程序。
所以诀窍是你需要手动将扩展复制到用户数据。
加载扩展代码必须是 运行 每次你想要加载扩展时,它不会像你手动安装时那样记住它。尽管如果扩展需要登录(我的也是如此),这可以使用 selenium 完成,并且在后续加载 driver.My 代码时会记住该 cookie 提供快速屏幕截图以检查它是否正常工作,并保存在本地位置你的 python.
希望所有这一切将节省我花了 10 天的时间来解决所有这些问题。 Selenium Grid 是值得的 顺便说一句,它会根据机器 运行ning 自动增加并发驱动程序的数量 运行ning,每个核心处理器一个。