Реализация веб-парсинга в Python с помощью Scrapy
С помощью Scrapy можно :
1. Эффективно получать миллионы данных
2. Запустить его на сервере
3. Получить данные
4. Запустить spider в нескольких процессах
Scrapy предлагает совершенно новые возможности по созданию spider'а, его запуску и последующему сохранению данных путем их соскабливания, что делает его отличным инструментом для парсинга сайтов и маркетплейсов. Поначалу это выглядит довольно запутанно, но это и к лучшему.
Давайте поговорим об установке, создании spider'а и его тестировании.
Шаг 1: Создание виртуальной среды
Хорошо создавать одну виртуальную среду, поскольку она изолирует программу и не влияет на другие программы, присутствующие на машине, что является общепринятой практикой в разработке ПО. Для создания виртуальной среды сначала установите ее с помощью:
sudo apt-get install python3-venv
Создайте одну папку и активизируйте ее:
mkdir scrapy-project && cd scrapy-project
python3 -m venv myvenv
Если приведенная выше команда дает ошибку, то попробуйте сделать следующее:
python3.5 -m venv myvenv
После создания виртуальной среды активизируйте ее с помощью :
source myvenv/bin/activate
Шаг 2 : Установка модуля Scrapy
Установите модуль Scrapy с помощью программы:
pip install scrapy
Для установки scrapy для какой-либо конкретной версии python:
python3.5 -m pip install scrapy
Замените версию 3.5 на какую-либо другую, например 3.6.
Шаг 3: Создание проекта Scrapy
При работе с Scrapy необходимо создать проект scrapy.
scrapy startproject gfg
В Scrapy всегда стараются создать одного паука, который помогает получать данные, поэтому для его создания перейдите в папку spider и создайте там один python-файл. Создайте одного паука с именем gfgfetch.py python-файла.
Шаг 4: Создание Spider
Перейдите в папку spider и создайте файл gfgfetch.py. При создании паука всегда создавайте один класс с уникальным именем и определяйте требования. Прежде всего, необходимо дать имя spider'у, присвоив ему переменную name, а затем указать начальный URL, по которому паук начнет ползать. Определите некоторые методы, которые помогут проползти гораздо глубже на этот сайт. На данный момент давайте отбракуем все имеющиеся URL и сохраним их.
import scrapyclass ExtractUrls(scrapy.Spider):# This name must be unique alwaysname = "extract"# Function which will be invokeddef start_requests(self):# enter the URL hereurls = ['https://www.geeksforgeeks.org/', ]for url in urls:yield scrapy.Request(url = url, callback = self.parse)
Основная цель - получить каждый url и затем запросить его. Извлечь из него все url или теги anchor. Для этого необходимо создать еще один метод parse , который будет получать данные из заданного url.

Шаг 5. Получение данных с заданной страницы
Перед написанием функции parse необходимо проверить несколько моментов, например, как получить данные с заданной страницы. Для этого можно воспользоваться оболочкой scrapy. Этот инструмент помогает в проектировании решения для веб-парсинга. Это такой же интерпретатор python, но с возможностью извлечения данных из заданного url. Короче говоря, это интерпретатор python с функциональностью Scrapy.
scrapy shell URL
Примечание: Убедитесь, что в той же директории, где находится scrapy.cfg, находится файл scrapy.cfg, иначе он не будет работать.
scrapy shell https://www.geeksforgeeks.org/
Теперь для получения данных с заданной страницы используются селекторы. Эти селекторы могут быть как из CSS, так и из Xpath. Сейчас попробуем получить все url с помощью CSS-селектора.
- Для получения тега anchor:
response.css('a')
- Для извлечения данных :
links = response.css('a').extract()
- Например, для links[0] будет показано что-то вроде этого :
'<a href="https://www.geeksforgeeks.org/" title="GeeksforGeeks" rel="home">GeeksforGeeks</a>'
- Чтобы получить атрибут href, используйте тег attributes.
links = response.css('a::attr(href)').extract()
Это позволит получить все данные href, что очень полезно. Воспользуйтесь этой ссылкой и начните запрашивать ее.
Теперь давайте создадим метод parse и получим все ссылки, а затем выдадим их. Следуйте за этим URL и получайте другие ссылки с этой страницы, и так будет повторяться снова и снова. Короче говоря, мы получаем все url, присутствующие на этой странице.
Scrapy, по умолчанию, фильтрует те url, которые уже были посещены. Таким образом, он не будет повторять один и тот же путь к url. Но возможно, что на двух разных страницах есть две или более двух одинаковых ссылок. Например, на каждой странице будет доступна ссылка на заголовок, что означает, что эта ссылка на заголовок будет приходить в каждом запросе страницы. Поэтому попробуйте исключить ее путем проверки.
# Parse function
def parse(self, response):
# Extra feature to get title
title = response.css('title::text').extract_first()
# Get anchor tags
links = response.css('a::attr(href)').extract()
for link in links:
yield
{
'title': title,
'links': link
}
if 'geeksforgeeks' in link:
yield scrapy.Request(url = link, callback = self.parse)
# importing the scrapy moduleimport scrapyclass ExtractUrls(scrapy.Spider):name = "extract"# request functiondef start_requests(self):urls = [ 'https://www.geeksforgeeks.org', ]for url in urls:yield scrapy.Request(url = url, callback = self.parse)# Parse functiondef parse(self, response):# Extra feature to get titletitle = response.css('title::text').extract_first()# Get anchor tagslinks = response.css('a::attr(href)').extract()for link in links:yield{'title': title,'links': link}if 'geeksforgeeks' in link:yield scrapy.Request(url = link, callback = self.parse)
Шаг 6: На последнем шаге запустите spider и получите результат в виде простого json-файла
scrapy crawl NAME_OF_SPIDER -o links.json
В данном примере имя spider'а - "extract". За несколько секунд он соберет большое количество данных.


