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