xpath只能解析静态html源码,无法提取javascript动态生成或隐藏在onclick/base64等属性中的链接;若源码无

为什么直接用 //table//a/@href 常常提取不到隐藏链接?
因为“隐藏”通常不是指 CSS 的 display: none 或 visibility: hidden,而是链接被包裹在 span、div 甚至文本节点里,或者 href 是通过 JavaScript 动态写入的。XPath 只能解析静态 HTML DOM,对 JS 渲染后的内容无能为力。如果你用 requests + lxml 直接解析响应体却没拿到链接,大概率是页面用了前端框架(如 Vue/React)或内联脚本拼接 href。
如何确认链接是否真在 HTML 源码中?
打开浏览器开发者工具 → 右键网页 →「查看页面源代码」(不是「检查元素」),然后搜索 @#@#@#@#@#@#@#@#@#@0),用 //table//a[@href]/@href 即可捕获
onclick 属性里(如 onclick="location.href='xxx'"),XPath 可提取该属性值://table//td[contains(@onclick,'href')]/@onclick,再用正则解析href="javascript:void(0)" data-url="base64:xxx"),需额外处理 @data-url 属性用 lxml 提取时怎么避免漏掉“伪链接”?
常见陷阱是匹配到空 href、javascript:void(0)、# 等无效值。必须加过滤逻辑:
from lxml import html
import re
<p>tree = html.fromstring(html_content)
links = tree.xpath('//table//a[@href]/@href')
clean_links = [
link.strip()
for link in links
if link.strip()
and not re.match(r'^\s*(#|javascript:|void(0)|mailto:)', link.strip())
]
</p>
注意:XPath 中的 @href 不会自动补全相对路径,你得用 urllib.parse.urljoin(base_url, link) 手动处理。
什么时候必须放弃 XPath 改用 Selenium?
当你发现目标链接只在点击某按钮、滚动到某区域、或等待几秒后才出现时,说明它依赖用户交互或异步加载。XPath 再精准也查不到尚未插入 DOM 的节点。
- 用 Selenium 启动浏览器后,先
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")触发懒加载 - 用
WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, "//table//a")))等待元素就绪 - 再执行
driver.find_elements(By.XPATH, "//table//a")并取.get_attribute("href")—— 这才是 JS 渲染后的最终值
真实项目里,80% 的“隐藏链接”问题其实出在没分清静态 HTML 和动态 DOM 的边界;盲目调 XPath 表达式不如先看一眼原始 HTML 源码。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











