使用Selenium来抓取动态网页。动态网页通常是指那些通过JavaScript动态加载内容的网页,这些内容在初始HTML中并不存在,因此使用传统的requests库无法获取到这些动态生成的内容。Selenium可以模拟浏览器行为,等待JavaScript执行并渲染页面,从而获取到完整的页面内容。

下面是一个使用 Selenium 编写的动态网页爬虫示例,用于抓取京东商品搜索页面的信息(商品名称和价格),并附有详细注释:
python
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
# 设置 Chrome 浏览器选项
chrome_options = Options()
chrome_options.add_argument('--headless') # 无头模式,不显示浏览器窗口
chrome_options.add_argument('--disable-gpu') # 禁用GPU加速
chrome_options.add_argument('--no-sandbox') # Linux 系统需要添加此参数
# 创建 WebDriver 服务 (需要下载对应版本的 chromedriver)
service = Service(executable_path='./chromedriver') # 替换为你的 chromedriver 路径
# 初始化浏览器驱动
driver = webdriver.Chrome(service=service, options=chrome_options)
try:
# 1. 打开目标网页
driver.get('https://search.jd.com/Search?keyword=手机')
print("已打开京东搜索页面...")
# 2. 等待页面加载 - 显式等待(推荐)
# 等待直到商品列表元素出现(最长等待10秒)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".gl-item"))
)
print("商品列表加载完成!")
# 3. 模拟滚动页面以加载更多内容(针对懒加载页面)
# 动态页面通常需要滚动才能加载更多元素
for i in range(3): # 滚动3次
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
print(f"滚动页面 {i+1}/3...")
time.sleep(1.5) # 等待新内容加载
# 4. 定位所有商品元素
# 使用 CSS 选择器获取商品列表项
items = driver.find_elements(By.CSS_SELECTOR, '.gl-item')
print(f"共找到 {len(items)} 个商品")
# 5. 遍历并提取数据
results = []
for item in items:
try:
# 在单个商品元素内查找名称和价格
name = item.find_element(By.CSS_SELECTOR, '.p-name em').text.strip()
price = item.find_element(By.CSS_SELECTOR, '.p-price i').text.strip()
results.append({'name': name, 'price': price})
except Exception as e:
print(f"提取商品时出错: {str(e)}")
continue
# 6. 打印抓取结果
print("\n抓取结果:")
for i, result in enumerate(results[:5], 1): # 只打印前5个结果
print(f"{i}. {result['name']} - 价格: {result['price']}")
print(f"\n共抓取 {len(results)} 条商品数据")
except Exception as e:
print(f"爬虫执行出错: {str(e)}")
finally:
# 7. 关闭浏览器
driver.quit()
print("浏览器已关闭")
代码详细解释:
1、导入必要模块:
webdriver
:控制浏览器By
:元素定位方式WebDriverWait
和expected_conditions
:显式等待Options
:浏览器配置选项
2、浏览器设置:
headless
模式:后台运行不显示界面- 禁用 GPU 和沙盒模式:提高稳定性和兼容性
3、、初始化驱动:
- 需要下载对应 Chrome 版本的
chromedriver
- 指定 driver 路径和服务
4、页面加载等待:
- 使用显式等待(
WebDriverWait
)确保目标元素加载完成 - 比
time.sleep()
更高效智能
5、模拟滚动:
- 执行 JavaScript 滚动到底部
- 分次滚动并等待加载(针对懒加载页面)
6、元素定位:
- 使用 CSS 选择器定位商品列表项
- 在单个商品元素内进一步提取名称和价格
7、异常处理:
- 捕获单个商品提取时的异常
- 整体爬虫的异常捕获
8、资源清理:
finally
块确保关闭浏览器释放资源
使用前准备:
1、安装必要库:
pip install selenium webdriver-manager
2、下载对应浏览器版本的驱动:
-
或使用
webdriver-manager
自动管理:scssfrom webdriver_manager.chrome import ChromeDriverManager service = Service(ChromeDriverManager().install())
常见问题解决:
1、元素定位失败:
- 检查网页结构是否更新
- 使用浏览器开发者工具验证选择器
2、内容加载不全:
- 增加滚动次数和等待时间
- 调整显式等待超时时间
3、反爬措施应对:
-
添加
user-agent
头:inichrome_options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36')
-
添加代理:
arduinochrome_options.add_argument('--proxy-server=http://your-proxy-ip:port')
这个爬虫可以扩展用于其他动态网站,只需修改:目标 URL、元素定位选择器、滚动/等待策略、数据提取逻辑等就能实现一个完整的爬虫过程。如有不懂可以留言讨论。