Selenium基础

学习使用Selenium进行浏览器自动化操作,掌握动态网页爬取技术

内容概述

Selenium是一个强大的浏览器自动化工具,它允许我们通过编程方式控制浏览器执行各种操作,如点击、输入、导航等。与Requests等静态爬取工具不同,Selenium能够处理需要JavaScript渲染的动态网页,是爬虫工程师的重要工具之一。

安装配置

学习如何安装Selenium和配置ChromeDriver

元素选择

掌握By类的各种元素选择器

高级操作

学习Keys和Options的使用方法

Selenium安装与配置

1. 安装Selenium库

使用pip命令安装Selenium库:

终端命令
pip install selenium

2. 下载ChromeDriver

ChromeDriver是Selenium控制Chrome浏览器的驱动程序,需要下载与您的Chrome浏览器版本相匹配的ChromeDriver。

  1. 首先查看您的Chrome浏览器版本(在Chrome中输入 chrome://version/ 查看)
  2. 在下载页面找到与您的Chrome版本匹配的ChromeDriver版本
  3. 下载对应操作系统的压缩包(Windows、macOS或Linux)
  4. 解压压缩包,将chromedriver.exe文件放置在一个方便的位置
  5. 确保chromedriver所在目录已添加到系统环境变量PATH中,或者在代码中指定其路径

3. 第一个Selenium程序

创建一个简单的程序来验证Selenium是否安装正确:

python
from selenium import webdriver
from selenium.webdriver.chrome.service import Service

# 指定ChromeDriver路径(如果未添加到环境变量)
# service = Service('path/to/chromedriver.exe')
# driver = webdriver.Chrome(service=service)

driver = webdriver.Chrome()

try:
    # 打开百度首页
    driver.get('https://www.baidu.com')
    print("页面标题:", driver.title)
    
    # 等待5秒后关闭浏览器
    import time
    time.sleep(5)
finally:
    # 无论如何都要关闭浏览器
    driver.quit()

By选择器详解

Selenium提供了多种方式来定位网页元素,这些方式通过By类来实现。掌握不同的选择器方法,能够帮助我们更高效地定位和操作页面元素。

1. By类的导入与基本用法

python
from selenium.webdriver.common.by import By

# 基本语法
element = driver.find_element(By.ID, 'element_id')  # 通过ID查找单个元素
elements = driver.find_elements(By.CLASS_NAME, 'element_class')  # 通过类名查找多个元素

2. ID选择器 (By.ID)

通过元素的id属性定位,是最快速、最精确的定位方式。

HTML示例:
html
<input type="text" id="username" placeholder="请输入用户名">
Python代码:
python
username_input = driver.find_element(By.ID, 'username')
username_input.send_keys('test_user')

3. Class选择器 (By.CLASS_NAME)

通过元素的class属性定位,可用于定位一组具有相同样式的元素。

HTML示例:
html
<div class="product-item">产品1</div>
<div class="product-item">产品2</div>
<div class="product-item">产品3</div>
Python代码:
python
product_items = driver.find_elements(By.CLASS_NAME, 'product-item')
for item in product_items:
    print(item.text)

4. Name选择器 (By.NAME)

通过元素的name属性定位,常用于表单元素。

HTML示例:
html
<input type="password" name="user_password" placeholder="请输入密码">
Python代码:
python
password_input = driver.find_element(By.NAME, 'user_password')
password_input.send_keys('secret_password')

5. Tag选择器 (By.TAG_NAME)

通过HTML标签名定位元素。

HTML示例:
html
<a href="https://www.example.com">访问示例网站</a>
<a href="https://www.test.com">访问测试网站</a>
Python代码:
python
links = driver.find_elements(By.TAG_NAME, 'a')
for link in links:
    print(link.get_attribute('href'))

6. CSS选择器 (By.CSS_SELECTOR)

通过CSS选择器定位元素,是一种功能强大、灵活的定位方式。

HTML示例:
html
<div class="nav">
    <ul>
        <li class="active"><a href="#home">首页</a></li>
        <li><a href="#news">新闻</a></li>
    </ul>
</div>
Python代码:
python
# 通过CSS选择器定位激活状态的导航项
active_nav = driver.find_element(By.CSS_SELECTOR, '.nav li.active a')
print(active_nav.text)  # 输出:首页

# 定位所有导航链接
nav_links = driver.find_elements(By.CSS_SELECTOR, '.nav ul li a')
for link in nav_links:
    print(link.text, link.get_attribute('href'))

7. XPath选择器 (By.XPATH)

通过XPath表达式定位元素,是最灵活的定位方式,几乎可以定位到任何元素。

HTML示例:
html
<form id="login-form">
    <input type="text" id="email" placeholder="邮箱">
    <input type="password" id="pwd" placeholder="密码">
    <button type="submit">登录</button>
</form>
Python代码:
python
# 通过XPath定位登录表单中的邮箱输入框
email_input = driver.find_element(By.XPATH, '//form[@id="login-form"]//input[@id="email"]')
email_input.send_keys('user@example.com')

# 通过XPath定位密码输入框(使用相对路径)
password_input = driver.find_element(By.XPATH, '//input[@placeholder="密码"]')
password_input.send_keys('password123')

# 定位登录按钮并点击
login_button = driver.find_element(By.XPATH, '//button[text()="登录"]')
login_button.click()

Keys类详解

Keys类提供了一组键盘按键的常量,可以模拟键盘操作,如Enter、Tab、箭头键等。

1. Keys类的导入

python
from selenium.webdriver.common.keys import Keys

2. 基本按键操作

使用Keys类来模拟键盘按键操作:

python
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

# 创建浏览器实例
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')

# 定位搜索框并输入内容
search_input = driver.find_element(By.ID, 'kw')
search_input.send_keys('Python Selenium')

# 模拟按下Enter键提交搜索
search_input.send_keys(Keys.ENTER)

# 其他常用按键示例
# search_input.send_keys(Keys.TAB)  # Tab键
# search_input.send_keys(Keys.ESCAPE)  # ESC键
# search_input.send_keys(Keys.BACKSPACE)  # 退格键

# 组合键示例
# search_input.send_keys(Keys.CONTROL, 'a')  # Ctrl+A 全选
# search_input.send_keys(Keys.CONTROL, 'c')  # Ctrl+C 复制
# search_input.send_keys(Keys.CONTROL, 'v')  # Ctrl+V 粘贴

# 关闭浏览器
driver.quit()

3. 使用ActionChains执行复杂键盘操作

对于更复杂的键盘操作,可以使用ActionChains类:

python
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

# 创建浏览器实例
driver = webdriver.Chrome()
driver.get('https://example.com')

# 定位一个可输入元素
input_element = driver.find_element(By.ID, 'input-box')
input_element.click()  # 聚焦到输入框

# 创建ActionChains对象
actions = ActionChains(driver)

# 输入文本
actions.send_keys('Hello, World!')

# 执行Ctrl+A全选
actions.key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL)

