我一直在使用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>
答案 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
这很快就会变得很痛苦,因为您需要越来越多的上下文来从文档中获取您想要的内容,这就是人们推荐lxml
和BeautifulSoup
的原因。这些是DOM样式的解析器,可以为您跟踪文档层次结构,并提供各种友好的方式来导航它,例如DOM API,XPath和/或CSS选择器。
顺便说一下,我最近回答了一个类似的问题here。