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