Beautifulsoup и Soupstrainer для получения ссылок не работают с hasattr, возвращая всегда true

Я использую Beautifulsoup4 и Soupstrainer с Python 3.3 для получения всех ссылок с веб-страницы. Ниже приведен важный фрагмент кода:

r = requests.get(adress, headers=headers)
for link in BeautifulSoup(r.text, parse_only=SoupStrainer('a')):
    if hasattr(link, 'href'):

Я проверил некоторые веб-страницы, и это работает очень хорошо, но сегодня при использовании

adress = 'http://www.goldentigercasino.de/'

Я понял, что hasattr(link, 'href') всегда возвращает TRUE, даже если такого поля 'href' нет, как в примере с goldentigercasino.de. Из-за этого у меня возникают проблемы с поздним использованием ссылки ['href'], потому что ее просто нет.

Я также попробовал обходной путь, как это:

test = requests.get('http://www.goldentigercasino.de/')
for link in BeautifulSoup(test.text, parse_only=SoupStrainer('a',{'href': not None})):

Это работает, как хотелось бы, за исключением того, что он также возвращает Doctype:

HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"

Что также вызывает проблемы по тем же причинам, что и выше.

Мой вопрос: почему hasattr всегда возвращает true и как я могу это исправить? И если нет возможности с hasattr, как я могу исправить мой обходной путь, что он не возвращает DOCTYPE?

Большое спасибо и лучшие пожелания!

1 ответ

Решение

hasattr() неправильный тест; он проверяет, есть ли a.href attribute, а BeautifulSoup динамически превращает атрибуты в поиски детей. Атрибуты HTML-тегов не переводятся в атрибуты Python.

Вместо этого используйте тестирование в стиле словаря; Вы перебираете все элементы, которые могут включать DocType экземпляр, поэтому я использую getattr() не ломаться на объектах, которые не имеют атрибутов:

if 'href' in getattr(link, 'attrs', {}):

Вы также можете проинструктировать SoupStrainer только соответствовать a теги с href атрибут с помощью href=True в качестве фильтра аргументов ключевых слов (not None просто значит True в любом случае):

for link in BeautifulSoup(test.text, parse_only=SoupStrainer('a', href=True)):

Это все еще включает объявление HTML конечно; искать просто a ссылки по теме:

soup = BeautifulSoup(test.text, parse_only=SoupStrainer('a', href=True))
for link in soup.find_all('a'):
    print link
Другие вопросы по тегам