Skip to main content

Chrome + Selenium 无界面环境搭建完整指南

在无图形界面的 Linux 服务器上搭建 Chrome + Selenium 环境是自动化测试和网页抓取的常见需求。本指南将详细介绍完整的安装和配置过程。

系统准备

系统要求

  • 操作系统:Ubuntu 18.04+ / Debian 9+ / CentOS 7+
  • 内存:建议 2GB 以上
  • 权限:root 或 sudo 权限
  • 网络:能够访问外网

1. 更新系统

# SSH 登录 VPS
ssh username@your-server-ip

# 更新软件包列表
sudo apt update

# 升级系统
sudo apt upgrade -y

# 安装必要的工具
sudo apt install -y wget curl unzip

安装 Google Chrome

方法 1:使用官方 .deb 包(推荐)

# 下载最新版本的 Chrome
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb

# 安装 Chrome
sudo dpkg -i google-chrome-stable_current_amd64.deb

# 如果出现依赖错误,运行以下命令
sudo apt-get install -f

# 验证安装
google-chrome --version

方法 2:使用官方仓库

# 添加 Google 官方仓库
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee /etc/apt/sources.list.d/google-chrome.list

# 更新软件包列表
sudo apt update

# 安装 Chrome
sudo apt install -y google-chrome-stable

# 验证安装
google-chrome --version

方法 3:安装 Beta 或 Unstable 版本

# 安装 Beta 版本
sudo apt install -y google-chrome-beta

# 安装 Unstable 版本
sudo apt install -y google-chrome-unstable

# 验证版本
google-chrome-beta --version
google-chrome-unstable --version

测试 Chrome 安装

# 启动 Chrome(无界面模式)
google-chrome --headless --disable-gpu --screenshot="test.png" https://google.com

# 查看是否生成了截图
ls -lh test.png

# 或者检查 Chrome 版本
google-chrome --version

# 查看可用的 Chrome 选项
google-chrome --help

安装 ChromeDriver

1. 查看 Chrome 版本

# 获取 Chrome 版本号
google-chrome --version

# 输出示例:Google Chrome 120.0.6099.109
# 版本号是:120.0.6099.109

2. 下载匹配的 ChromeDriver

# 访问 ChromeDriver 下载页面
# https://chromedriver.chromium.org/downloads

# 或者使用脚本自动获取
CHROME_VERSION=$(google-chrome --version | grep -oP '\d+\.\d+\.\d+\.\d+')
echo "Chrome version: $CHROME_VERSION"

# 根据 Chrome 版本选择合适的 ChromeDriver 版本
# 通常 ChromeDriver 版本需要与 Chrome 版本主版本号匹配

# 下载 ChromeDriver(以 120 版本为例)
wget -O chromedriver.zip https://chromedriver.storage.googleapis.com/120.0.6099.109/chromedriver_linux64.zip

# 解压文件
unzip chromedriver.zip

# 移动到系统路径
sudo mv chromedriver /usr/local/bin/chromedriver

# 设置权限
sudo chown root:root /usr/local/bin/chromedriver
sudo chmod +x /usr/local/bin/chromedriver

# 验证安装
chromedriver --version

3. 使用第三方工具自动匹配版本

# 安装 chromedriver-autoinstaller(Python 包)
pip install chromedriver-autoinstaller

# 在 Python 代码中自动处理
python3 -c "
import chromedriver_autoinstaller
chromedriver_autoinstaller.install()
print('ChromeDriver installed successfully')
"

4. 使用 snap 安装(可选)

# 安装 snap
sudo apt install snapd

# 安装 ChromeDriver
sudo snap install chromedriver

# 设置链接
sudo ln -s /snap/chromedriver/current/chromedriver /usr/local/bin/chromedriver

安装 Selenium

1. 安装 Python 和 pip

# 安装 Python3 和 pip
sudo apt install -y python3 python3-pip

# 验证安装
python3 --version
pip3 --version

2. 安装 Selenium

