Advertisement
Guest User

Untitled

a guest
Feb 17th, 2021
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.11 KB | None | 0 0
  1. import urllib.request
  2. from urllib.parse import urlsplit, urlunsplit, urljoin, urlparse
  3. import re
  4. from multiprocessing.pool import ThreadPool
  5.  
  6.  
  7. class Crawler:
  8.     MAX_LINKS = 50000
  9.  
  10.     def __init__(self, url, silence=False):
  11.         self.url = self.normalize(url)
  12.         self.host = urlparse(self.url).netloc
  13.         self.silence = silence
  14.         self.founded_links = []
  15.         self.visited_links = [self.url]
  16.  
  17.  
  18.  
  19.     def _crawl(self, url):
  20.         """
  21.        Основной процесс класса. \n
  22.        Поиск всех линков на сайте.
  23.        """
  24.         if not self.silence:
  25.             print(f"{len(self.founded_links)} - Парсинг {url}")
  26.         try:
  27.             response = urllib.request.urlopen(url)
  28.         except:
  29.             print(f"Ошибка {url}")
  30.             return
  31.  
  32.         founded_links = self.find_links(response)
  33.         links = []
  34.  
  35.         # Фильтрация полученных URl.
  36.         for link in founded_links:
  37.             if 'infinite' in link:
  38.                 pass
  39.  
  40.             elif Crawler.is_url(link) and self.is_internal(link):
  41.                 links.append(link) if (link not in links) else None
  42.                 self.founded_links.append(link) if (link not in self.founded_links) else None
  43.  
  44.         # Исследование найденных URL с мультипроцессингом.
  45.         scrap_pool = ThreadPool(15)
  46.         scrap_pool.map(self.link_analyze, links)
  47.         if len(self.founded_links) > 50000:
  48.             scrap_pool.terminate()
  49.             scrap_pool.join()
  50.  
  51.     def run(self):
  52.         """
  53.        Запуска кравлера.
  54.        """
  55.         self._crawl(self.url)
  56.         return self.founded_links
  57.  
  58.     def is_internal(self, url):
  59.         """
  60.        Проверка принадлежности URL к исследуемому домену.
  61.        """
  62.         host = urlparse(url).netloc
  63.         return host == self.host or host == ''
  64.  
  65.     def link_analyze(self, link):
  66.         if link not in self.visited_links:
  67.             link = self.normalize(link)
  68.             self.visited_links.append(link)
  69.             self._crawl(urljoin(self.url, link))
  70.  
  71.  
  72.     @staticmethod
  73.     def find_links(response):
  74.         """
  75.        Поиск url-ов на странице.
  76.        """
  77.         page = str(response.read())
  78.         pattern = '<a [^>]*href=[\'|"](.*?)[\'"].*?>'
  79.         founded_links = found_links = re.findall(pattern, page)
  80.         return found_links
  81.  
  82.     @staticmethod
  83.     def is_url(url):
  84.         """
  85.        Проверка корректности url.
  86.        """
  87.         scheme, netloc, path, qs, anchor = urlsplit(url)
  88.         return url != '' and scheme in ['http', 'https', '']
  89.  
  90.     @staticmethod
  91.     def normalize(url):
  92.         """
  93.        Нормализует полученный url.
  94.        :param url:
  95.        :return:
  96.        """
  97.         scheme, netloc, path, qs, anchor = urlsplit(url)
  98.         return urlunsplit((scheme, netloc, path, qs, anchor))
  99.  
  100.  
  101. if __name__ == '__main__':
  102.     c = Crawler('http://yandex.ru/')
  103.     k = c.run()
  104.     print(len(k))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement