Скрапинг страниц с бесконечной прокруткой с помощью Scrapy и Splash

Скрапинг страниц с бесконечной прокруткой с помощью Scrapy и Splash

Здесь я расскажу вам о том, как настроить Scrapy с ВсплескВы можете использовать бесконечную прокрутку, добавлять динамический контент и решать распространенные проблемы со скраппингом. Давайте погрузимся в процесс и посмотрим, как это делается, шаг за шагом.

Зачем скрапировать контент с бесконечной прокруткой?

Бесконечная прокрутка часто встречается на сайтах электронной коммерции, в социальных сетях и новостных агрегаторах, где дополнительные элементы подгружаются по мере прокрутки страницы вниз. Обычный HTML-парсер не справится со скрапингом таких сайтов, потому что новый контент появляется только после прокрутки. Здесь помогают headless-браузеры, такие как Splash: они имитируют прокрутку и загружают динамический контент для эффективного скрапинга.

Основы Scrapy и Splash

Scrapy Это фреймворк с открытым исходным кодом для веб-скрапинга на Python, известный своей скоростью, простотой и расширяемостью. Он предоставляет структурированный способ организовывать код и извлекать информацию с веб-сайтов.

Всплеск Splash — это headless-браузер, специально созданный для скрапинга. Он умеет выполнять JavaScript и рендерить HTML-страницы. В связке со Scrapy через Scrapy-Splash он позволяет скрапить сайты, которые полагаются на JavaScript для загрузки контента, например сайты с бесконечной прокруткой.

Пропустите бесконечный скроллинг - получите данные

Ниже перечислены лучшие сайты с наборами данныхЕсли ваш проект слишком сложен и вы не хотите тратить время впустую, обратите на них внимание:

  1. Яркие данные — Настраиваемые и готовые наборы данных по различным отраслям.
  2. Statista — Подробная статистика и отчеты для бизнеса и исследований.
  3. Datarade — Маркетплейс премиальных data-продуктов от разных поставщиков.
  4. AWS Data Exchange Наборы данных сторонних поставщиков, интегрированные с сервисами AWS.
  5. Zyte — Веб-скрейпинг и пользовательские наборы данных, адаптированные под потребности бизнеса.
  6. Data & Sons — Открытая торговая площадка для покупки и продажи разнообразных наборов данных.
  7. Coresignal — Аналитика рынка труда с обширными данными о вакансиях и занятости.
  8. Oxylabs — Специализированные услуги по данным компаний и веб-скрейпингу.
  9. Bloomberg Enterprise Data Catalog — Финансовые данные для корпоративного использования.
  10. Kaggle — Бесплатные общедоступные наборы данных и инструменты для науки о данных.

Шаг 1: Настройка Scrapy с помощью Splash

Чтобы начать использовать Splash вместе со Scrapy, выполните следующие шаги первоначальной настройки.

1. Установите Scrapy-Splash Откройте терминал и установите пакет scrapy-splash:

pip install scrapy-splash

2. Запуск Splash в Docker Для работы Splash требуется Docker, поэтому убедитесь, что Docker установлен и запущен на вашей машине. Используйте следующую команду, чтобы загрузить образ Splash:

docker pull scrapinghub/splash

Затем запустите сервер Splash:

docker run -it -p 8050:8050 -. rm scrapinghub/splash

Теперь Splash будет доступен по адресу http://localhost:8050, готовый отрисовывать JavaScript для вашего Scrapy-паука.

Шаг 2: Написание Lua-скрипта для прокрутки

Функция Lua-скриптов в Splash позволяет управлять браузером, прокручивать страницу вниз и ждать загрузки нового содержимого. Следующий Lua-скрипт прокручивает страницу до самого низа, ожидает появления нового содержимого и повторяет этот процесс несколько раз.

Lua-скрипт для прокрутки

функция главная(splash, args)
splash:go(args.url)
splash:wait(args.wait)
местный scroll_to = splash:jsfunc('window.scrollTo')
местный get_body_height = splash:jsfunc([[
function() {
return document.body.scrollHeight;
}
]])
местный scroll_count = 0
для _ = 1, args.max_scrolls сделать
scroll_count = scroll_count + 1
scroll_to(0, get_body_height())
splash:wait(args.scroll_delay)
конец
возврат {
html = splash:html(),
scroll_count = scroll_count
}
конец

В этом сценарии:

  • splash:go(args.url) загружает целевой URL.
  • splash:wait(args.wait) делает паузу, чтобы начальные элементы страницы успели загрузиться.
  • Цикл for прокручивает страницу несколько раз, ожидая некоторое время (args.scroll_delay) после каждого прокручивания, чтобы дать возможность загрузиться новому содержимому.

Шаг 3: Интеграция Lua-скрипта в Scrapy Spider

Когда Lua-скрипт готов, следующий шаг - настроить паука Scrapy для его запуска. Этот паук отправляет запрос через Splash на целевой сайт и передает Lua-скрипт.

Код паука

