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

标签 python parsing hyperlink web-crawler html-parsing

我一直在使用 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 LinkExtractor(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

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

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

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

相关文章:

python yaml.dump 其他YAML格式的格式列表

Python:抑制进入命令行的错误?

c - Yacc问题: Make Data available in next Non Terminal

c# - 如何使用相对文件路径和 PDFsharp 创建 PDF 文件链接?

google-chrome - Chrome 浏览器可以打开本地链接吗?

c# - 将 RSpec 与其他语言(如 Python 或 C#)集成的好方法是什么?

ruby - 什么是 Ruby 的快速 XML 解析器?

c++ - 如何清除包含 C 函数声明的字符串中的注释和中间空格?

html - 如何只使图像可点击而不是整个 div?

python - 在 pandas 中创建列配对