# 执行Ctrl+C复制
actions.key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL)

# 移动到另一个输入框
another_input = driver.find_element(By.ID, 'another-input')
actions.move_to_element(another_input).click()

# 执行Ctrl+V粘贴
actions.key_down(Keys.CONTROL).send_keys('v').key_up(Keys.CONTROL)

# 执行所有操作
actions.perform()

# 关闭浏览器
driver.quit()

Options类与无头浏览器

Options类用于配置Chrome浏览器的启动参数,如设置窗口大小、启用无头模式等。无头模式(Headless)允许在不显示浏览器界面的情况下运行Selenium,适用于服务器环境或需要提高执行速度的场景。

1. Options类的导入

python
from selenium.webdriver.chrome.options import Options

2. 配置无头浏览器

设置Chrome浏览器在无头模式下运行:

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

# 创建Options对象
chrome_options = Options()

# 添加无头模式参数
chrome_options.add_argument('--headless')

# 添加禁用GPU参数(某些系统需要)
chrome_options.add_argument('--disable-gpu')

# 添加窗口大小参数
chrome_options.add_argument('--window-size=1920,1080')

# 创建浏览器实例时传入配置
# 如果ChromeDriver没有添加到环境变量,还需要指定service
# from selenium.webdriver.chrome.service import Service
# service = Service('path/to/chromedriver.exe')
# driver = webdriver.Chrome(service=service, options=chrome_options)

driver = webdriver.Chrome(options=chrome_options)

try:
    # 访问网站
    driver.get('https://www.baidu.com')
    
    # 输出页面标题
    print("页面标题:", driver.title)
    
    # 可以进行各种操作,如查找元素、截图等
    # driver.save_screenshot('baidu.png')  # 截取屏幕截图
    
finally:
    # 关闭浏览器
    driver.quit()

3. 常用Options配置参数

以下是一些常用的ChromeOptions配置参数:

python
from selenium.webdriver.chrome.options import Options

# 创建Options对象
chrome_options = Options()

# 基本配置
chrome_options.add_argument('--headless')  # 无头模式
chrome_options.add_argument('--disable-gpu')  # 禁用GPU
chrome_options.add_argument('--window-size=1920,1080')  # 设置窗口大小

