当前位置: 首页 > news >正文

Selenium 数据提取全攻略:从元素到页面数据一网打尽

Selenium 提取数据的核心是「先定位元素,再提取内容」,覆盖元素文本、属性值、页面源码、Cookie、JS 动态数据等场景。我会按「基础提取→进阶提取→实战案例→避坑技巧」的逻辑讲解,每个方法都配可直接运行的代码,新手也能快速上手。

一、核心提取思路

Selenium 数据提取的本质是:

  1. 通过 find_element()/find_elements() 定位目标元素(单元素/多元素);
  2. 调用元素的方法/属性,提取文本、属性或执行 JS 获取动态数据;
  3. 对提取的原始数据做清洗(去重、格式转换),最终存储。

二、基础数据提取(最常用)

1. 提取元素可见文本(text 属性)

适用场景:提取标题、价格、评分、按钮文字等可见的文本内容

from selenium import webdriver
from selenium.webdriver.common.by import By# 初始化浏览器
driver = webdriver.Chrome()
driver.get('https://movie.douban.com/top250')
driver.maximize_window()# 定位单个元素:提取第一部电影名称
first_movie_title = driver.find_element(By.CLASS_NAME, 'title').text
print(f'豆瓣Top250第一部电影:{first_movie_title}')# 定位多个元素:提取前5部电影评分
score_elements = driver.find_elements(By.CLASS_NAME, 'rating_num')[:5]
for idx, element in enumerate(score_elements):print(f'第{idx+1}部电影评分:{element.text}')driver.quit()

2. 提取元素属性值(get_attribute() 方法)

适用场景:提取链接(href)、图片地址(src)、输入框值(value)、class 名等元素属性

from selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.get('https://movie.douban.com/top250')# 提取第一部电影的链接(href属性)
movie_link = driver.find_element(By.XPATH, '//div[@class="item"][1]/a').get_attribute('href')
print(f'电影详情页链接:{movie_link}')# 提取页面logo的图片地址(src属性)
logo_src = driver.find_element(By.XPATH, '//img[@alt="豆瓣电影"]').get_attribute('src')
print(f'豆瓣电影logo地址:{logo_src}')# 模拟输入后提取输入框值(value属性)
driver.get('https://www.baidu.com')
search_box = driver.find_element(By.ID, 'kw')
search_box.send_keys('Selenium数据提取')
input_value = search_box.get_attribute('value')
print(f'输入框当前值:{input_value}')driver.quit()

3. 提取整个页面源码(page_source 属性)

适用场景:需要批量解析页面、或结合 BeautifulSoup/lxml 二次解析时(Selenium 定位+解析库提取更高效)。

from selenium import webdriver
from bs4 import BeautifulSoupdriver = webdriver.Chrome()
driver.get('https://movie.douban.com/top250')# 获取整个页面的HTML源码
page_source = driver.page_source# 结合BeautifulSoup解析源码(批量提取数据)
soup = BeautifulSoup(page_source, 'lxml')
movies = soup.find_all('div', class_='item')[:3]
for movie in movies:title = movie.find('span', class_='title').textprint(f'电影名称:{title}')driver.quit()

三、进阶数据提取(处理动态/特殊数据)

1. 执行 JS 提取动态加载数据

适用场景:提取隐藏元素、滚动加载的数据、JS 渲染的动态内容(如页面高度、滚动位置、隐藏文本)。

from selenium import webdriverdriver = webdriver.Chrome()
driver.get('https://www.taobao.com')# 1. 提取页面总高度(JS动态计算)
page_height = driver.execute_script('return document.body.scrollHeight')
print(f'页面总高度:{page_height}px')# 2. 滚动到页面底部,提取动态加载的商品(以淘宝为例)
driver.get('https://s.taobao.com/search?q=Python编程书籍')
# 执行JS滚动到页面底部
driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')# 提取滚动后加载的商品名称(动态数据)
goods_titles = driver.find_elements(By.CLASS_NAME, 'J_ClickStat')[:3]
for title in goods_titles:print(f'商品名称:{title.text}')# 3. 提取隐藏元素的文本(常规text获取不到时)
# hidden_text = driver.execute_script('return document.getElementById("hidden_id").innerText')driver.quit()