импорт scrapy
с сайта scrapy_splash импорт SplashRequest
класс InfiniteScrollSpider(scrapy.Spider):
имя = 'infinite_scroll_spider'
разрешенные_домены = ['example.com']
start_urls = ['http://example.com/target_page']
lua_script = """
function main(splash, args)
splash:go(args.url)
splash:wait(args.wait)
local scroll_to = splash:jsfunc('window.scrollTo')
local get_body_height = splash:jsfunc([[
function() {
return document.body.scrollHeight;
}
]])
local scroll_count = 0
for _ = 1, args.max_scrolls do
scroll_count = scroll_count + 1
scroll_to(0, get_body_height())
splash:wait(args.scroll_delay)
конец
return {
html = splash:html(),
scroll_count = scroll_count
}
end
"""
def start_requests(себя):
урожайность SplashRequest(
self.start_urls[0],
self.parse,
конечная точка='выполнить',
args={
'lua_source': self.lua_script,
'wait': 2,
'scroll_delay': 1,
'max_scrolls': 8
}
)
def разбор(self, response):
для пункт в response.css('.item-selector'):
урожайность {
'name': item.css('.name::text').get(),
'цена': item.css('.price::text').get()
}

Пояснение:

  • Паук отправляет SplashRequest с lua_source, указывающим на Lua-скрипт.
  • Такие аргументы, как wait, scroll_delay и max_scrolls, определяют поведение скрипта при прокрутке.
  • Функция parse извлекает данные о товаре (название и цену) из каждой итерации прокрутки.

Шаг 4: Работа с пагинацией и кнопками "Загрузить еще"

На многих страницах с бесконечной прокруткой используется скрытая кнопка «Загрузить еще», которая срабатывает, когда пользователь прокручивает страницу до конца. Lua-скрипт в Splash может обрабатывать этот сценарий, нажимая кнопку «Загрузить еще», когда она появляется.

Модифицированный Lua-скрипт для кнопки «Загрузить еще»

function main(splash, args)
splash:go(args.url)
splash:wait(args.wait)
local scroll_to = splash:jsfunc('window.scrollTo')
local get_body_height = splash:jsfunc([[
function() {
возврат document.body.scrollHeight;
}
]])
local scroll_count = 0
для _ = 1, args.max_scrolls do
scroll_count = scroll_count + 1
scroll_to(0, get_body_height())
splash:wait(args.scroll_delay)
local load_more = splash:select('.load-more-button')
если load_more then
load_more:mouse_click()
splash:wait(1) end end
возврат splash:html() end

Здесь переменная load_more ищет кнопку "Загрузить еще" с помощью своего селектора. Если она найдена, она имитирует нажатие, ждет загрузки содержимого и повторяет прокрутку.

Шаг 5: Обход защиты от ботов

На страницах с бесконечной прокруткой часто применяют антибот-защиту, включая CAPTCHA, ограничение частоты запросов и блокировку IP-адресов. Способы обхода включают:

  1. Ротация доверенных лиц: Ротация IP-адресов помогает избежать обнаружения. Такие сервисы, как ZenRows и ScraperAPI, позволяют включить ротацию IP-адресов с минимальной настройкой.
  2. User-Agent Rotation: Чтобы избежать обнаружения, случайным образом меняйте строку User-Agent при каждом запросе.
  3. Безголовый браузер: Splash работает в headless-режиме, поэтому ваши запросы больше похожи на обычный пользовательский трафик.

Вот как можно реализовать ротацию прокси с помощью ZenRows:

импорт scrapy
класс InfiniteScrollSpider(scrapy.Spider):
имя = 'proxy_spider'
разрешенные_домены = ['example.com']
def start_requests(себя):
прокси = 'http://@api.zenrows.com:8001'
url = 'http://example.com/target_page'
урожайность scrapy.Request(
url,
callback=self.parse,
мета={'proxy': proxy}
)
def разбор(self, response):
Логика разбора #

Этот пример настраивает Scrapy на использование ZenRows в качестве прокси для каждого запроса.

Шаг 6: Собираем все вместе

Вот полный код Scrapy-паука для скрапинга сайтов с бесконечной прокруткой, с интеграцией Splash, Lua-скриптом и ротацией прокси:

импорт scrapy
с сайта scrapy_splash импорт SplashRequest
класс FullInfiniteScrollSpider(scrapy.Spider):
имя = 'full_infinite_scroll'
разрешенные_домены = ['example.com']
start_urls = ['http://example.com/target_page']
lua_script = """
function main(splash, args)
splash:go(args.url)
splash:wait(args.wait)
local scroll_to = splash:jsfunc('window.scrollTo')
local get_body_height = splash:jsfunc([[
function() {
return document.body.scrollHeight;
}
]])
for _ = 1, args.max_scrolls do
scroll_to(0, get_body_height())
splash:wait(args.scroll_delay)
local load_more = splash:select('.load-more-button')
if load_more then
load_more:mouse_click()
splash:wait(1)
end
end
return splash:html()
end
"""
def start_requests(себя):
урожайность SplashRequest(
self.start_urls[0],
self.parse,
конечная точка='выполнить',
args={
'lua_source': self.lua_script,
'wait': 2,
'scroll_delay': 1,
'max_scrolls': 10
}
)
def разбор(self, response):
для пункт в response.css('.item-selector'):
урожайность {
'name': item.css('.name::text').get(),
'цена': item.css('.price::text').get()
}

Заключение

При создании страниц с бесконечной прокруткой я считаю Scrapy в связке со Splash очень удобным решением. Это удачная связка, которая позволяет без труда справляться даже с самыми сложными динамическими сайтами. С помощью Splash я могу справляться с рендерингом на JavaScript, а Scrapy отлично подходит для извлечения данных. Lua-скрипты Splash позволяют взаимодействовать с элементами страницы и подгружать дополнительный контент так, как если бы страницу прокручивал пользователь.

Похожие записи