说我有类似的HTML代码:
<a href="http://example.org/">Stuff I do want</a>
<p>Stuff I don't want</p>
使用HTMLParser的handle_data不区分链接文本(我想要的东西)(这是否是正确的术语?)和我不想要的东西。 HTMLParser是否有内置的方法让handle_data只返回链接文本而没有其他内容?
答案 0 :(得分:2)
基本上你也必须写一个handle_starttag()
方法。只需将您看到的每个标记保存为self.lasttag
或其他内容即可。然后,在handle_data()
方法中,只需检查self.lasttag
并查看它是否为'a'
(表示您看到的最后一个标记是HTML锚标记,因此您处于链接中)。
这样的事情(未经测试)应该有效:
from HTMLParser import HTMLParser
class MyHTMLParser(HTMLParser):
lasttag = None
def handle_starttag(self, tag, attr):
self.lasttag = tag.lower()
def handle_data(self, data):
if self.lasttag == "a" and data.strip():
print data
事实上,HTML允许在<a...> ... </a>
容器中包含其他标记。并且还可以存在包含文本但不是链接的锚点(没有href=
属性)。如果需要,可以处理这些情况。同样,此代码未经测试:
from HTMLParser import HTMLParser
class MyHTMLParser(HTMLParser):
inlink = False
data = []
def handle_starttag(self, tag, attr):
if tag.lower() == "a" and "href" in (k.lower() for k, v in attr):
self.inlink = True
self.data = []
def handle_endtag(self, tag):
if tag.lower() == "a":
self.inlink = False
print "".join(self.data)
def handle_data(self, data):
if self.inlink:
self.data.append(data)
HTMLParser就是你所谓的SAX风格的解析器,它会通知你经过的标签,但是你可以自己跟踪标签层次结构。你可以看到这里的第一版和第二版之间的区别有多复杂。
DOM样式的解析器更容易用于这些类型的任务,因为它们将整个文档读入内存并生成易于导航和搜索的树。 DOM风格的解析器倾向于使用更多内存并且比SAX风格的解析器慢,但现在这比十年前要重要得多。