【问题标题】:Finding links fast: regex vs. lxml快速查找链接:正则表达式与 lxml
【发布时间】:2013-05-31 12:24:28
【问题描述】:

我正在尝试构建一个快速的网络爬虫,因此,我需要一种有效的方法来定位页面上的所有链接。像 lxml 这样的快速 XML/HTML 解析器和使用正则表达式匹配之间的性能比较是什么?

【问题讨论】:

    标签: python regex html-parsing web-crawler lxml


    【解决方案1】:

    这里的问题不在于 regex 与 lxml。正则表达式不是解决方案。您将如何限制链接来源的元素?一个更真实的例子是格式错误的 HTML。您将如何从该链接中提取href 属性的内容?

    <A href = /text" data-href='foo>' >Test</a>
    

    lxml 可以很好地解析它,就像 Chrome 一样,但祝你好运让正则表达式工作。如果你对实际的速度差异感到好奇,这里是我做的一个快速测试。

    设置:

    import re
    import lxml.html
    
    def test_lxml(html):
        root = lxml.html.fromstring(html)
        #root.make_links_absolute('http://stackoverflow.com/')
    
        for href in root.xpath('//a/@href'):
            yield href
    
    LINK_REGEX = re.compile(r'href="(.*?)"')
    
    def test_regex(html):
        for href in LINK_REGEX.finditer(html):
            yield href.group(1)
    

    测试 HTML:

    html = requests.get('http://stackoverflow.com/questions?pagesize=50').text
    

    结果:

    In [22]: %timeit list(test_lxml(html))
    100 loops, best of 3: 9.05 ms per loop
    
    In [23]: %timeit list(test_regex(html))
    1000 loops, best of 3: 582 us per loop
    
    In [24]: len(list(test_lxml(html)))
    Out[24]: 412
    
    In [25]: len(list(test_regex(html)))
    Out[25]: 416
    

    作为比较,以下是 Chrome 挑选出的链接数量:

    > document.querySelectorAll('a[href]').length
    413
    

    另外,为了记录,Scrapy 是目前最好的网络抓取框架之一,它使用 lxml 来解析 HTML。

    【讨论】:

    • 嗯,有时更多的是关于内置或非内置功能。您提供的 html 示例 (Test) 不太现实(或者我想这样想......)。非常感谢你展示速度测试。
    • @erm3nda:我遇到过多次损坏的 HTML。多个关闭 &lt;/body&gt; 标记、未关闭的引号等。浏览器通常会按照作者的意图解释损坏的 HTML,因此它们永远不会修复错误,但严格的 HTML 解析器无法修复。
    【解决方案2】:

    您可以使用 pyquery,这是一个为您提供 jquery 函数的 python 库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-11
      • 2015-01-13
      • 1970-01-01
      • 1970-01-01
      • 2013-05-13
      • 1970-01-01
      • 2013-06-23
      • 1970-01-01
      相关资源
      最近更新 更多