快速解析链接在python中的页面

时间:2011-06-02 20:26:30

标签: python parsing beautifulsoup

我需要解析大量页面(比如1000)并用微小链接替换链接。

现在我正在使用正则表达式

href_link_re = re.compile(r"<a[^>]+?href\s*=\s*(\"|')(.*?)\1[^>]*>", re.S)

但速度不够快。

到目前为止我在想

  1. 状态机(这取决于我编写聪明代码的能力)
  2. 使用html解析器
  3. 你能建议更快吗?

    修改 您会认为html解析器比正则表达式更快,但在我的测试中它不是:

    from BeautifulSoup import BeautifulSoup, SoupStrainer
    
    import re
    import time
    
    __author__ = 'misha'
    
    regex = re.compile(r"<a[^>]+?href\s*=\s*(\"|')(.*?)\1[^>]*>", re.S)
    
    def test(text, fn, desc):
    
        start = time.time()
        total  = 0
        links = [];
        for i in range(0, 10):
            links = fn(text)
            total += len(links)
        end = time.time()
        print(desc % (end-start, total))
       # print(links)
    
    def parseRegex(text):
        links  = set([])
        for link in regex.findall(text):
            links.add(link[1])
        return links
    
    def parseSoup(text):
        links = set([])
        for link in BeautifulSoup(text, parseOnlyThese=SoupStrainer('a')):
            if link.has_key('href'):
                links.add(link['href'])
    
        return links
    
    
    
    if __name__ == '__main__':
        f = open('/Users/misha/test')
        text = ''.join(f.readlines())
        f.close()
    
        test(text, parseRegex, "regex time taken: %s found links: %s" )
        test(text, parseSoup, "soup time taken: %s found links: %s" )
    

    输出:

    regex time taken: 0.00451803207397 found links: 2450
    soup time taken: 0.791836977005 found links: 2450
    

    (测试是维基百科首页的转储)

    我必须严厉地使用汤。 我做错了什么?

2 个答案:

答案 0 :(得分:2)

LXML可能是您完成此任务的最佳选择。见Beautiful Soup vs LXML Performance。在LXML中解析链接很容易,而且速度很快。

root = lxml.html.fromstring(s)
anchors = root.cssselect("a")
links = [a.get("href") for a in anchors]

答案 1 :(得分:1)

解析使用regexp的非常糟糕的想法,因为速度和正则表达式指数时间问题。 相反,您可以将解析器用于xhtml。最好的是LXML。 或者,您可以使用LL,LR解析器专门为此目的编写解析器。例如:ANTLRYAPPSYACCPYBISON