Я строю веб-сканер в 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>
.
Есть идеи?
Вы можете использовать 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.