【发布时间】:2013-05-31 12:24:28
【问题描述】:
我正在尝试构建一个快速的网络爬虫,因此,我需要一种有效的方法来定位页面上的所有链接。像 lxml 这样的快速 XML/HTML 解析器和使用正则表达式匹配之间的性能比较是什么?
【问题讨论】:
标签: python regex html-parsing web-crawler lxml
我正在尝试构建一个快速的网络爬虫,因此,我需要一种有效的方法来定位页面上的所有链接。像 lxml 这样的快速 XML/HTML 解析器和使用正则表达式匹配之间的性能比较是什么?
【问题讨论】:
标签: python regex html-parsing web-crawler lxml
这里的问题不在于 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。
【讨论】:
</body> 标记、未关闭的引号等。浏览器通常会按照作者的意图解释损坏的 HTML,因此它们永远不会修复错误,但严格的 HTML 解析器无法修复。
您可以使用 pyquery,这是一个为您提供 jquery 函数的 python 库。
【讨论】: