文章目录
-
- 一、环境准备(新手必做)
-
- [1. 安装 python](#1. 安装 python)
- [2. 安装 Selenium 库](#2. 安装 Selenium 库)
- [3. 下载浏览器驱动(关键!)](#3. 下载浏览器驱动(关键!))
- [二、Selenium 核心操作(基础语法)](#二、Selenium 核心操作(基础语法))
-
- [1. 基础示例:打开浏览器并访问网页](#1. 基础示例:打开浏览器并访问网页)
- [2. 核心操作详解(新手重点)](#2. 核心操作详解(新手重点))
- [3. 智能等待(替代 time.sleep,更优雅)](#3. 智能等待(替代 time.sleep,更优雅))
- 三、实战案例:爬取动态加载的商品数据
- 四、避坑技巧(新手常踩的坑)
- 五、进阶用法(新手后续可学)
Selenium 是专门用于模拟浏览器操作的工具,核心优势是能处理「JavaScript 动态渲染」的页面(比如需要滚动加载、点击按钮、登录后才能看到的内容)。我会从 环境准备、核心操作、实战案例、避坑技巧 四个方面,手把手教你用 Selenium 爬取动态页面。
一、环境准备(新手必做)
1. 安装 python
python安装教程:https://blog.csdn.net/2501_91538706/article/details/148033554
2. 安装 Selenium 库
打开终端/命令行,执行:
bash
pip install selenium
3. 下载浏览器驱动(关键!)
Selenium 需要「驱动程序」来控制浏览器,不同浏览器对应不同驱动,新手优先用 Chrome:
- Chrome 驱动下载 :https://sites.google.com/chromium.org/driver/
- 注意:驱动版本必须和你的 Chrome 浏览器版本匹配(查看 Chrome 版本:设置→关于 Chrome);
- Windows:下载后解压得到
chromedriver.exe,建议放到 Python 安装目录(或直接指定路径); - Mac/Linux:下载后解压,放到
/usr/local/bin目录(方便调用)。
二、Selenium 核心操作(基础语法)
先从最常用的「浏览器控制+元素定位」学起,以下是新手必掌握的核心操作:
1. 基础示例:打开浏览器并访问网页
python
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
# 1. 初始化浏览器(Chrome)
# 如果驱动不在系统路径,需指定 executable_path(Windows 示例)
# driver = webdriver.Chrome(executable_path='C:/chromedriver.exe')
driver = webdriver.Chrome() # 驱动在系统路径时可直接用
# 2. 访问网页
driver.get('https://www.baidu.com')
# 3. 窗口操作
driver.maximize_window() # 最大化窗口
print('当前页面标题:', driver.title) # 输出页面标题
# 4. 元素定位(核心!):定位百度搜索框并输入内容
# 常用定位方式:By.ID / By.CLASS_NAME / By.XPATH / By.CSS_SELECTOR
search_box = driver.find_element(By.ID, 'kw') # 通过ID定位搜索框
search_box.send_keys('Python Selenium 教程') # 输入文字
# 5. 点击操作:点击搜索按钮
search_btn = driver.find_element(By.ID, 'su')
search_btn.click()
# 6. 等待页面加载(强制等待,新手先用)
time.sleep(2) # 等待2秒
# 7. 提取数据:获取搜索结果的第一个标题
first_result = driver.find_element(By.XPATH, '//div[@id="content_left"]/div[1]/h3/a')
print('第一个搜索结果:', first_result.text)
print('结果链接:', first_result.get_attribute('href'))
# 8. 关闭浏览器(可选:close()关闭当前标签,quit()关闭整个浏览器)
time.sleep(3)
driver.quit()
2. 核心操作详解(新手重点)
| 操作类型 | 代码示例 | 说明 |
|---|---|---|
| 元素定位 | driver.find_element(By.ID, 'id值') |
定位单个元素(找不到会报错) |
driver.find_elements(By.CLASS_NAME, '类名') |
定位多个元素(返回列表) | |
| 输入内容 | element.send_keys('文本') |
向输入框输入文字 |
| 点击元素 | element.click() |
点击按钮/链接/复选框等 |
| 提取文本 | element.text |
获取元素的可见文本 |
| 提取属性 | element.get_attribute('href') |
获取元素的属性(如链接、图片src) |
| 页面滚动 | driver.execute_script('window.scrollTo(0, document.body.scrollHeight)') |
滚动到页面底部 |
| 切换标签页 | driver.switch_to.window(driver.window_handles[1]) |
切换到第二个标签页 |
| 等待页面加载 | WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'id值'))) |
智能等待(推荐) |
3. 智能等待(替代 time.sleep,更优雅)
time.sleep() 是「强制等待」,不管页面是否加载完都等固定时间;Selenium 提供「显式等待」,直到目标元素出现才继续,避免无效等待:
python
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 等待10秒,直到ID为"kw"的元素出现(最多等10秒,找到就继续)
wait = WebDriverWait(driver, 10)
search_box = wait.until(EC.presence_of_element_located((By.ID, 'kw')))
三、实战案例:爬取动态加载的商品数据
以「某电商平台商品列表」为例(模拟动态加载场景),爬取需要滚动页面才能加载的商品名称和价格:
python
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
import pandas as pd
# 初始化浏览器
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.taobao.com') # 淘宝首页(动态加载示例)
# 步骤1:搜索商品(先定位搜索框,输入关键词)
wait = WebDriverWait(driver, 10)
# 定位淘宝搜索框(通过ID)
search_box = wait.until(EC.presence_of_element_located((By.ID, 'q')))
search_box.send_keys('Python编程书籍')
# 点击搜索按钮
search_btn = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'btn-search')))
search_btn.click()
# 步骤2:滚动页面加载更多商品
goods_data = []
# 滚动3次,每次加载更多商品
for i in range(3):
# 滚动到页面底部
driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'item J_MouserOnverReq')))
time.sleep(2) # 等待加载
# 提取商品信息
goods_list = driver.find_elements(By.CLASS_NAME, 'item J_MouserOnverReq')
for goods in goods_list:
try:
# 商品名称
name = goods.find_element(By.CLASS_NAME, 'J_ClickStat').text
# 商品价格
price = goods.find_element(By.CLASS_NAME, 'J_price').text
goods_data.append({
'商品名称': name,
'价格': price
})
except Exception as e:
continue
# 步骤3:保存数据
df = pd.DataFrame(goods_data)
df.drop_duplicates(inplace=True) # 去重
df.to_excel('淘宝商品数据.xlsx', index=False)
print(f'共爬取{len(df)}条商品数据,已保存到Excel')
# 关闭浏览器
driver.quit()
代码关键说明
- 显式等待 :用
WebDriverWait等待元素可点击/出现,避免因页面加载慢导致的定位失败; - 页面滚动 :通过
execute_script执行 JS 代码滚动页面,触发动态加载; - 异常处理 :部分商品元素可能缺失,用
try-except避免爬虫崩溃; - 去重 :动态加载可能重复获取商品,用
drop_duplicates去重。
四、避坑技巧(新手常踩的坑)
-
驱动版本不匹配:
-
报错:
SessionNotCreatedException; -
解决:严格匹配 Chrome 版本和驱动版本,或使用
webdriver-manager自动管理驱动(推荐):bashpip install webdriver-manager代码中替换驱动初始化:
pythonfrom selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
-
-
元素定位失败:
-
原因:元素还没加载、定位方式错误、元素在 iframe 里;
-
解决:用显式等待、检查定位符(优先用 ID/XPath)、如果是 iframe 需先切换:
python# 切换到iframe(通过ID/索引) driver.switch_to.frame('iframe_id') # 操作完切回主页面 driver.switch_to.default_content()
-
-
被网站检测为爬虫:
-
解决:添加浏览器伪装(禁用自动化提示):
pythonoptions = webdriver.ChromeOptions() options.add_experimental_option('excludeSwitches', ['enable-automation']) options.add_experimental_option('useAutomationExtension', False) driver = webdriver.Chrome(options=options)
-
-
页面加载慢:
-
解决:设置页面加载超时,或禁止加载图片/视频(提升速度):
pythonoptions = webdriver.ChromeOptions() # 禁止加载图片 prefs = {'profile.managed_default_content_settings.images': 2} options.add_experimental_option('prefs', prefs) driver = webdriver.Chrome(options=options) # 设置加载超时 driver.set_page_load_timeout(10)
-
五、进阶用法(新手后续可学)
-
模拟登录:定位账号/密码输入框,输入信息后点击登录,或读取 cookies 免登录;
-
无头模式 :不显示浏览器窗口,后台运行(适合服务器):
pythonoptions = webdriver.ChromeOptions() options.add_argument('--headless') # 无头模式 options.add_argument('--disable-gpu') # 禁用GPU(避免报错) driver = webdriver.Chrome(options=options) -
处理弹窗 :切换到 alert 弹窗并确认/取消:
pythonalert = driver.switch_to.alert alert.accept() # 确认 # alert.dismiss() # 取消