如何使用Python HTML Parser提取特定链接

时间:2012-03-14 01:37:09

标签: python parsing hyperlink web-crawler html-parsing

我一直在使用HTMLParser类在Python中使用基本的Web爬虫。我使用修改后的handle_starttag方法获取我的链接,如下所示:

def handle_starttag(self, tag, attrs):
    if tag == 'a':
        for (key, value) in attrs:
            if key == 'href':
                newUrl = urljoin(self.baseUrl, value)
                self.links = self.links + [newUrl]

当我想在页面上找到每个链接时,这非常有用。现在我只想获取某些链接。

我如何仅提取<td class="title"></td>标记之间的链接,如下所示:

<td class="title"><a href="http://www.stackoverflow.com">StackOverflow</a><span class="comhead"> (arstechnica.com) </span></td>

1 个答案:

答案 0 :(得分:7)

HTMLParser是一种SAX风格或流式解析器,这意味着您可以在解析文档时获取部分文档,但不能同时获取整个文档。解析器调用您提供的方法来处理标记和其他类型的数据。您可能感兴趣的任何上下文,例如哪些标记位于其他标记内,您必须从您看到的标记中收集。

例如,如果您看到<td>标记,则表示您处于表格单元格中,并且可以为该效果设置标记。当您看到</td>时,您知道已离开表格单元格并可以清除该标记。要获取表格单元格中的链接,那么,如果您看到<a>并且您知道自己位于表格单元格中(因为您设置了该标记),则可以获取标记href的值如果它有一个属性。

from HTMLParser import HTMLParser

class LinkExctractor(HTMLParser):

    def reset(self):
        HTMLParser.reset(self)
        self.extracting = False
        self.links      = []

    def handle_startag(self, tag, attrs):
        if tag == "td" or tag == "a":
            attrs = dict(attrs)   # save us from iterating over the attrs
        if tag == "td" and attrs.get("class", "") == "title":
            self.extracting = True
        elif tag == "a" and "href" in attrs and self.extracting:
            self.links.append(attrs["href"])

    def handle_endtag(self, tag):
        if tag == "td":
            self.extracting = False

这很快就会变得很痛苦,因为您需要越来越多的上下文来从文档中获取您想要的内容,这就是人们推荐lxmlBeautifulSoup的原因。这些是DOM样式的解析器,可以为您跟踪文档层次结构,并提供各种友好的方式来导航它,例如DOM API,XPath和/或CSS选择器。

顺便说一下,我最近回答了一个类似的问题here