По сути, вы должны написать метод 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, но сейчас это гораздо менее важно, чем это было десять лет назад.