在HTML页面中查找匹配特定URL模板的所有链接

1 投票
1 回答
2084 浏览
提问于 2025-04-18 10:48

假设我有一个基本的链接地址 http://example.com/Stuff/preview/v/{id}/fl/1/t/。在我解析的网页上,有很多不同的{id}的链接。我想找到所有符合这个模板的链接。

我可以用xpath来匹配这个模板的一部分,比如用 //a[contains(@href,preview/v],或者直接用正则表达式。但我在想,有没有更优雅的方法,能用xpath和正则表达式快速而准确地匹配整个模板。

谢谢。

补充一下。我在一个样本页面上测试了一下。在我的网络连接下,经过100次测试,平均耗时是0.467秒,而使用BeautifulSoup则是0.669秒。

另外,如果你有Scrapy的话,可以使用选择器

  data=get(url).text
  sel = Selector(text=data, type="html")
  a=sel.xpath('//a[re:test(@href,"/Stuff/preview/v/\d+/fl/1/t/")]//@href').extract()

这个的平均时间也是0.467秒

1 个回答

3

你不能在使用 lxmlxpath 表达式中使用正则表达式,因为 lxml 只支持 xpath 1.0,而 xpath 1.0 不支持正则表达式搜索

相反,你可以使用 iterlinks() 找到页面上的所有链接,遍历这些链接并检查它们的 href 属性值:

import re
import lxml.html

tree = lxml.html.fromstring(data)

pattern = re.compile("http://example.com/Stuff/preview/v/\d+/fl/1/t/")
for element, attribute, link, pos in tree.iterlinks():
    if not pattern.match(link):
        continue
    print link

另外一个选择是使用 BeautifulSoup 这个 HTML 解析器:

import re
from bs4 import BeautifulSoup

data = "your html"
soup = BeautifulSoup(data)

pattern = re.compile("http://example.com/Stuff/preview/v/\d+/fl/1/t/")
print soup.find_all('a', {'href': pattern})

为了让 BeautifulSoup 的解析速度更快,你可以 让它使用 lxml

soup = BeautifulSoup(data, "lxml")

此外,你还可以使用 SoupStrainer 类,这样你可以只解析网页的特定部分,而不是整个页面。

希望这些信息对你有帮助。

撰写回答