# 安装最新版本的 Selenium
pip3 install selenium

# 安装指定版本(可选)
pip3 install selenium==4.15.0

# 安装相关依赖
pip3 install webdriver-manager # 自动管理 WebDriver

3. 验证 Selenium 安装

# 检查 Selenium 版本
python3 -c "import selenium; print(selenium.__version__)"

# 测试导入
python3 -c "from selenium import webdriver; print('Selenium imported successfully')"

配置无界面 Chrome

1. 基础配置

创建测试脚本:

#!/usr/bin/env python3
# test_selenium.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# 配置 Chrome 选项
options = Options()
options.headless = True # 无界面模式
options.add_argument('--no-sandbox') # 跳过沙箱
options.add_argument('--disable-dev-shm-usage') # 禁用 /dev/shm
options.add_argument('--disable-gpu') # 禁用 GPU 加速

# 初始化 WebDriver
driver = webdriver.Chrome(options=options)

# 测试访问
driver.get("https://www.google.com/")
print(f"页面标题: {driver.title}")

# 截图
driver.save_screenshot("screenshot.png")

# 关闭浏览器
driver.quit()

print("测试完成!")

运行测试:

python3 test_selenium.py

2. 高级配置

完整的无界面配置:

#!/usr/bin/env python3
# advanced_selenium.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

def create_driver():
"""创建配置完整的 Chrome WebDriver"""
options = Options()

# 无界面配置
options.headless = True
options.add_argument('--headless')

# 基本设置
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--disable-gpu')
options.add_argument('--disable-software-rasterizer')

# 窗口大小
options.add_argument('--window-size=1920,1080')

# 用户代理
options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36')

# 性能优化
options.add_argument('--disable-extensions')
options.add_argument('--disable-plugins')
options.add_argument('--disable-images') # 禁用图片加载
options.add_argument('--disable-javascript') # 可选:禁用 JS
options.add_argument('--disable-css') # 可选:禁用 CSS

# 禁用通知和弹窗
prefs = {
"profile.default_content_setting_values.notifications": 2,
"profile.default_content_setting_values.media_stream": 2,
}
options.add_experimental_option("prefs", prefs)

# 禁用日志
options.add_argument('--disable-logging')
options.add_argument('--silent')

# 网络设置
options.add_argument('--disable-web-security')
options.add_argument('--allow-running-insecure-content')

return webdriver.Chrome(options=options)

def main():
driver = create_driver()

try:
# 访问页面
print("正在访问 https://httpbin.org/html...")
driver.get("https://httpbin.org/html")

# 等待页面加载
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "h1"))
)

# 获取页面信息
title = driver.title
h1_text = driver.find_element(By.TAG_NAME, "h1").text

print(f"页面标题: {title}")
print(f"H1 文本: {h1_text}")