适用场景:爬取需要登录的网站时,提取登录后的 Cookie,后续请求可直接使用。

from selenium import webdriver
import requestsdriver = webdriver.Chrome()
# 访问需要登录的页面(此处以豆瓣为例,需手动登录一次)
driver.get('https://www.douban.com')
input('请手动登录豆瓣后按回车继续...')# 提取页面所有Cookie
cookies = driver.get_cookies()
print(f'提取到Cookie数量:{len(cookies)}')# 转换Cookie格式(适配requests库)
cookie_dict = {cookie['name']: cookie['value'] for cookie in cookies}# 用提取的Cookie请求豆瓣(无需再次登录)
session = requests.Session()
session.cookies.update(cookie_dict)
response = session.get('https://www.douban.com/people/me/')
print(f'请求状态码:{response.status_code}')  # 200表示免登录成功driver.quit()

3. 提取标签页/iframe 中的数据

适用场景:数据在新标签页、弹窗或 iframe 嵌套页面中(如12306、后台管理系统)。

from selenium import webdriver
from selenium.webdriver.common.by import By
import timedriver = webdriver.Chrome()
driver.get('https://www.baidu.com')# 场景1:提取新标签页数据
# 打开新标签页
driver.execute_script('window.open("https://movie.douban.com/top250")')
time.sleep(1)
# 切换到新标签页(句柄索引从0开始)
driver.switch_to.window(driver.window_handles[1])
# 提取新标签页的电影名称
title = driver.find_element(By.CLASS_NAME, 'title').text
print(f'新标签页电影名称:{title}')# 场景2:提取iframe中的数据(以B站登录iframe为例)
driver.get('https://passport.bilibili.com/login')
time.sleep(2)
# 切换到iframe(通过id/name/索引)
iframe = driver.find_element(By.ID, 'i_cecream')
driver.switch_to.frame(iframe)
# 提取iframe中的登录按钮文本
login_btn_text = driver.find_element(By.CLASS_NAME, 'btn-login').text
print(f'iframe中的登录按钮文本:{login_btn_text}')
# 切回主页面(必须!否则后续定位会失败)
driver.switch_to.default_content()driver.quit()

四、实战案例:提取动态加载的商品数据

以「京东商品列表」为例,完整演示「定位→提取→清洗→存储」全流程:

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
import time# 初始化浏览器(禁用图片提升速度)
options = 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(15)
driver.maximize_window()# 访问京东搜索页
driver.get('https://search.jd.com/Search?keyword=Python编程书籍&enc=utf8')# 存储提取的数据
goods_data = []
wait = WebDriverWait(driver, 10)# 滚动3次,加载更多商品
for _ in range(3):# 执行JS滚动到底部driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')# 等待商品元素加载完成wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'gl-item')))time.sleep(2)# 提取商品数据goods_list = driver.find_elements(By.CLASS_NAME, 'gl-item')for goods in goods_list:try:# 提取商品名称(文本)name = goods.find_element(By.CLASS_NAME, 'p-name').text.strip()# 提取商品价格(文本)price = goods.find_element(By.CLASS_NAME, 'p-price').text.strip()# 提取商品链接(属性)link = goods.find_element(By.TAG_NAME, 'a').get_attribute('href')goods_data.append({'商品名称': name,'价格': price,'链接': link})except Exception as e:# 跳过提取失败的商品,避免程序崩溃continue# 数据清洗:去重、去空值
df = pd.DataFrame(goods_data)
df = df.drop_duplicates(subset=['商品名称'])  # 按名称去重
df = df.dropna()  # 删除空值行# 存储数据到Excel
df.to_excel('京东Python书籍数据.xlsx', index=False)
print(f'共提取并清洗出 {len(df)} 条商品数据,已保存到Excel')driver.quit()

