本文详解如何用 Selenium 高效获取页面中全部 H2 标签(尤其是嵌套在 H2 中的 <a> 元素)的 href 属性和可见文本,替代低效的单元素定位方式,实现结构化、可批量处理的演讲标题与 PDF 链接采集。
本文详解如何用 selenium 高效获取页面中全部 h2 标签(尤其是嵌套在 h2 中的 `` 元素)的 `href` 属性和可见文本,替代低效的单元素定位方式,实现结构化、可批量处理的演讲标题与 pdf 链接采集。
在网页自动化数据采集任务中,常需批量提取具有统一结构的标题类元素——例如巴西总统档案馆网站中,每个演讲条目均以 <h2 class="tileHeadline"> 包裹一个 <a> 标签,该标签同时承载标题文本与 PDF 下载链接。此时若沿用 visibility_of_element_located() 等单元素等待条件(如原代码中仅获取首个 .tileHeadline),将无法覆盖页面中多达 20 个同类项,导致数据严重缺失。
✅ 正确做法是:放弃单元素定位,改用 find_elements() 批量获取所有匹配节点。针对目标页面 HTML 结构(<h2 class="tileHeadline"><a href="https://www.php.cn/link/263b1243ca2dbeb358777ceabc4a2e4c">标题文本</a></h2>),推荐使用 CSS 选择器 "h2 a" ——它精准定位所有位于 <h2> 内部的 <a> 标签,天然规避了父元素文本提取不完整、子元素干扰等问题。
以下是生产就绪的优化实现:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
options = webdriver.ChromeOptions()
options.add_argument("--disable-notifications")
options.add_experimental_option("excludeSwitches", ["enable-automation", "enable-logging"])
driver = webdriver.Chrome(options=options)
wait = WebDriverWait(driver, 10)
try:
url = "http://www.biblioteca.presidencia.gov.br/presidencia/ex-presidentes/jose-sarney/discursos/1985?b_start:int=0"
driver.get(url)
# 等待至少一个 h2 a 元素可见,确保 DOM 加载完成
wait.until(EC.visibility_of_element_located(("css selector", "h2 a")))
# ✅ 批量获取所有匹配的 <a> 元素(位于 h2 内)
links = driver.find_elements("css selector", "h2 a")
# 结构化存储结果
speeches = []
for idx, link in enumerate(links, 1):
href = link.get_attribute("href") or "[无链接]"
text = link.text.strip() if link.text else "[无标题]"
speeches.append({
"index": idx,
"title": text,
"pdf_url": href
})
print(f"[{idx}] 标题: {text}")
print(f" PDF: {href}\n")
print(f"✅ 共采集 {len(speeches)} 条总统演讲记录。")
finally:
driver.quit()⚠️ 关键注意事项:
- 勿混淆 find_element 与 find_elements:前者返回单个 WebElement(遇多匹配仅取首),后者返回 list[WebElement],是批量提取的唯一可靠方式;
- 避免直接操作 <h2> 元素:本例中 <h2> 本身不含 href,其子 <a> 才是真实链接载体。若错误地对 h2 调用 .get_attribute("href") 将返回 None;
-
增强健壮性建议:实际项目中应增加空值校验、超时重试及异常日志(如 NoSuchElementException),例如:
href = link.get_attribute("href") if not href: href = link.get_attribute("data-href") or "[链接缺失]" - 性能与反爬提示:该站点无强动态渲染,但若需翻页采集,建议复用同一 driver 实例并配合 time.sleep(1) 或显式等待,避免高频请求触发风控。
通过上述方法,你不仅能完整捕获页面中全部 H2 关联链接,还可轻松扩展为 JSON 导出、CSV 存储或数据库写入,真正实现从“能跑通”到“可交付”的工程化跃迁。


