# 截图
driver.save_screenshot("advanced_s print("截图已creenshot.png")
保存为 advanced_screenshot.png")

# 获取页面源码
page_source = driver.page_source[:500]
print(f"页面源码前 500 字符:\n{page_source}")

# 等待一段时间
time.sleep(2)

except Exception as e:
print(f"发生错误: {e}")

finally:
driver.quit()
print("浏览器已关闭")

if __name__ == "__main__":
main()

3. 使用 ChromeDriver Manager(推荐)

自动管理 WebDriver:

#!/usr/bin/env python3
# auto_driver.py

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options

def main():
# 使用 webdriver_manager 自动下载和管理 ChromeDriver
service = Service(ChromeDriverManager().install())

options = Options()
options.headless = True
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')

driver = webdriver.Chrome(service=service, options=options)

try:
driver.get("https://www.baidu.com")
print(f"页面标题: {driver.title}")

# 搜索
search_box = driver.find_element('name', 'wd')
search_box.send_keys("Selenium")
search_box.submit()

# 等待结果
driver.implicitly_wait(5)
print("搜索完成")

finally:
driver.quit()

if __name__ == "__main__":
main()

常用配置选项

Chrome 选项详解

选项说明示例
--headless无界面模式--headless
--no-sandbox跳过沙箱检查--no-sandbox
--disable-dev-shm-usage禁用 /dev/shm--disable-dev-shm-usage
--disable-gpu禁用 GPU 加速--disable-gpu
--window-size设置窗口大小--window-size=1920,1080
--user-agent自定义 User-Agent--user-agent="..."
--disable-images禁用图片加载--disable-images
--disable-javascript禁用 JavaScript--disable-javascript
--disable-extensions禁用扩展--disable-extensions
--disable-plugins禁用插件--disable-plugins
--disable-css禁用 CSS--disable-css
--hide-scrollbars隐藏滚动条--hide-scrollbars
--mute-audio静音--mute-audio
--disable-web-security禁用 Web 安全--disable-web-security
--disable-features禁用特定功能--disable-features=VizDisplayCompositor

配置示例

高性能模式(快速加载)

options = Options()
options.headless = True
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--disable-gpu')
options.add_argument('--disable-images') # 不加载图片
options.add_argument('--disable-plugins')
options.add_argument('--disable-extensions')
options.add_argument('--mute-audio')
options.add_argument('--window-size=1920,1080')

兼容性模式(完整渲染)

options = Options()
options.headless = True
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--window-size=1920,1080')
options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36')

移动端模拟

options = Options()
options.headless = True
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')

# 移动设备配置
mobile_emulation = {
"deviceMetrics": {
"width": 375,
"height": 667,
"pixelRatio": 2.0
},
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15"
}
options.add_experimental_option("mobileEmulation", mobile_emulation)

实战案例

案例 1:网页抓取

#!/usr/bin/env python3
# web_scraper.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import json

class WebScraper:
def __init__(self):
self.options = Options()
self.options.headless = True
self.options.add_argument('--no-sandbox')
self.options.add_argument('--disable-dev-shm-usage')
self.options.add_argument('--disable-images')
self.driver = None

def start(self):
self.driver = webdriver.Chrome(options=self.options)
return self

def scrape(self, url, selectors):
"""抓取网页数据"""
try:
print(f"正在访问: {url}")
self.driver.get(url)

# 等待页面加载
WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "body"))
)

time.sleep(2) # 额外等待

results = {}
for key, selector in selectors.items():
try:
elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
results[key] = [elem.text.strip() for elem in elements]
except Exception as e:
print(f"抓取 {key} 时出错: {e}")
results[key] = []

return results

except Exception as e:
print(f"抓取失败: {e}")
return {}

def screenshot(self, filename="screenshot.png"):
"""保存截图"""
if self.driver:
self.driver.save_screenshot(filename)
print(f"截图已保存: {filename}")

def close(self):
"""关闭浏览器"""
if self.driver:
self.driver.quit()
print("浏览器已关闭")

# 使用示例
if __name__ == "__main__":
scraper = WebScraper().start()

# 抓取示例页面
selectors = {
'titles': 'h1, h2, h3',
'links': 'a',
'paragraphs': 'p'
}

results = scraper.scrape("https://httpbin.org/html", selectors)

# 输出结果
for key, values in results.items():
print(f"\n{key}:")
for value in values[:5]: # 只显示前 5 个
print(f" - {value}")

# 保存截图
scraper.screenshot()

# 关闭
scraper.close()

案例 2:自动化测试

#!/usr/bin/env python3
# test_login.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

class LoginTest:
def __init__(self):
options = Options()
options.headless = True
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
self.driver = webdriver.Chrome(options=options)

def test_login(self, login_url, username, password):
"""测试登录功能"""
try:
print(f"访问登录页面: {login_url}")
self.driver.get(login_url)

# 等待登录表单
username_field = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.NAME, "username"))
)

password_field = self.driver.find_element(By.NAME, "password")
submit_button = self.driver.find_element(By.XPATH, "//input[@type='submit']")

# 输入凭据
print("输入用户名和密码...")
username_field.clear()
username_field.send_keys(username)
password_field.clear()
password_field.send_keys(password)

