Веб-скрапинг — это процесс программного извлечения данных с веб-сайтов. Scrapy — это популярная платформа для очистки веб-страниц с открытым исходным кодом для Python, которая позволяет легко собирать данные из Интернета в любом масштабе. В этом подробном руководстве вы узнаете, как использовать Scrapy для создания надежных парсеров веб-страниц.
Что такое Scrapy?
Scrapy — это платформа сканирования и очистки веб-страниц с открытым исходным кодом для Python. Он предоставляет высокоуровневый API для быстрого и эффективного извлечения данных с веб-сайтов.
Некоторые ключевые особенности Scrapy:
- Встроенная поддержка рекурсивного сканирования веб-сайтов и перехода по ссылкам.
- Гибкий механизм извлечения данных с помощью селекторов CSS и выражений XPath.
- Встроенная поддержка анализа содержимого HTML и XML.
- Удобно для парсинга сайтов с большим количеством JavaScript за счет интеграции с такими браузерами, как Selenium.
- Простой способ очистки данных с использованием асинхронного ввода-вывода для повышения производительности.
- Экспортируйте очищенные данные в форматы JSON, CSV, XML.
- Способен обрабатывать большие проекты парсинга, включающие тысячи запросов.
- Расширяйте функциональность с помощью промежуточного программного обеспечения, расширений и конвейеров.
- Широкий спектр готовых к использованию пауков с открытым исходным кодом для популярных веб-сайтов.
Короче говоря, Scrapy предоставляет все функции, необходимые для создания надежных парсеров любого масштаба и сложности.
Создание вашего первого Scrapy Spider
Лучший способ понять Scrapy — создать простого паука. Давайте посмотрим, как создать паука, который собирает цитаты с сайта. http://quotes.toscrape.com.
Сначала установите Scrapy:
pip install scrapy
Затем создайте новый проект Scrapy под названием myquotes
:
scrapy startproject myquotes
Это создаст myquotes
каталог со следующим содержимым:
myquotes/
scrapy.cfg
myquotes/
__init__.py
items.py
middlewares.py
pipelines.py
settings.py
spiders/
__init__.py
Мы будем писать наш код внутри spiders/
. Создайте нового паука под названием quotes_spider.py
запустив:
cd myquotes
scrapy genspider quotes_spider quotes.toscrape.com
Это создаст файл quotes_spider.py
с шаблонным кодом для нашего паука. Давайте изменим его, чтобы очистить кавычки:
import scrapy
class QuotesSpider(scrapy.Spider):
name = ‘quotes‘
allowed_domains = [‘quotes.toscrape.com‘]
start_urls = [‘http://quotes.toscrape.com/‘]
def parse(self, response):
quotes = response.css(‘.quote‘)
for quote in quotes:
text = quote.css(‘.text::text‘).extract_first()
author = quote.css(‘.author::text‘).extract_first()
tags = quote.css(‘.tags .tag::text‘).extract()
yield {
‘text‘: text,
‘author‘: author,
‘tags‘: tags
}
Этот паук будет:
- Сканировать сайт, начиная с
start_urls
. - Использовать
parse()
метод извлечения данных из ответа. - Найти все
.quote
элементы на странице и извлеките цитатуtext
,author
иtags
. - Получите словарь Python с извлеченными данными для каждой цитаты.
Чтобы запустить этого паука:
scrapy crawl quotes
Это соберет данные с веб-сайта котировок и выведет их на консоль. Вы также можете сохранить результаты в файл, передав -o filename.json
.
Вот и все! Вы создали своего первого паука Scrapy. Далее давайте подробно рассмотрим некоторые ключевые понятия.
Обзор Scrapy-архитектуры
Scrapy построен на основе следующих основных компонентов:
Двигатель
Движок отвечает за управление потоком данных между всеми компонентами Scrapy. Он запускает события при возникновении определенных действий, таких как запуск паука или выполнение запроса.
Планировщик
Планировщик получает запросы от движка и ставит их в очередь для очистки загрузчиком. Он определяет приоритетность запросов на основе различных очередей и оптимизирует эффективность очистки.
Загрузчик
Загрузчик занимается загрузкой веб-страниц и передачей ответов обратно в движок. Он эффективно управляет несколькими одновременными запросами.
Spiders
Пауки — это основные компоненты, в которых вы реализуете логику очистки. Они начинают сканирование с определенных URL-адресов и анализируют ответы с помощью парсеров.
Конвейер элементов
Трубопроводы обрабатывают очищенные предметы. Они используются для проверки, очистки, хранения и последующей обработки данных. Можно включить несколько конвейеров для формирования цепочки обработки элементов.
Промежуточное ПО загрузчика
Промежуточное программное обеспечение загрузчика находится между движком и загрузчиком и изменяет запросы перед их отправкой и ответы до того, как они будут возвращены в движок. Они используются для таких вещей, как регулирование запросов, кэширование, модификация заголовков и т. д.
Промежуточное программное обеспечение паука
Промежуточное программное обеспечение паука — это перехватчики, которые располагаются между движком и пауком и вызываются перед методами паука. Они используются для расширения и изменения поведения пауков.
Эта архитектура делает Scrapy очень модульным и гибким для создания надежных сканеров. Далее давайте углубимся в пауков.
Понимание Scrapy Spiders
Паук — это компонент, который контролирует процесс очистки в Scrapy. Основными задачами пауков являются:
- Начните сканирование с одного или нескольких определенных URL-адресов.
- Следуйте ссылкам, чтобы рекурсивно очищать контент.
- Анализируйте ответы с помощью синтаксических анализаторов, таких как селекторы CSS и XPath.
- Возвращайте очищенные данные в виде диктовок, элементов или других объектов.
В Scrapy есть несколько типов встроенных пауков:
ПолзатьПаук
CrawlSpider используется для сканирования и очистки данных с нескольких веб-страниц в домене (или группе доменов). Он имеет полезные функции, такие как переход по ссылкам и правилам.
Например:
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
class MySpider(CrawlSpider):
name = ‘crawlspider‘
allowed_domains = [‘example.com‘]
start_urls = [‘http://www.example.com‘]
rules = (
Rule(LinkExtractor(allow=r‘Items/‘), callback=‘parse_item‘, follow=True),
)
def parse_item(self, response):
# Scrape data and return Items here
pass
Этот паук начнет ползать из example.com
, перейдите по всем ссылкам, совпадающим Items/
и позвонить parse_item()
метод для очистки данных из каждого ответа.
XMLFeedSpider
XMLFeedSpider предназначен для извлечения данных из XML-каналов. Вы предоставляете ему URL-адреса каналов, а затем извлекаете данные из узлов с помощью XPath.
Например:
from scrapy.spiders import XMLFeedSpider
class MySpider(XMLFeedSpider):
name = ‘xmlspider‘
allowed_domains = [‘example.com‘]
start_urls = [‘http://www.example.com/feed.xml‘]
iterator = ‘iternodes‘ # This is actually unnecessary, since it‘s the default value
itertag = ‘item‘
def parse_node(self, response, node):
# Extract data from <item> nodes using XPath
pass
Этот паук будет очищать данные из XML-канала, расположенного по адресу http://www.example.com/feed.xml
.
Существуют и другие встроенные типы пауков, например CSVFeedSpider
, SitemapSpider
и т. д., предназначенные для разных целей. Вы можете даже создайте свои собственные классы пауков.
Селекторы для извлечения данных
Scrapy предоставляет селекторы для извлечения данных из ответов HTML и XML с использованием селекторов CSS или выражений XPath.
Например:
response.css(‘div.quote‘).extract() # Get all <div class="quote"> elements
response.xpath(‘//div‘) # Get all <div> elements
quote = response.css(‘div.quote‘)[0]
quote.css(‘span.text::text‘).get() # Extract text from <span> inside first <div>
quote.xpath(‘./span/text()‘).get() # Alternative way with XPath
Вы даже можете выбрать данные из элемента и извлечь атрибуты:
for link in response.css(‘ul.links li a‘):
link_name = link.xpath(‘./text()‘).get()
link_url = link.xpath(‘./@href‘).get()
Это позволяет очень легко находить и извлекать нужные данные из ответов.
Обработка страниц JavaScript
По умолчанию пауки Scrapy не могут очищать страницы с большим количеством JavaScript, поскольку Scrapy видит только исходный HTML, возвращаемый сервером. Чтобы очистить динамический контент, загружаемый через JavaScript, вы можете интегрировать Scrapy с инструментом автоматизации браузера, например Драматург or Селен.
Самый простой способ - это использовать scrapy-playwright
расширение, которое интегрирует Playwright со Scrapy.
Сначала установите его:
pip install scrapy-playwright
Затем включите его, добавив это промежуточное программное обеспечение:
DOWNLOADER_MIDDLEWARES = {
‘scrapy_playwright.middleware.PlaywrightMiddleware‘: 1,
}
Наконец, установите playwright=True
в Request
мета для рендеринга страниц с помощью Playwright:
yield scrapy.Request(url, meta={
‘playwright‘: True,
})
Playwright загрузит JavaScript на каждой странице перед передачей визуализированного HTML в Scrapy для очистки.
Это позволяет легко парсить современные веб-сайты JavaScript с помощью Scrapy и Playwright!
Хранение очищенных данных
По умолчанию Scrapy выводит очищенные данные на консоль. Существует несколько способов хранения очищенных данных:
JSON, CSV, XML-каналы
Самый простой способ — сохранить очищенные элементы в файл с помощью команды -o
флаг:
scrapy crawl quotes -o quotes.json
Это сохранит все очищенные элементы в файл JSON. CSV, JSONL, XML и другие форматы также поддерживаются.
Конвейер в базу данных
Для структурированного хранения данных вы можете написать конвейер для хранения элементов в таких базах данных, как MongoDB, PostgreSQL и т. д.
Например, конвейер MongoDB:
import pymongo
class MongoPipeline(object):
collection_name = ‘quotes‘
def __init__(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db
@classmethod
def from_crawler(cls, crawler):
return cls(
mongo_uri=crawler.settings.get(‘MONGO_URI‘),
mongo_db=crawler.settings.get(‘MONGO_DATABASE‘)
)
def open_spider(self, spider):
self.client = pymongo.MongoClient(self.mongo_uri)
self.db = self.client[self.mongo_db]
def close_spider(self, spider):
self.client.close()
def process_item(self, item, spider):
self.db[self.collection_name].insert_one(dict(item))
return item
Этот конвейер подключается к MongoDB и вставляет все очищенные элементы в коллекцию.
Пользовательские серверные хранилища
Вы можете написать подклассы Scrapy.Exporter для хранения данных любым удобным для вас способом, например, в собственной базе данных или системе аналитики.
Некоторые популярные варианты хранения:
- Scrapy Cloud – хранит очищенные элементы в облаке и предоставляет веб-интерфейс для доступа к данным.
- Kafka — потоковая передача очищенных элементов в кластер Kafka.
- Elasticsearch — индексируйте и запрашивайте очищенные элементы в Elasticsearch.
Советы по сканированию
Вот несколько советов по эффективному сканированию с помощью Scrapy:
Инициализировать
allowed_domains
атрибут, позволяющий ограничить сканирование одним доменом (или небольшой группой доменов).Установите небольшой
DOWNLOAD_DELAY
примерно 1-2 секунды, чтобы избежать перегруженности сайтов.Отключите файлы cookie, установив
COOKIES_ENABLED = False
если не требуется улучшение производительности.Использовать
CONCURRENT_REQUESTS
настройка для регулировки количества одновременных запросов. Начните с низкого значения, например 8-16.Создайте одного паука для каждого веб-сайта, если парсинг нескольких доменов.
Используйте
scrapy shell
для быстрого интерактивного тестирования селекторов.Отслеживайте статус и статистику парсинга с помощью веб-интерфейса Scrapyd.
Используйте такие услуги, как Прокси-сетка маршрутизировать запросы через резидентные прокси и избегать банов по IP.
Расширенные функции
Некоторые более продвинутые функции Scrapy:
Динамическое сканирование с помощью FormRequest
Используйте FormRequest
и данные формы для имитации отправки HTML-форм:
data = {
‘search_query‘: ‘scraping‘
}
yield FormRequest(url=‘http://quotes.toscrape.com/search‘, formdata=data, callback=self.parse_search_results)
Постобработка с помощью Item Pipeline
Конвейеры предметов позволяют обрабатывать очищенные предметы. Полезно для:
- Проверка и очистка данных
- дедупликации
- Хранение данных в базах данных
- Отправка элементов в конечные точки API
Можно включить несколько конвейеров, заказав их через ITEM_PIPELINES
установка.
HTTP-кеширование
Включите встроенное кэширование, чтобы избежать повторной загрузки часто посещаемых страниц:
HTTPCACHE_ENABLED = True
HTTPCACHE_EXPIRATION_SECS = 0 # Cache forever
HTTPCACHE_DIR = ‘cache‘
HTTPCACHE_IGNORE_HTTP_CODES = [500, 503, 504]
Пользовательские промежуточные программы Spider
Промежуточное программное обеспечение Spider позволяет внедрять собственный код до/после выполнения методов Spider. Полезно для обертывания парсеров с ротацией прокси, повторными попытками и т. д.
class UserAgentMiddleware:
def process_request(self, request, spider):
request.headers[‘User-Agent‘] = random_user_agent()
Распределенное сканирование с помощью Scrapyd и Scrapy Cloud
Такие инструменты, как Скрэпид и Скрэпи-облако упростить запуск Scrapy-пауков на нескольких серверах для масштабирования парсинга.
Заключение
И вот оно — подробное руководство по парсингу веб-страниц с помощью Scrapy на Python. Scrapy — это универсальный инструмент, который может обрабатывать все: от простых одностраничных парсеров до крупных распределенных проектов сканирования. Ключевые сильные стороны — это простые, но мощные механизмы извлечения, встроенная обработка асинхронности и широкие возможности постобработки и хранения очищенных данных.
Некоторые ключевые темы, которые мы рассмотрели, включали:
- Архитектура Scrapy и основные компоненты, такие как пауки, конвейеры, промежуточное ПО и т. д.
- Создание базовых пауков путем создания подклассов
scrapy.Spider
. - Использование выражений селектора для извлечения данных из HTML и XML.
- Сканирование нескольких страниц с помощью таких пауков, как
CrawlSpider
. - Парсинг страниц JavaScript с помощью интеграции таких инструментов, как Playwright.
- Хранение очищенных элементов в разных форматах или базах данных.
- Следование лучшим практикам эффективного сканирования и избежания банов.
- Расширенные функции, такие как промежуточное программное обеспечение, кэширование, распределенное сканирование и т. д.
Подводя итог, Scrapy предоставляет надежную основу для создания веб-парсеров промышленного уровня любой сложности. Проявив немного осторожности и планирования, вы можете использовать Scrapy для извлечения данных практически с любого веб-сайта. Приятного скрежетания!