Skip to content
Go back

Selenium 容器 standalone-chrome 的启动和部分 Python3 使用例

| 0 Views Edit page

将 Selenium 容器化之后,通过远程调用来加载一些页面的前端 JS 是不错的注意。

一、确定容器启动的参数

官方镜像仓库:selenium/standalone-chrome
官方文档:Docker images for the Selenium Grid Server

不得不说官方对容器各参数的解释真的很乱。
因此我总结了一些常用的参数,通过它们启动的容器在我的生产环境运行得非常稳定:

  • --ulimit nofile=32768:32768:防止出现由于限制打开文件数导致无法新建 Session 的问题。
  • -p 4444:4444:连接 Chrome 用的远程端口。
  • -p 7900:7900:查看容器内 Chrome 在发生什么的 VNC 端口(直接使用网页浏览器访问即可)。
  • -e SE_VNC_NO_PASSWORD=1:VNC 端口不设置密码。
  • -e SE_NODE_SESSION_TIMEOUT=180:Session 多久没有操作后断开连接。
  • -e SE_NODE_MAX_SESSIONS=2:同时多少个 Session 可以连接容器进行操作(理论上 1 个 Session 对应 1 个容器是最佳实践)。
  • -e SE_SCREEN_WIDTH=1920-e SE_SCREEN_HEIGHT=1080:页面分辨率。
  • --shm-size="2g":容器可用内存,官方推荐的 2G 其实够用了。

二、启动 Selenium standalone-chrome 容器

如果你是云服务器,那么在启动前请先关闭 4444 端口和 7900 端口对应的防火墙或安全组。这两个端口并没有认证,被扫到后容器会被入侵。

启动命令:

docker run -d \
  --name selenium \
  --restart=unless-stopped \
  --ulimit nofile=32768:32768 \
  -p 4444:4444 \
  -p 7900:7900 \
  -e SE_VNC_NO_PASSWORD=1 \
  -e SE_NODE_SESSION_TIMEOUT=180 \
  -e SE_NODE_MAX_SESSIONS=2 \
  -e SE_SCREEN_WIDTH=1920 \
  -e SE_SCREEN_HEIGHT=1080 \
  --shm-size="2g" \
  selenium/standalone-chrome:latest

三、Python3 使用例

1、连接容器打开 Google 并查看页面标题

from selenium import webdriver

chrome_options = webdriver.ChromeOptions()
driver = webdriver.Remote(
    command_executor='http://127.0.0.1:4444/wd/hub', # 远程服务器地址
    options=chrome_options
)
driver.get('https://www.google.com')
print(driver.title)
driver.quit()

执行结果:
Google 标题打印成功

2、为容器内的 Chrome 配置代理

注意:只能使用不需要用户认证的 HTTP 或 SOCKS5 代理!

在其他云服务器上启动 HTTP 代理服务:

wget https://github.com/go-gost/gost/releases/download/v3.0.0-nightly.20240927/gost_3.0.0-nightly.20240927_linux_amd64.tar.gz
tar xzvf gost_3.0.0-nightly.20240927_linux_amd64.tar.gz
./gost -L socks5://:37215

使用下面的命令测试代理可用性:

curl -x socks5://1.2.3.4:37215 http://ipinfo.io
from selenium import webdriver

chrome_options = webdriver.ChromeOptions()
# 为 Chrome 设置代理
chrome_options.add_argument("--proxy-server=socks5://1.2.3.4:37215")
driver = webdriver.Remote(
    command_executor='http://127.0.0.1:4444/wd/hub', # 远程服务器地址
    options=chrome_options
)
driver.get("http://api.ip.sb/geoip")
print(driver.page_source)
driver.quit()

可以看到代理生效了,美国的服务器返回了代理所在的日本的 IP 信息:
代理生效

如果你出现下面这样的错误:

This site can’t be reached
The webpage at https://ip-api.com/ might be temporarily down or it may have > moved permanently to a new web address.
ERR_NO_SUPPORTED_PROXIES

那么大概率就是你使用需要认证的代理了,请用 GOST 做下转发去掉它的认证

./gost -L socks5://:8888 -F socks5://username:password@1.2.3.4:37215

3、截图页面并保存到本地

from selenium import webdriver

chrome_options = webdriver.ChromeOptions()
driver = webdriver.Remote(
    command_executor='http://127.0.0.1:4444/wd/hub', # 远程服务器地址
    options=chrome_options
)
driver.get('https://www.youtube.com')

# 将截图保存到本地
screenshot_path = "./youtube.png"
screenshot = driver.get_screenshot_as_png()
with open(screenshot_path, "wb") as file:
    file.write(screenshot)
print(f"Screenshot saved to {screenshot_path}")

将服务器上的图片取到本地:

scp root@1.2.3.4:/root/youtube.png ./

虽然内容还没加载,但是可以看出是 YouTube 的界面了:
YouTube 页面截图


参考资料:


Edit page