Скрапинг изображений с Yahoo Images при помощи Python

Комментарии: 0

В этом руководстве рассмотрим, как использовать Python для извлечения изображений из Yahoo Images, применяя при этом библиотеки Requests и lxml для парсинга HTML. Особое внимание будет уделено применению прокси для минимизации риска блокировки со стороны механизмов Yahoo, предназначенных для обнаружения и блокировки ботов.

Необходимые инструменты и библиотеки

Для скрапинга изображений с сервиса Yahoo Images вам потребуются следующие инструменты и библиотеки Python:

  • Requests: для отправки HTTP-запросов.
  • lxml: для парсинга HTML.
  • Прокси: для избежания блокировки IP при интенсивном скрапинга.

Установка необходимых библиотек

Для настройки среды, убедитесь, что у вас установлены все необходимые библиотеки с помощью pip:

pip install requests
pip install lxml

Или используйте одну команду для установки обеих библиотек:

pip install requests lxml

Пошаговая инструкция по скрапингу с помощью Python

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

import requests
from lxml import html

Выполнение поиска в Yahoo Images

Далее мы выполним поиск в Yahoo Images. Определим поисковый запрос как “puppies” и отправим GET-запрос к поиску изображений Yahoo с необходимыми заголовками. Заголовки запроса важны для имитации запроса из браузера, что помогает обходить некоторые базовые механизмы обнаружения ботов.

# Определение заголовков для имитации запроса из браузера
headers = {
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "accept-language": "en-IN,en;q=0.9",
    "cache-control": "max-age=0",
    "dnt": "1",
    "priority": "u=0, i",
    "sec-ch-ua": '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"Linux"',
    "sec-fetch-dest": "document",
    "sec-fetch-mode": "navigate",
    "sec-fetch-site": "none",
    "sec-fetch-user": "?1",
    "upgrade-insecure-requests": "1",
    "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
}

# Определение поискового запроса
search_query = "puppies"

# Отправка GET-запроса на страницу поиска изображений Yahoo
response = requests.get(
    url=f"https://images.search.yahoo.com/search/images?p={search_query}",
    headers=headers
)

Парсинг URL изображений с помощью lxml

После получения ответа от Yahoo нам нужно проанализировать HTML, чтобы извлечь URL изображений. Для этого мы используем библиотеку lxml.

# Парсинг HTML-ответа
parser = fromstring(response.text)

# Извлечь URL изображений с помощью XPath
images_urls = parser.xpath("//li[contains(@id, 'resitem-')]/a//@src")

Функция fromstring используется для парсинга текста HTML-ответа. Xpath используется для извлечения URL изображений. На изображении ниже показано, как был получен XPath:

yaho.png

Скачивание изображений

Далее необходимо выполнить загрузку изображений из списка “images_urls”, содержащего URL-адреса изображений. Для этого используем следующий подход в Python: каждый URL в списке будет обработан с помощью GET-запроса для загрузки изображения.

# Скачайте каждое изображение и сохраните его в файл
for count, url in enumerate(images_urls):
    response = requests.get(url=url, headers=headers)

Сохранение изображений

Далее, мы сохраняем загруженные изображения в локальной файловой системе. Мы определяем функцию download_file, которая управляет процессом сохранения файла.

Эта функция принимает индекс для создания уникальных имен файлов и ответ, содержащий данные изображения. Она определяет расширение файла из заголовка Content-Type и сохраняет файл в директории ./images/.

def download_file(count, response):
    # Получите расширение файла из заголовка Content-Type
    extension = response.headers.get("Content-Type").split("/")[1]
    filename = "./images/" + str(count) + f".{extension}"

    # Создайте директорию, в случае если она отсутствует
    os.makedirs(os.path.dirname(filename), exist_ok=True)

    # Запишите содержимое ответа в файл
    with open(filename, "wb") as f:
        f.write(response.content)

Применяя эту функцию в цикле, мы сохраняем каждое загруженное изображение:

for count, url in enumerate(images_urls):
    response = requests.get(url=url, headers=headers)
    download_file(count, response)

Механизмы обнаружения ботов на сервисе Yahoo