# 提交表单
print("提交登录表单...")
submit_button.click()

# 等待重定向或页面变化
time.sleep(3)

# 检查是否登录成功
if "dashboard" in self.driver.current_url or "welcome" in self.driver.page_source.lower():
print("✅ 登录测试通过")
return True
else:
print("❌ 登录测试失败")
return False

except Exception as e:
print(f"❌ 登录测试出错: {e}")
return False

def close(self):
self.driver.quit()

# 运行测试
if __name__ == "__main__":
test = LoginTest()
success = test.test_login(
"https://example.com/login",
"test_user",
"test_password"
)
test.close()

案例 3:多标签页处理

#!/usr/bin/env python3
# multi_tab.py

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time

options = Options()
options.headless = True
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome(options=options)

try:
# 打开第一个标签页
driver.get("https://www.baidu.com")
print(f"标签页 1: {driver.title}")

# 打开新标签页
driver.execute_script("window.open('https://www.google.com', '_blank');")
driver.switch_to.window(driver.window_handles[1])
print(f"标签页 2: {driver.title}")

# 打开第三个标签页
driver.execute_script("window.open('https://www.github.com', '_blank');")
driver.switch_to.window(driver.window_handles[2])
print(f"标签页 3: {driver.title}")

# 切换回第一个标签页
driver.switch_to.window(driver.window_handles[0])
print(f"切换回标签页 1: {driver.title}")

# 获取所有标签页
print(f"\n总共打开了 {len(driver.window_handles)} 个标签页")

# 关闭当前标签页
driver.close()

# 切换到剩余标签页中的第一个
driver.switch_to.window(driver.window_handles[0])
print(f"剩余标签页: {driver.title}")

finally:
driver.quit()

故障排除

常见问题及解决方案

问题 1:ChromeDriver 版本不匹配

错误信息:

SessionNotCreatedException: session not created: This version of ChromeDriver only supports Chrome version XX

解决方案:

# 方法 1:使用 webdriver_manager 自动管理
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service

service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=options)

# 方法 2:手动下载匹配版本
# 1. 查看 Chrome 版本
google-chrome --version

# 2. 下载对应版本的 ChromeDriver
# https://chromedriver.chromium.org/downloads

# 3. 替换系统中的 chromedriver
sudo rm /usr/local/bin/chromedriver
sudo mv chromedriver /usr/local/bin/
sudo chmod +x /usr/local/bin/chromedriver

问题 2:权限错误

错误信息:

Permission denied: '/usr/local/bin/chromedriver'

解决方案:

# 设置正确的权限
sudo chown root:root /usr/local/bin/chromedriver
sudo chmod +x /usr/local/bin/chromedriver

# 或者将 chromedriver 放在用户目录下
mkdir -p ~/bin
mv chromedriver ~/bin/
echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

问题 3:内存不足

错误信息:

DevToolsActivePort file doesn't exist

解决方案:

# 添加更多内存选项
options = Options()
options.headless = True
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--disable-gpu')
options.add_argument('--disable-software-rasterizer')
options.add_argument('--disable-setuid-sandbox')
options.add_argument('--disable-extensions')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--disable-background-timer-throttling')
options.add_argument('--disable-backgrounding-occluded-windows')
options.add_argument('--disable-renderer-backgrounding')

# 设置内存限制
options.add_argument('--memory-pressure-off')
options.add_argument('--max_old_space_size=4096')

问题 4:页面加载失败

解决方案:

# 添加更多网络选项
options = Options()
options.headless = True
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--disable-gpu')

# 网络配置
options.add_argument('--disable-web-security')
options.add_argument('--allow-running-insecure-content')
options.add_argument('--disable-features=VizDisplayCompositor')
options.add_argument('--ignore-certificate-errors')
options.add_argument('--ignore-ssl-errors')

