You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python获取符合指定href格式的所有<a>标签?

解决XPath提取特定格式链接的问题

嘿,我看到你在尝试用XPath提取特定格式的链接时遇到了问题——问题出在你误用了contains()函数,它不支持正则表达式匹配,只是简单检查字符串是否包含某个子串。要实现正则匹配,你需要用XPath 2.0+的matches()方法,或者换一种更兼容的方式:先用XPath提取所有链接,再用Python的正则库过滤。

问题分析

你的目标链接格式是/static_word/带横杠的随机字符串/随机数字,而你写的XPath表达式//a[contains(@href,'^/static_word/[A-Za-z0-9_-]/[0-9]$')]有两个核心问题:

  1. contains()不识别正则语法,它会把整个正则字符串当作普通子串去匹配,自然找不到符合条件的链接
  2. 你的正则本身也有小瑕疵:[A-Za-z0-9_-]和[0-9]都只匹配单个字符,而你需要匹配的是一段字符串/数字,应该加上+表示匹配至少一个字符

方案一:使用XPath的matches()函数(推荐,更简洁)

lxml库支持XPath 2.0的matches()方法,可以直接在XPath中写正则匹配:

from lxml import html
import ssl
import requests

ssl._create_default_https_context = ssl._create_unverified_context
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
myRequest = requests.get("https://somesecureurl.com/", headers=headers)
webpage = html.fromstring(myRequest.content)

# 修正后的XPath:用matches实现正则匹配,调整正则语法匹配多字符
theLinks = webpage.xpath("//a[matches(@href, '^/static_word/[A-Za-z0-9_-]+/[0-9]+$')]/@href")
print(theLinks)

关键改动说明:

  • 用matches(@href, '正则表达式')替代contains(),实现真正的正则匹配
  • 正则中把[A-Za-z0-9_-]改成[A-Za-z0-9_-]+,匹配至少一个字母/数字/下划线/横杠组成的字符串
  • 把[0-9]$改成[0-9]+$,匹配至少一个数字结尾的路径
  • 最后加上/@href直接提取链接字符串,而不是返回a标签元素

方案二:提取所有链接后用Python正则过滤(兼容性更好)

如果你的lxml环境不支持XPath 2.0的matches()函数,或者你想更灵活地处理链接,可以先用XPath提取所有链接,再用Python的re库过滤:

from lxml import html
import ssl
import requests
import re

ssl._create_default_https_context = ssl._create_unverified_context
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
myRequest = requests.get("https://somesecureurl.com/", headers=headers)
webpage = html.fromstring(myRequest.content)

# 先提取所有a标签的href属性
all_links = webpage.xpath("//a/@href")
# 定义匹配目标格式的正则模式
link_pattern = re.compile(r'^/static_word/[A-Za-z0-9_-]+/[0-9]+$')
# 过滤出符合条件的链接
filtered_links = [link for link in all_links if link_pattern.match(link)]
print(filtered_links)

额外注意事项:

  • 如果目标链接后面可能带有查询参数(比如/static_word/abc-def/123?foo=bar),可以把正则末尾的$去掉,改成^/static_word/[A-Za-z0-9_-]+/[0-9]+
  • 可以先打印all_links看看实际返回的链接格式,再微调正则表达式,确保匹配准确

内容的提问来源于stack exchange,提问作者andres.gtz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:37:50