案例关键说明

  1. 显式等待:用 WebDriverWait 等待商品元素加载,避免「元素未加载就提取」导致的失败;
  2. 异常处理:部分商品可能缺失价格/名称,用 try-except 跳过,保证程序运行;
  3. 数据清洗:动态加载易出现重复数据,用 drop_duplicates 去重,提升数据质量;
  4. 性能优化:禁用图片加载,减少页面加载时间,提升提取效率。

五、避坑技巧(新手常踩的坑)

1. 提取的文本为空?

  • 原因1:元素还未加载完成 → 解决方案:用 WebDriverWait 显式等待,而非 time.sleep()
  • 原因2:文本在隐藏元素中 → 解决方案:执行 JS 提取 innerText,如:
    text = driver.execute_script('return arguments[0].innerText', element)
    
  • 原因3:定位错了元素 → 解决方案:检查定位符(XPath/ID/Class)是否正确,可通过浏览器开发者工具验证。

2. 提取属性返回 None?

  • 原因:属性名拼写错误(如把 href 写成 herf)→ 解决方案:在开发者工具中确认属性名;
  • 特殊情况:动态属性需等待 JS 赋值 → 解决方案:增加等待时间或执行 JS 提取。

3. 批量提取效率低?

  • 解决方案:
    1. 禁用图片/视频加载(减少页面加载时间);
    2. find_elements() 批量定位,而非循环定位单个元素;
    3. 结合解析库(BeautifulSoup):先用 Selenium 获取 page_source,再用解析库批量提取,效率更高。
http://www.jsqmd.com/news/482335/

相关文章:

  • 普通Java程序员如何快速上手性能调优?
  • LeetCode 50. Pow(x, n)
  • Unity平台跳跃游戏开发利器:Platformer Project 技术架构深度解析
  • 金三银四已到,Java就业压力为啥还没缓解?
  • JeecgBoot低代码 AI Skills 实战:自然语言驱动 BPM 流程自动生成
  • OpenClaw-龙虾智能体-新手入门必看,一文搞懂核心定义与应用场景
  • LeetCode-206:从数组反转到链表反转,一篇搞懂反转链表
  • IT界有哪些优秀的高并发解决方案?
  • 二次剩余
  • 手机秒变高清摄像头?这个工具用了就回不去了
  • 「JOI Open 2021」怪兽游戏题解
  • 词向量做句子相似度已经落伍?深度解析词移距离(WMD)为何能成为语义匹配新宠!
  • 三月十二
  • 十万个why:Nacos 服务注册为什么默认是临时实例?
  • MySQL 1045 登录失败,远程登录提示1045(本地登录正常)
  • 提示工程架构师深度钻研AI上下文工程长短期记忆机制设计的核心算法
  • AI 换脸软件 MagicMirror 下载安装教程全攻略:普通电脑也能轻松实现离线 AI 换脸
  • 【实证分析】上市公司债务融资成本数据-含代码(2006-2024年)
  • 线程池里的代码明明报错了,为什么控制台一行异常日志都不打?
  • 《Mastering Atari with Discrete World Models》随记
  • 11 张图总结下,微服务增量拉取
  • STM32入门(10)
  • 打开网站显示图片上传失败?错误怎么办|已解决
  • 校园网线是否可以通过两个路由器进行中转?
  • PHP 网站完整搬家避坑指南(新手必看,杜绝报错、断站)
  • Java 后端实现 token自动续期,这方案有点优雅!
  • AI 批量图片去水印工具 v1.0.0 - 豆包专属去水印
  • 分发:AI的终极护城河
  • LLM可观测性:AI系统缺失的环节
  • 面试官问:订单30分钟未支付,自动取消,该怎么实现?