我一直在使用HTMLParser类在Python中开发基本的网络爬虫。我使用修改后的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>

最佳答案

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回答了类似的问题。

关于python - 如何使用Python HTML解析器提取特定链接,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9694769/

10-11 23:09
查看更多