При скрапинге данных с Yahoo важно помнить о механизмах обнаружения ботов Yahoo. Yahoo в основном использует следующие техники для идентификации и блокировки ботов для автоматизации:

  • Ограничение частоты запросов по IP: Yahoo отслеживает частоту запросов, поступающих с одного IP-адреса. Чрезмерное количество запросов с одного IP может привести к временной или постоянной блокировке.
  • CAPTCHA: Yahoo может использовать CAPTCHA для подтверждения, что пользователь не является роботом.

Использование прокси для обхода ограничений

Чтобы избежать блокировки механизмами обнаружения ботов Yahoo, особенно при отправке множества запросов с одного IP-адреса, мы используем прокси для маскировки IP-адреса.

Маршрутизация запросов через различные прокси позволяет распределить активность скрапера по множеству IP-адресов, тем самым снижая вероятность обнаружения.

proxies = {
    'http': 'http://USER:PASS@HOST:PORT',
    'https': 'http://USER:PASS@HOST:PORT'
}
response = requests.get(url, headers=headers, proxies=proxies, verify=False)

Полная версия кода

Ниже представлен корректный код для скрапинга изображений из результатов поиска Yahoo Images с использованием прокси:

import os
import requests
from lxml.html import fromstring


def download_file(count, response):
    """
    Сохраняет содержимое ответа в файл в директории ./images/.

    Args:
        count (int): Уникальный идентификатор файла.
        response (requests.Response): HTTP-ответ, содержащий контент файла.

    """
    # Получите расширение файла из заголовка Content-Type
    extension = response.headers.get("Content-Type").split("/")[1]
    filename = "./images/" + str(count) + f".{extension}"

    # Создайте директорию, в случае если она отсутствует
    os.makedirs(os.path.dirname(filename), exist_ok=True)

    # Запишите содержимое ответа в файл
    with open(filename, "wb") as f:
        f.write(response.content)


def main():
    """
   Основная функция для поиска изображений и их загрузки.

    Эта функция выполняет следующие действия:
    1. Настраивает заголовки запроса.
    2. Ищет изображения щенков на Yahoo.
    3. Анализирует HTML-ответ для извлечения URL-адресов изображений.
    4. Скачивает каждое изображение и сохраняет его в директории ./images/.

    """
    # Определите заголовки для имитации запроса из браузера
    headers = {
        "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        "accept-language": "en-IN,en;q=0.9",
        "cache-control": "max-age=0",
        "dnt": "1",
        "priority": "u=0, i",
        "sec-ch-ua": '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": '"Linux"',
        "sec-fetch-dest": "document",
        "sec-fetch-mode": "navigate",
        "sec-fetch-site": "none",
        "sec-fetch-user": "?1",
        "upgrade-insecure-requests": "1",
        "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
    }

    # Определите прокси для обхода ограничений по частоте запросов
    proxies = {"http": "http://USER:PASS@HOST:PORT", "https": "http://USER:PASS@HOST:PORT"}

    # Определите поисковый запрос
    search_query = "puppies"

    # Отправьте GET-запрос на страницу поиска изображений Yahoo
    response = requests.get(
        url=f"https://images.search.yahoo.com/search/images?p={search_query}",
        headers=headers,
        proxies=proxies,
        verify=False
    )

    # Парсинг HTML-ответа
    parser = fromstring(response.text)

    # Извлеките URL изображений с помощью XPath
    images_urls = parser.xpath("//li[contains(@id, 'resitem-')]/a//@src")

    # Скачайте каждое изображение и сохраните его в файл
    for count, url in enumerate(images_urls):
        response = requests.get(url=url, headers=headers, proxies=proxies, verify=False)
        download_file(count, response)


if __name__ == "__main__":
    main()

Скрапинг изображений из результатов поиска Yahoo Images с помощью Python представляет собой мощный метод автоматизации сбора визуальных данных. Применение библиотеки Requests позволяет эффективно отправлять HTTP-запросы, а lxml упрощает парсинг HTML, обеспечивая возможность извлекать URL-адреса изображений. Использование прокси важно для обеспечения анонимности и предотвращения блокировки IP-адреса, что особенно актуально при массовом сборе данных. Таким образом, не только расширяются возможности по обработке и анализу данных, но и повышается надежность и эффективность скрапинговых процессов.

Комментарии:

0 комментариев