Узнайте о различных способах использования прокси-серверов для парсинга веб-страниц с помощью Splash.
При парсинге веб-страниц нам часто приходится использовать прокси-серверы из-за блокировки IP-адресов или данных, зависящих от геолокации, что означает, что извлеченные данные могут меняться в зависимости от геолокации IP-адресов, отправляющих запросы. Несложно указать прокси для обычного парсинга. Однако, когда дело доходит до скрапинга веб-страниц, отображаемых с помощью JavaScript, с использованием Splash, это может быть более сложным, поскольку запросы должны выполняться через безголовый браузер Splash за кулисами.
В этом посте мы расскажем, как использовать Splash с прокси-серверами для парсинга веб-страниц, обработанных JavaScript, на простых примерах.
Подготовка
Для начала нам нужно запустить сервер Splash локально. Самый простой способ — использовать Docker:
docker run -it -p 8050:8050 --rm scrapinghub/splash:3.5
Затем нам нужно установить библиотеку requests
для HTTP-запросов в Python. Если вам нужно выполнить более сложный веб-скрейпинг на Python, вы также можете установить библиотеку lxml
.
Для более подробной подготовки Splash обратитесь к этому руководству.
Получите свой IP-адрес в веб-скрапинге
Самый простой способ проверить, успешно ли используется прокси-сервер, — это проверить IP-адрес в веб-скрапинге.
Мы можем сделать запрос на https://httpbin.org/ip, который вернет IP запроса:
import requests response = requests.get("https://httpbin.org/ip") print(response.json()) # {'origin': '31.XXX.XXX.16'}
Когда прокси-сервер используется для парсинга веб-страниц, IP-адрес прокси-сервера используется в парсинге веб-страниц, что может помочь избежать блокировки IP-адресов, а также получить данные, зависящие от геолокации.
Существует множество коммерческих прокси-провайдеров, как показано в этой ссылке. Если вы просто хотите провести некоторые тесты, вы можете использовать WebShare, который предоставляет бесплатные прокси для тестирования. Подробнее об использовании прокси в парсинге читайте в этой публикации.
Давайте используем прокси в нашем запросе выше и посмотрим, какой IP возвращается:
import requests proxies = { "http": "http://USERNAME:[email protected]:5074", "https": "http://USERNAME:[email protected]:5074", } response = requests.get("https://httpbin.org/ip", proxies=proxies) print(response.json()) # {'origin': '2.XXX.XXX.93'}
Он показывает, что возвращается IP-адрес прокси-сервера, а не локальный IP-адрес, как показано выше.
Используйте прокси со Splash
Теперь воспользуемся прокси со Splash. Мы можем просто указать параметр запроса proxy
в URL-адресе Splash API. Значение proxy
— это либо URL-адрес прокси-сервера, либо имя профиля прокси-сервера, как мы скоро представим:
import requests httpbin_url = "https://httpbin.org/ip" encoded_url = quote(httpbin_url) proxy = "http://USERNAME:[email protected]:5074" splash_url='http://localhost:8050' api_url = f"{splash_url}/render.html?url={encoded_url}&proxy={proxy}&timeout=5" response = requests.get(api_url) print(response.text)
И вот что мы получаем:
<html><head></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">{ "origin": "2.XXX.XXX.93" } </pre></body></html>
Как мы видим, IP-адрес прокси-сервера возвращается, что означает, что прокси-сервер успешно используется Splash для очистки веб-страниц. Однако здесь следует отметить два момента.
- Здесь необходимо указать только прокси-сервер HTTP, даже для URL-адресов HTTPS.
- Обычный текст возвращается, если запрашивается конечная точка
render.html
. Данные JSON не возвращаются.
Чтобы получить данные JSON, нам нужно сделать запросы к конечной точке execute
и запустить в ней какой-нибудь пользовательский Splash-скрипт. Давайте завернем код в функцию, чтобы его можно было легко использовать повторно позже:
from urllib.parse import quote import requests splash_url='http://localhost:8050' httpbin_url = "https://httpbin.org/ip" proxy = "http://USERNAME:[email protected]:5074" def get_ip_json(proxy, timeout=5): encoded_url = quote(httpbin_url) api_url = f"{splash_url}/execute?url={encoded_url}&proxy={proxy}&wait={timeout}" payload = { "lua_source": """ function main(splash, args) local response = splash:http_get(args.url) splash:wait(args.wait) return response.body end """ } response = requests.post(api_url, json=payload) print(response.text) get_ip_json(proxy) # {'origin': '2.XXX.XXX.93'}
Простой скрипт Lua используется для выполнения HTTP-запроса и возврата тела ответа, содержащего данные JSON.
Если мы вызовем функцию get_ip_json()
с прокси, данные JSON могут быть возвращены, как в нашем первом примере.
Используйте прокси-профили
Когда вам нужно использовать несколько прокси в парсинге, например, используя разные прокси для разных стран, удобнее использовать «профили прокси», а не указывать их явно в коде.
Профиль прокси — это файл конфигурации в формате INI, в котором вы можете указать конфигурацию прокси-сервера HTTP, включая хост, порт, имя пользователя, пароль и т. д. Каждый профиль идентифицируется по имени файла без расширения .ini
.
Давайте создадим папку с именем proxy-profiles
в текущей папке, а затем создадим в ней два файла proxy-es.ini
и proxy-us.ini
:
proxy-profiles/ ├── proxy-es.ini └── proxy-us.ini
Содержание для proxy-es.ini
:
[proxy] ; required host=185.XXX.XXX.156 port=7492 ; optional, default is no auth username=USERNAME password=PASSWORD ; optional, default is HTTP. Allowed values are HTTP and SOCKS5 type=HTTP
И содержание для proxy-us.ini
:
[proxy] ; required host=2.XXX.XXX.93 port=5074 ; optional, default is no auth username=USERNAME password=PASSWORD ; optional, default is HTTP. Allowed values are HTTP and SOCKS5 type=HTTP
Не забудьте заменить конфигурации своими, чтобы они работали на вас.
Затем мы можем привязать папку proxy-profiles
к контейнеру Docker:
docker run -it -p 8050:8050 -v ./proxy-profiles:/etc/splash/proxy-profiles --rm scrapinghub/splash:3.5
Обратите внимание, что вам нужно остановить существующий контейнер Docker для Splash, прежде чем запускать новый, иначе у вас возникнут конфликты портов.
Соответствующий файл docker-compose.yaml
для Docker Compose:
version: '3.8' services: splash: image: scrapinghub/splash:3.5 ports: - target: 8050 published: 8050 volumes: - type: bind source: ./proxy-profiles target: /etc/splash/proxy-profiles restart: always
Когда контейнер запустится, вы увидите в логе, что поддержка прокси-профилей включена:
2023-05-26 06:12:42.115017 [-] proxy profiles support is enabled, proxy profiles path: /etc/splash/proxy-profiles
Теперь мы можем начать использовать прокси-профили для парсинга. Обратите внимание, что мы используем имена файлов профилей прокси (без расширения) для справки в коде:
get_ip_json(proxy="proxy-us") # {'origin': '2.XXX.XXX.93'} get_ip_json(proxy="proxy-es") # {'origin': '185.XXX.XXX.156'}
Ваше здоровье! Профили прокси для разных стран успешно используются в парсинге.
Статьи по Теме:
- Как использовать прокси в геотаргетинге веб-скрейпинга с помощью Python
- Как очищать веб-страницы JavaScript с помощью Splash, Requests и lxml в Python
Дополнительные материалы на PlainEnglish.io.
Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .