【问题标题】:Finding all links matching specific URL template in an HTML page在 HTML 页面中查找与特定 URL 模板匹配的所有链接
【发布时间】:2014-08-13 21:30:43
【问题描述】:

假设我有以下基本网址http://example.com/Stuff/preview/v/{id}/fl/1/t/。正在解析的页面上有许多具有不同 {id} 的 url。我想在 HTML 页面中找到与此模板匹配的所有链接。

我可以使用 xpath 仅匹配模板的一部分//a[contains(@href,preview/v] 或仅使用正则表达式,但我想知道是否有人知道使用 xpath 和正则表达式匹配整个模板的更优雅的方法,因此它快速且匹配绝对正确。

谢谢。

编辑。我在示例页面上对其进行了计时。通过我的互联网连接和 100 次试验,迭代平均需要 0.467 秒,BeautifulSoup 需要 0.669 秒。

另外,如果你有 Scrapy,它可以使用 Selectors

  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

【问题讨论】:

    标签: python regex xpath html-parsing lxml


    【解决方案1】:

    您不能在使用lxmlxpath 表达式中使用正则表达式,因为lxml supports xpath 1.0xpath 1.0 doesn't support regular expression search

    相反,您可以使用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 解析更快,您可以let it use lxml

    soup = BeautifulSoup(data, "lxml")
    

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

    希望对您有所帮助。

    【讨论】:

    • 这行得通,但我更倾向于使用 xpath,因为 BeautifulSoup 相当慢,而且我正在做很多次匹配。迭代可能会更快,但还没有测试过。
    • @Artii 请查看更新。不过,我仍在努力寻找答案。
    • 我在一个示例页面上对其进行了计时。使用我的互联网连接和 100 次试验,迭代平均需要 0.467 秒,BeautifulSoup 需要 0.669 秒。
    • @zx81 谢谢,我看到你喜欢正则表达式和非正则表达式解决方案:)
    • 我非常喜欢正则表达式,而且我几乎从不为正则表达式问题提供非正则表达式的解决方案......而且我知道它通常不是最好的工具......所以当有人展示其他方式时我喜欢它! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-29
    • 2023-03-30
    相关资源
    最近更新 更多