CircleCI环境下Selenium无法通过自定义域名访问本地Web服务
问题根本原因
出现这个问题核心是两个配置误区:
- 你的
/etc/hosts修改只作用于执行测试脚本的运行环境,没有作用于Selenium实际运行浏览器的环境。CircleCI中绝大多数Selenium测试会用独立sidecar容器运行Chrome/Firefox浏览器,和跑Python服务、执行测试代码的主容器是网络隔离的,你在主容器加的hosts规则,浏览器容器完全感知不到,访问my-domain时会直接触发DNS解析失败,跳转到浏览器的错误页,自然找不到目标元素抛出NoSuchElementException。 - 就算你把hosts规则同步到了浏览器容器,把
my-domain指向127.0.0.1也是错误的:容器网络中127.0.0.1是容器自身的回环地址,指向浏览器容器本身,根本访问不到主容器里启动的3000端口服务。你之所以能通过127.0.0.1和localhost访问成功,是因为这两个地址的请求是从测试脚本侧发起的,走的是主容器的回环网卡,和浏览器侧发起的请求链路完全不一样。
解决方案
按以下步骤调整配置即可:
- 首先调整Web服务启动配置,把Python服务的监听地址从默认的
127.0.0.1改成0.0.0.0,确保服务能接收容器网络内的请求,示例修改:
如果你的server.py不支持传host参数,直接改代码里的监听配置为- run: name: Start server for testing command: | cd ${DIR} . venv/bin/activate python3 server.py --host 0.0.0.0 --port 3000 background: true0.0.0.0即可。 - 删掉原来在主容器修改
/etc/hosts的步骤,直接在Selenium浏览器容器的配置中注入hosts规则,CircleCI的Docker网络下,主容器暴露的端口可以通过docker0网桥地址172.17.0.1访问,配置示例:jobs: selenium-test: docker: - image: 你的主执行镜像(比如cimg/python:3.10、cimg/openjdk:17) - image: selenium/standalone-chrome:latest # 你的Selenium浏览器镜像 extra_hosts: - "my-domain:172.17.0.1" steps: - checkout # 移除原有修改/etc/hosts的步骤 - run: name: Start server for testing command: | cd ${DIR} . venv/bin/activate python3 server.py --host 0.0.0.0 --port 3000 background: true - run: name: Verify domain resolution command: curl -I http://my-domain:3000/some-endpoint - run: name: Start Testing command: ./gradlew test --stacktrace - 如果你用的是Machine executor(全虚拟机运行环境,无容器隔离):
- 保留原来修改
/etc/hosts的步骤,加完后先跑getent hosts my-domain确认解析结果是127.0.0.1,再用curl验证接口可访问。 - 如果验证通但Selenium仍访问失败,检查Selenium驱动的代理配置,把
my-domain加到代理绕过列表,比如Chrome启动参数加--proxy-bypass-list=my-domain,避免代理服务器无法解析自定义域名导致请求失败。
- 保留原来修改
排查小技巧:测试代码中访问
my-domain后先打印driver.getPageSource()和driver.getCurrentUrl(),可以直接看到浏览器实际加载的页面内容,快速确认是解析失败、连接失败还是元素等待不足的问题。
内容的提问来源于stack exchange,提问作者Necromancer
相关产品推荐
相关产品推荐

