2013-06-04 61 views
1

我試圖建立一個快速的網絡爬蟲,因此,我需要一種有效的方法來查找頁面上的所有鏈接。快速XML/HTML解析器(如lxml)和使用正則表達式匹配之間的性能比較是什麼?查找快速鏈接:正則表達式與lxml

回答

6

這裏的問題不在於regex vs 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 

爲了便於比較,這裏有多少鏈接鉻挑選出:

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

而且,只是備案,Scrapy是最好的網頁抓取框架之一,在那裏,它使用LXML來解析HTML。

+0

那麼,有時更多的是內置或不是功能。你給的html樣本(Test)並不那麼現實(或者我想這是...)。非常感謝您展示速度測試。 – erm3nda

+0

@ erm3nda:我遇到了多次錯誤的HTML。多重結束''標記,未封閉的引號等。瀏覽器通常將破碎的HTML解釋爲作者所期望的,以便他們永遠不會修正他們的錯誤,但嚴格的HTML解析器無法做到。 – Blender

-2

你可以使用pyquery,這是一個爲jquery帶來功能的python庫。