有些场景不能用BeautifulSoup解决,例如一些弹框点击,模拟操作浏览器页面,这个时候,就得使用selenium

安装selenium

1
pip3 install selenium

安装chrome和驱动chromedriver

chrome官方下载地址

chromedriver国内驱动

chrome和chromedriver的版本号要对应才可以

上面的驱动已经没有更新最新驱动了。可以在下面链接获取匹配的驱动

chromedriver国内最新镜像驱动

windows配置环境变量

  • 二选一

  • 把下载的chromedriver.exe复制到chrome的chrome.exe同目录,并且复制到python.exe同目录下

  • 或者把chromedriver.exe的路径添加到windows的系统环境变量

linux配置

  • chrome和chromedriver需要相同版本,所以我们安装指定版本,目前最新版本是121.0.6167.185,但是驱动只更新到121.0.6167.184
  • 下载121.0.6167.184版本的chromedriver
1
2
3
wget https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/linux64/chromedriver-linux64.zip -O chromedriver_linux64.zip
#解压
unzip chromedriver_linux64.zip -d /
  • 下载安装121.0.6167.184版本的chrome
1
2
3
wget https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_121.0.6167.184-1_amd64.deb
sudo dpkg -i google-chrome-stable_121.0.6167.184-1_amd64.deb
sudo apt-get install -f
  • 添加环境变量
1
2
sudo mv /chromedriver /usr/local/bin/
sudo sh -c 'echo "PATH=\$PATH:/usr/bin/google-chrome:/usr/local/bin/chromedriver" >> /etc/environment'

基础使用

1
2
3
4
5
from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http://www.baidu.com/')
#...

ChromeOptions配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from selenium import webdriver
# 创建ChromeOptions实例
option = webdriver.ChromeOptions()
#禁用了Chrome浏览器的沙箱功能。沙箱是一种安全机制,用于限制进程的权限,以防止恶意软件对系统进行攻击。禁用沙箱可能会增加系统的风险
option.add_argument('--no-sandbox')
#禁用了Chrome浏览器在/dev/shm上创建临时文件的使用。在某些情况下,使用这个选项可以提高性能或解决一些特定的问题
option.add_argument('--disable-dev-shm-usage')
#禁用了Chrome浏览器的扩展功能,即禁止加载和运行浏览器扩展程序。这可以用于确保浏览器的纯净性,或者解决一些与扩展程序相关的问题
option.add_argument('--disable-extensions')
#将Chrome浏览器设置为无头模式,即在没有图形界面的情况下运行。这对于自动化测试、爬虫和其他需要在后台运行的任务非常有用
option.add_argument('--headless')
#禁用了Chrome浏览器中的信息栏,例如保存密码的提示等
option.add_argument('--disable-extensions')
#禁用了Chrome浏览器中的信息栏,例如保存密码的提示等
option.add_argument('--disable-infobars')
#禁用了浏览器的客户端导航,即禁止通过JavaScript导航到新的页面。这可以用于防止某些类型的网络攻击
option.add_argument('--disable-browser-side-navigation')
# 添加代理设置(此处我使用的是socks5 http代理:proxy-server=https://127.0.0.1:8888)
option.add_argument('proxy-server=socks5://127.0.0.1:8888')
#其他..
driver = webdriver.Chrome(options=option)
driver.get('http://www.baidu.com/')
#...
  • 还有一个很常用的。等待元素出现。例如点击A按钮之后,过一会才会出现B元素,那么需要使用到WebDriverWait
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


# 创建ChromeOptions实例
option = webdriver.ChromeOptions()
option.add_argument('--headless')
option.add_argument('--disable-extensions')
option.add_argument('proxy-server=socks5://127.0.0.1:8888')
driver = webdriver.Chrome(options=option)
driver.get('http://www.baidu.com/')

# 使用 WebDriverWait 等待页面加载完成(此处是等待 class为enter-btn的元素出现,再执行之后的代码)
wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'enter-btn')))
#...

新标签页

如果有打开新标签页的情况可以使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#...
# 记录当前窗口句柄
handles = driver.window_handles

# 点击 a 链接(此处会打开新标签页)
pick_links[0].click()

# 等待新窗口打开
wait.until(EC.new_window_is_opened(handles))

# 切换到新窗口
handles = driver.window_handles

driver.switch_to.window(handles[-1])
#...

find_element 用法

  1. 根据id寻找元素
1
element.find_element(By.ID, 'postlist')
  1. 根据class寻找元素,如果会找到多个。就用find_elements
1
element.find_element(By.CLASS_NAME, 'enter-btn')
  1. 根据id,模糊寻找message_
1
element.find_element(By.XPATH, "//*[contains(@id, 'message_')]")
  1. 根据class模糊寻找元素message_
1
element.find_element(By.XPATH, './/*[contains(@class, "message_")]')

以上用法基本可以满足涉及到selenium的日常脚本需求了。