# 设置超时
driver = webdriver.Chrome(options=options)
driver.set_page_load_timeout(30) # 30 秒超时
driver.implicitly_wait(10) # 隐式等待 10 秒

调试技巧

1. 查看 Chrome 日志

options = Options()
options.headless = True
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')

# 启用详细日志
options.add_argument('--enable-logging')
options.add_argument('--v=1')
options.add_argument('--log-level=0')

driver = webdriver.Chrome(options=options)

# 获取日志
logs = driver.get_log('browser')
for log in logs:
print(log)

2. 保存页面源码

try:
driver.get(url)

# 保存页面源码
with open('page_source.html', 'w', encoding='utf-8') as f:
f.write(driver.page_source)

# 保存截图
driver.save_screenshot('debug_screenshot.png')

except Exception as e:
print(f"调试信息: {e}")

3. 使用远程调试

# 启动 Chrome 并启用远程调试
google-chrome --headless --disable-gpu --remote-debugging-port=9222

# 然后连接
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")

driver = webdriver.Chrome(options=options)

性能优化

1. 禁用不必要的功能

options = Options()
options.headless = True

# 禁用图片加载
prefs = {
"profile.managed_default_content_settings.images": 2
}
options.add_experimental_option("prefs", prefs)

# 禁用 CSS 加载
prefs = {
"profile.default_content_settings.stylesheets": 2
}
options.add_experimental_option("prefs", prefs)

# 禁用 JavaScript(如果不需要)
options.add_argument('--disable-javascript')

2. 使用无头模式优化

options = Options()
options.headless = True

# 使用 new headless 实现(Chrome 96+)
options.add_argument('--headless=new')

3. 复用浏览器实例

# 在同一浏览器中执行多个任务
driver = webdriver.Chrome(options=options)

# 任务 1
driver.get("https://site1.com")
do_task1(driver)

# 任务 2
driver.get("https://site2.com")
do_task2(driver)

# 关闭
driver.quit()

最佳实践

1. 编码规范

# ✅ 推荐:封装为类
class ChromeDriver:
def __init__(self, headless=True):
self.options = self._configure_options(headless)
self.driver = None

def _configure_options(self, headless):
options = Options()
if headless:
options.headless = True
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
return options

def __enter__(self):
self.driver = webdriver.Chrome(options=self.options)
return self

def __exit__(self, exc_type, exc_val, exc_tb):
if self.driver:
self.driver.quit()

# 使用
with ChromeDriver() as driver:
driver.get("https://example.com")

2. 错误处理

from selenium.common.exceptions import TimeoutException, NoSuchElementException

def safe_find_element(driver, by, value, timeout=10):
try:
element = WebDriverWait(driver, timeout).until(
EC.presence_of_element_located((by, value))
)
return element
except TimeoutException:
print(f"未找到元素: {value}")
return None

3. 配置管理

# config.py
import os

class Config:
CHROME_OPTIONS = {
'headless': True,
'window_size': '1920,1080',
'user_agent': 'Mozilla/5.0 (compatible; Bot/1.0)',
}

@classmethod
def get_chrome_options(cls):
options = Options()
for key, value in cls.CHROME_OPTIONS.items():
if key == 'headless':
if value:
options.add_argument('--headless')
elif key == 'window_size':
options.add_argument(f'--window-size={value}')
elif key == 'user_agent':
options.add_argument(f'--user-agent={value}')
return options

总结

在 Linux 服务器上成功搭建 Chrome + Selenium 无界面环境的关键点:

  1. 正确安装 Chrome:使用官方 .deb 包或仓库
  2. 匹配 ChromeDriver 版本:确保与 Chrome 版本兼容
  3. 配置必要参数--no-sandbox--disable-dev-shm-usage
  4. 优化性能:禁用不必要的功能
  5. 错误处理:添加适当的异常捕获
  6. 测试验证:使用简单脚本验证环境

掌握这些知识,您就能在服务器环境中高效使用 Selenium 进行自动化测试和网页抓取!

相关资源

持续实践,您将成为 Selenium 自动化专家!