# 性能相关配置
chrome_options.add_argument('--no-sandbox')  # 禁用沙盒模式
chrome_options.add_argument('--disable-dev-shm-usage')  # 禁用/dev/shm使用
chrome_options.add_argument('--disable-extensions')  # 禁用扩展
chrome_options.add_argument('--start-maximized')  # 窗口最大化启动
chrome_options.add_argument('--incognito')  # 隐身模式

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

# 日志相关配置
chrome_options.add_argument('--log-level=3')  # 设置日志级别:3表示只显示错误
chrome_options.add_argument('--silent')  # 静默模式

# 代理配置
# chrome_options.add_argument('--proxy-server=http://proxy_ip:proxy_port')

# 禁用自动化特征检测
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
chrome_options.add_experimental_option('useAutomationExtension', False)

# 创建浏览器实例时传入配置
driver = webdriver.Chrome(options=chrome_options)

综合案例:使用Selenium自动搜索信息

下面是一个综合案例,展示如何使用Selenium、By选择器和Keys类来自动完成一次搜索操作。

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

# 创建Options对象,配置无头模式
chrome_options = Options()
# chrome_options.add_argument('--headless')  # 如需无头模式,取消注释
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--window-size=1920,1080')

# 创建浏览器实例
driver = webdriver.Chrome(options=chrome_options)

try:
    # 步骤1: 访问百度首页
    print("访问百度首页...")
    driver.get('https://www.baidu.com')
    time.sleep(2)  # 等待页面加载
    
    # 步骤2: 定位搜索框并输入搜索词
    print("输入搜索关键词...")
    search_input = driver.find_element(By.ID, 'kw')
    search_input.send_keys('Python Selenium教程')
    time.sleep(1)
    
    # 步骤3: 提交搜索(使用Keys.ENTER)
    print("提交搜索...")
    search_input.send_keys(Keys.ENTER)
    time.sleep(3)  # 等待搜索结果加载
    
    # 步骤4: 提取搜索结果
    print("提取搜索结果...")
    # 使用CSS选择器定位搜索结果标题
    result_titles = driver.find_elements(By.CSS_SELECTOR, 'h3.t a')
    
    # 打印前5个搜索结果的标题和链接
    print("\n前5个搜索结果:")
    for i, title in enumerate(result_titles[:5]):
        print(f"{i+1}. {title.text}")
        print(f"   {title.get_attribute('href')}")
    
    # 步骤5: 点击第一个搜索结果
    print("\n点击第一个搜索结果...")
    if result_titles:
        result_titles[0].click()
        time.sleep(3)  # 等待新页面加载
        
        # 打印当前页面标题
        print(f"\n当前页面标题: {driver.title}")
        
    # 步骤6: 返回上一页
    print("\n返回上一页...")
    driver.back()
    time.sleep(2)
    
finally:
    # 关闭浏览器
    print("\n关闭浏览器...")
    driver.quit()

练习题

请根据所学知识,完成以下练习题:

练习题1:安装配置与基础操作

安装Selenium库并配置ChromeDriver,编写一个简单的Python程序,打开Chrome浏览器并访问您最喜欢的网站。

提示:确保下载的ChromeDriver版本与您的Chrome浏览器版本相匹配,并正确设置路径。

练习题2:By选择器练习

访问百度首页(https://www.baidu.com),使用至少三种不同的By选择器方法定位搜索框和搜索按钮。

提示:可以使用By.ID、By.NAME、By.CSS_SELECTOR、By.XPATH等方法。

练习题3:使用Keys类模拟键盘操作

编写一个程序,使用Selenium打开百度首页,在搜索框中输入"Python",然后使用Keys类模拟按下Tab键,再输入"教程",最后按下Enter键进行搜索。

提示:使用send_keys方法和Keys类的常量来模拟键盘操作。

练习题4:配置无头浏览器

修改练习题1中的程序,配置ChromeOptions以无头模式运行浏览器,访问同一网站并截取屏幕截图保存到本地。

提示:使用add_argument('--headless')配置无头模式,使用save_screenshot方法保存截图。

练习题5:综合应用

编写一个完整的Selenium程序,实现以下功能:

  1. 打开淘宝首页(https://www.taobao.com)
  2. 在搜索框中输入"Python书籍"并搜索
  3. 提取搜索结果的前10个商品名称和价格
  4. 将结果保存到一个文本文件中

提示:淘宝可能有反爬机制,您可能需要添加适当的等待时间或配置用户代理。