
本文详解如何用 Selenium 高效获取页面内全部 标签(尤其是嵌套 的结构)的文本内容和 href 属性,避免仅取首个元素的常见误区,提供可直接运行的健壮代码及关键注意事项。
本文详解如何用 selenium 高效获取页面内全部 `
` 标签(尤其是嵌套 `` 的结构)的文本内容和 `href` 属性,避免仅取首个元素的常见误区,提供可直接运行的健壮代码及关键注意事项。在网页结构化数据抓取任务中,常需批量提取具有语义层级的标题信息——例如巴西总统档案馆(biblioteca.presidencia.gov.br)中每个演讲条目均以
包裹一个 标签,其内含演讲标题(.text)和 PDF 下载链接(href 属性)。此时,若沿用 find_element() 或 visibility_of_element_located() 等单元素定位方法,将仅返回首个匹配项,无法满足“一页 20+ 条目”的实际需求。✅ 正确做法:使用 find_elements() + 合理选择器
Selenium 并不内置类似 BeautifulSoup 的 .find_all() 方法,但其 find_elements()(注意是复数形式)完全等价于“批量查找”,是处理多元素的标准接口。关键在于:
-
必须使用 find_elements()(返回 list[WebElement]),而非 find_element()(仅返回第一个 WebElement);
-
选择器需精准匹配目标结构:该网站中 H2 内容实际位于
标题文本
,因此直接定位 h2 a(CSS 选择器)比定位 h2 更高效、更安全——既确保元素可见可交互,又天然绑定文本与链接。
以下为生产环境推荐代码(适配 Selenium 4.15+,含显式等待与异常防护):
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
from selenium.webdriver.chrome.options import Options
# 配置无头模式与反检测选项(提升稳定性)
options = Options()
options.add_argument("--headless")
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options)
wait = WebDriverWait(driver, 15) # 延长等待时间,适应慢速政府网站
try:
url = "http://www.biblioteca.presidencia.gov.br/presidencia/ex-presidentes/jose-sarney/discursos/1985?b_start:int=0"
driver.get(url)
# 显式等待:确保至少一个 .tileHeadline 出现在 DOM 中(作为页面加载完成信号)
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".tileHeadline")))
# ✅ 批量定位所有 h2 内的 a 标签(即每个演讲条目的链接节点)
speech_links = driver.find_elements(By.CSS_SELECTOR, "h2.tileHeadline a")
# 提取并结构化数据
results = []
for idx, elem in enumerate(speech_links, 1):
href = elem.get_attribute("href")
title = elem.text.strip()
if href and title: # 过滤空值,增强鲁棒性
results.append({"index": idx, "title": title, "url": href})
# 输出示例(可替换为存入 CSV/JSON)
for item in results[:5]: # 仅打印前5条作验证
print(f"[{item['index']}] {item['title']}")
print(f" → URL: {item['url']}\n")
print(f"✅ 共提取 {len(results)} 条演讲记录")
finally:
driver.quit() # 必须显式关闭,防止残留进程
⚠️ 关键注意事项
-
勿混淆 element 与 elements:find_element() 永远只返回一个对象,用于 for 循环会报 TypeError;只有 find_elements() 返回列表,方可遍历。
-
CSS 选择器优先于 XPath(本场景):h2.tileHeadline a 比 //h2[@class='tileHeadline']/a 更简洁、性能更好,且避免 XPath 中引号嵌套的转义问题。
-
显式等待应基于 presence_of_element_located 而非 visibility_of_element_located:后者要求元素不仅存在还需可见(可能因滚动位置失败),而前者仅检查 DOM 加载,更适合列表型数据初始化。
-
始终校验属性值:get_attribute("href") 在 无 href 时返回 None,需判空;text 可能含首尾空白,建议 .strip()。
-
政府网站常限速或反爬:添加 --headless、禁用自动化标识、合理设置 WebDriverWait 超时(如 15 秒),可显著降低被拦截风险。
通过上述方法,您即可稳定、批量地将非结构化网页标题列表转化为结构化数据字典,为后续存储、分析或批量下载 PDF 提供坚实基础。
✅ 正确做法:使用 find_elements() + 合理选择器
Selenium 并不内置类似 BeautifulSoup 的 .find_all() 方法,但其 find_elements()(注意是复数形式)完全等价于“批量查找”,是处理多元素的标准接口。关键在于:
- 必须使用 find_elements()(返回 list[WebElement]),而非 find_element()(仅返回第一个 WebElement);
-
选择器需精准匹配目标结构:该网站中 H2 内容实际位于
标题文本
,因此直接定位 h2 a(CSS 选择器)比定位 h2 更高效、更安全——既确保元素可见可交互,又天然绑定文本与链接。
以下为生产环境推荐代码(适配 Selenium 4.15+,含显式等待与异常防护):
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
from selenium.webdriver.chrome.options import Options
# 配置无头模式与反检测选项(提升稳定性)
options = Options()
options.add_argument("--headless")
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options)
wait = WebDriverWait(driver, 15) # 延长等待时间,适应慢速政府网站
try:
url = "http://www.biblioteca.presidencia.gov.br/presidencia/ex-presidentes/jose-sarney/discursos/1985?b_start:int=0"
driver.get(url)
# 显式等待:确保至少一个 .tileHeadline 出现在 DOM 中(作为页面加载完成信号)
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".tileHeadline")))
# ✅ 批量定位所有 h2 内的 a 标签(即每个演讲条目的链接节点)
speech_links = driver.find_elements(By.CSS_SELECTOR, "h2.tileHeadline a")
# 提取并结构化数据
results = []
for idx, elem in enumerate(speech_links, 1):
href = elem.get_attribute("href")
title = elem.text.strip()
if href and title: # 过滤空值,增强鲁棒性
results.append({"index": idx, "title": title, "url": href})
# 输出示例(可替换为存入 CSV/JSON)
for item in results[:5]: # 仅打印前5条作验证
print(f"[{item['index']}] {item['title']}")
print(f" → URL: {item['url']}\n")
print(f"✅ 共提取 {len(results)} 条演讲记录")
finally:
driver.quit() # 必须显式关闭,防止残留进程
⚠️ 关键注意事项
- 勿混淆 element 与 elements:find_element() 永远只返回一个对象,用于 for 循环会报 TypeError;只有 find_elements() 返回列表,方可遍历。
- CSS 选择器优先于 XPath(本场景):h2.tileHeadline a 比 //h2[@class='tileHeadline']/a 更简洁、性能更好,且避免 XPath 中引号嵌套的转义问题。
- 显式等待应基于 presence_of_element_located 而非 visibility_of_element_located:后者要求元素不仅存在还需可见(可能因滚动位置失败),而前者仅检查 DOM 加载,更适合列表型数据初始化。
- 始终校验属性值:get_attribute("href") 在 无 href 时返回 None,需判空;text 可能含首尾空白,建议 .strip()。
- 政府网站常限速或反爬:添加 --headless、禁用自动化标识、合理设置 WebDriverWait 超时(如 15 秒),可显著降低被拦截风险。
通过上述方法,您即可稳定、批量地将非结构化网页标题列表转化为结构化数据字典,为后续存储、分析或批量下载 PDF 提供坚实基础。











