Узнайте о различных способах использования прокси-серверов для парсинга веб-страниц с помощью 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'}

Ваше здоровье! Профили прокси для разных стран успешно используются в парсинге.

Статьи по Теме:

Дополнительные материалы на PlainEnglish.io.

Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .