Webcrawler - Проверьте, находится ли тег <a> с href в теге li с помощью Beautiful soup?

1

Я строю веб-сканер в Python, используя красивый суп для сканирования Википедии. Проблема в том, что в Википедии есть много мусорных ссылок, на которые я не хочу смотреть.

Например:

целевые ссылки с # перед целевой частью

<li class="toclevel-1 tocsection-1">
  <a href="#Overview">
    <span class="tocnumber">1</span>
    <span class="toctext">Overview</span>
  </a>
</li>

страницы обсуждения

<li class="nv-talk">
  <a href="/wiki/Template_talk:Data_structures" title="Template talk:Data structures">
    <span title="Discuss this template" style=";;background:none transparent;border:none;;">t</span>
  </a>
</li>

страницы шаблона

<li class="nv-view">
  <a href="/wiki/Template:Data_structures" title="Template:Data structures">
    <span title="View this template" style=";;background:none transparent;border:none;;">v</span>
  </a>
</li>

и так далее...

Теперь я храню все ссылки, которые я уже посетил, в словаре, поэтому я не посещаю их дважды, поэтому я могу избежать целевых ссылок, просто проверив, находится ли ссылка на символ # в таблице.

Однако, у меня немного больше проблем с разговорами, шаблонами и другими подобными страницами.

Что-то уникальное в них заключается в том, что они всегда появляются в <li> с некоторым атрибутом класса ("nv-talk", "nv-view" т.д.), Однако мой сканер полагается на просмотр тегов <a>, поэтому я не имеют доступа к атрибутам <li> в котором он содержится.

Кроме того, не все ссылки на странице содержатся в <li>, поэтому я не могу просто искать теги <li>.

Есть идеи?

Теги:
web-crawler
beautifulsoup

1 ответ

2
Лучший ответ

Вы можете использовать find_parents() для BeautifulSoup. Это скажет вам, является ли конкретный тег внутри другого тега с указанными атрибутами. В этом случае мы ищем тег привязки в другом теге с атрибутом класса nv-talk или nv-view.

Демо-версия:

html = '''<li class="nv-talk"><a href="/wiki/Template_talk:Data_structures" title="Template talk:Data structures"><span title="Discuss this    template" style=";;background:none    transparent;border:none;;">t</span></a></li>    '''
soup = BeautifulSoup(html)
a_tag = soup.find('a')
a_tag.find_parents(attrs={'class':'nv-talk'})

который дает вам:

[<li class="nv-talk"><a href="/wiki/Template_talk:Data_structures" title="Template talk:Data    structures"><span style=";;background:none transparent;border:none;;"    title="Discuss this template">t</span></a></li>]

Для каждого тега привязки в списке ваших URL-адресов вы можете проверить, возвращает ли find_parents() пустой список. Если да, это означает, что эта ссылка не относится к странице "Разговор" или "Обсудить" и, следовательно, безопасна для вашего сканирования.

Другим способом решения этой проблемы было бы узнать, начинается ли атрибут href тега привязки с 'http' или 'https'. Но я не совсем уверен, соответствует ли это логике вашего кода. Я имею в виду, что привязанные теги с атрибутами href, начинающиеся с # являются ссылками на разделы на одной странице. Если вам нужно их игнорировать, вы можете искать якорные теги, которые не начинаются с # но вместо этого начинаются с http или https. Это то, что я имею в виду:

html = '''
<li class="toclevel-1 tocsection-1"><a href="#Overview"><span class="tocnumber">1</span> <span class="toctext">Overview</span></a></li>
<li class="toclevel-1 tocsection-1"><a href="http://www.google.com"><span class="tocnumber">1</span> <span class="toctext">Overview</span></a></li>
<li class="toclevel-1 tocsection-1"><a href="#Overview"><span class="tocnumber">1</span> <span class="toctext">Overview</span></a></li>
'''
soup = BeautifulSoup(html)
a_tag = soup.find('a', attrs={'href': re.compile(r'^http.*')})

Это дает вам только ссылку, которая начинается с http.

  • 0
    Похоже, это может сработать. Что вы имели в виду, используя http против https для решения проблемы? (Я немного новичок в разборе HTML)
  • 0
    @Kittenmittons Проверьте мой обновленный ответ
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню