在HTML页面中查找匹配特定URL模板的所有链接
假设我有一个基本的链接地址 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
你不能在使用 lxml
的 xpath
表达式中使用正则表达式,因为 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
类,这样你可以只解析网页的特定部分,而不是整个页面。
希望这些信息对你有帮助。