我正在使用 Selenium 和多处理在 Python 3.12 中编写一个网页抓取程序。我正在使用 docker 设置 selenium 网格,并使用它并行运行多个 selenium 实例。但是,向网格发出的任何请求都不会执行,并且会在 5 分钟后超时。即使我将函数简化为仅获取页面的源代码,它仍然不会执行。我将“请求者”内置到一个类中。这是我尝试运行的基本函数(在我删除了要为 html 完成的所有计算之后)。
def get_discounts(self) -> list:
discounts = []
driveroptions = webdriver.ChromeOptions()
driveroptions.add_argument('--headless')
driver = webdriver.Remote(command_executor='http://127.0.0.1:4444', options=driveroptions, keep_alive=False)
driver.get(self.current_url)
html = driver.page_source()
driver.quit()
return discounts
也供参考,这是我的 docker-compose 文件:
version: "3"
services:
chrome:
image: selenium/node-chrome:4.21.0-20240517
shm_size: 2gb
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_MAX_SESSIONS=8
selenium-hub:
image: selenium/hub:4.21.0-20240517
container_name: selenium-hub
ports:
- "4442:4442"
- "4443:4443"
- "4444:4444"
我尝试过无头运行,甚至将 SE_NODE_MAX_SESSIONS 限制为几个(3 或 4),但它仍然不起作用。我在一台只有 16GB RAM 的戴尔笔记本电脑上运行这一切,并且为 docker 运行虚拟机会消耗其中的一部分。一旦我实际运行网格,它就接近最大化我的 RAM(最高使用 14.8GB)。仍然不知道为什么这行不通。
此外,仅使用 selenium 在网格外运行此函数效果也很好。
使用 Docker Compose 堆栈,我能够在本地运行以下测试脚本:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
driveroptions = webdriver.ChromeOptions()
driveroptions.add_argument('--headless')
driver = webdriver.Remote(command_executor='http://127.0.0.1:4444', options=driveroptions, keep_alive=False)
driver.get("https://www.example.com")
print(driver.find_element(By.TAG_NAME, 'h1').text)
driver.quit()
它按预期打印了 HTML 源代码,我可以看到 selenium-hub
和 Chrome 容器在浏览器启动时一致地记录日志。下面的屏幕截图显示了 Docker Compose 日志(顶部面板)和测试脚本的输出(底部面板)。再次阅读您的问题,我发现您提到您正在虚拟机上运行 Docker。您的意思是您的网络抓取客户端在本地运行并且它在虚拟机上远程访问 Selenium 网格?如果是这种情况,那么我有两个建议: