Python получаем все ссылки со страницы

Извлечение всех ссылок web-сайта с помощью Python

Одна из задач, которая стояла в рамках проекта, нацеленного на исследование мер поисковой оптимизации (SEO, search engine optimization) информационных ресурсов дочерних структур организации, предполагала поиск всех ссылок и выявление среди них так называемых «мертвых (битых) ссылок», отсылающих на несуществующий сайт, страницу, файл, что в свою очередь понижает рейтинг информационного ресурса.

В этом посте я хочу поделиться одним из способов извлечения всех ссылок сайта (внутренних и внешних), который поможет при решении подобных задач.

Посмотрим, как можно создать инструмент извлечения ссылок в Python, используя пакет requests и библиотеку BeautifulSoup. Итак,

Импортируем необходимые модули:

import requests from urllib.parse import urlparse, urljoin from bs4 import BeautifulSoup

Затем определим две переменные: одну для всех внутренних ссылок (это URL, которые ссылаются на другие страницы того же сайта), другую для внешних ссылок вэб-сайта (это ссылки на другие сайты).

# Инициализировать набор ссылок (уникальные ссылки) int_url = set() ext_url = set()

Далее создадим функцию для проверки URL – адресов. Это обеспечит правильную схему в ссылке — протокол, например, http или https и имя домена в URL.

# Проверяем URL def valid_url(url): parsed = urlparse(url) return bool(parsed.netloc) and bool(parsed.scheme)

На следующем шаге создадим функцию, возвращающую все действительные URL-адреса одной конкретной веб-страницы:

# Возвращаем все URL-адреса def website_links(url): urls = set() # извлекаем доменное имя из URL domain_name = urlparse(url).netloc # скачиваем HTML-контент вэб-страницы soup = BeautifulSoup(requests.get(url).content, "html.parser")

Теперь получим все HTML теги, содержащие все ссылки вэб-страницы.

 for a_tag in soup.findAll("a"): href = a_tag.attrs.get("href") if href == "" or href is None: # href пустой тег continue

В итоге получаем атрибут href и проверяем его. Так как не все ссылки абсолютные, возникает необходимость выполнить соединение относительных URL-адресов и имени домена. К примеру, когда найден href — «/search» и URL — «google.com» , то в результате получим «google.com/search».

# присоединить URL, если он относительный (не абсолютная ссылка) href = urljoin(url, href)

В следующем шаге удаляем параметры HTTP GET из URL-адресов:

parsed_href = urlparse(href) # удалить параметры URL GET, фрагменты URL и т. д. href = parsed_href.scheme + "://" + parsed_href.netloc + parsed_href.path 

Если URL-адрес недействителен/URL уже находится в int_url , следует перейти к следующей ссылке.

Читайте также:  Java system console returns null

Если URL является внешней ссылкой, вывести его и добавить в глобальный набор ext_url и перейдти к следующей ссылке.

И наконец, после всех проверок получаем URL, являющийся внутренней ссылкой; выводим ее и добавляем в наборы urls и int_url

 if not valid_url(href): # недействительный URL continue if href in int_url: # уже в наборе continue if domain_name not in href: # внешняя ссылка if href not in ext_url: print(f"[!] External link: ") ext_url.add(href) continue print(f"[*] Internal link: ") urls.add(href) int_url.add(href) return urls 

Напоминаю, что эта функция захватывает ссылки одной вэб-страницы.

Теперь создадим функцию, которая сканирует весь веб-сайт. Данная функция получает все ссылки на первой странице сайта, затем рекурсивно вызывается для перехода по всем извлеченным ссылкам. Параметр max_urls позволяет избежать зависания программы на больших сайтах при достижении определенного количества проверенных URL-адресов.

# Количество посещенных URL-адресов visited_urls = 0 # Просматриваем веб-страницу и извлекаем все ссылки. def crawl(url, max_urls=50): # max_urls (int): количество макс. URL для сканирования global visited_urls visited_urls += 1 links = website_links(url) for link in links: if visited_urls > max_urls: break crawl(link, max_urls=max_urls) 

Итак, проверим на сайте, к которому имеется разрешение, как все это работает:

if __name__ == "__main__": crawl("https://newtechaudit.ru") print("[+] Total External links:", len(ext_url)) print("[+] Total Internal links:", len(int_url)) print("[+] Total:", len(ext_url) + len(int_url))

Вот фрагмент результата работы программы:

Обратите внимание, что многократный запрос к одному и тому же сайту за короткий промежуток времени может привести к тому, что ваш IP-адрес будет заблокирован. Ссылка на оригинал поста.

Источник

Возможно ли с помощью Python вытащить все внешние ссылки из сайта?

Rou1997

Если именно все и с любого сайта, то нужен встраиваемый браузер, то есть Selenium или Phantom.js, потому что на дворе 2016 год, и JavaScript все-таки уже существует, а еще есть Flash, который все-таки еще существует, и с ним еще сложнее все.
Ну а если достаточно простых , причем только тех которые не загружаются AJAX’ом, то можно с помощью RoboBrowser (BeautifulSoup) и т.п, то есть библиотек, которые только с DOM (HTML) работают.

Читайте также:  Задать значение словаря python

lxsmkv

lxml позволяет парсить вебстраницы. вот скрипт который открывает страницы хабра и выписывает все заголовки статей вместе со ссылками

# -*- coding: utf-8 -*- import urllib2 import sys from lxml import html import codecs codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None) cnt = 1 for x in range(1,100): url = ("http://habrahabr.ru/interesting/page%s/" % x) try: print "=== page "+str(x)+" ===" tree = html.fromstring(str(urllib2.urlopen(url).read())) topicLink =tree.xpath("//a[@class='post__title_link']/@href") topicTitle = tree.xpath("//a[@class='post__title_link']/text()") for i in range(0, len(topicTitle)): var = str(cnt)+" "+topicTitle[i]+" "+topicLink[i] print var print cnt=cnt+1 except IndexError: print("Page "+str(x)+" does not exist!") except urllib2.URLError: print("Could not retrieve the page..")

Источник

Оцените статью