Разве HTMLParser различает текст ссылки и другие данные? - PullRequest
1 голос
/ 23 февраля 2012

Скажем, у меня есть HTML-код, похожий на этот:

<a href="http://example.org/">Stuff I do want</a>
<p>Stuff I don't want</p>

Использование handle_data в HTMLParser не делает различий между текстом ссылки (что мне действительно нужно) (это даже правильный термин?) И тем, что мне не нужно. Есть ли в HTMLParser встроенный способ, чтобы handle_data возвращал только текст ссылки и ничего больше?

1 Ответ

2 голосов
/ 23 февраля 2012

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

...