Как спарсить картинку python

Как спарсить картинку python

Извлечение изображений с веб-страниц – задача, требующая понимания структуры HTML-документа и работы с HTTP-запросами. В Python для этого чаще всего применяются библиотеки requests и BeautifulSoup, а для загрузки файлов – shutil или aiohttp при асинхронном подходе.

Перед парсингом важно изучить DOM-структуру страницы через инструменты разработчика браузера. Изображения чаще всего находятся в тегах <img> с атрибутом src. Иногда ссылки на них подгружаются динамически через JavaScript, что требует применения Selenium или Playwright.

Надёжный парсинг невозможен без корректной обработки заголовков запроса. Многие сайты блокируют «пустые» user-agent’ы, поэтому необходимо указывать его явно. Также стоит учитывать возможные редиректы и коды ответа сервера, особенно 403 Forbidden и 429 Too Many Requests.

Для сохранения изображений рекомендуется использовать os.path.basename() для извлечения имени файла из URL, а затем записывать бинарные данные в файл через open(…, ‘wb’). Если необходимо скачать десятки или сотни изображений, лучше использовать асинхронную загрузку для повышения скорости и снижения нагрузки на сайт.

Выбор и установка библиотек для загрузки изображений

Выбор и установка библиотек для загрузки изображений

Для загрузки изображений с веб-сайтов в Python чаще всего используют библиотеки requests, aiohttp и httpx. Выбор зависит от требований к производительности и типу проекта.

requests – синхронная библиотека, подходящая для простых сценариев. Устанавливается командой pip install requests. Поддерживает cookies, редиректы и заголовки, легко сохраняет изображения через response.content.

aiohttp – асинхронный аналог, подходит для одновременной загрузки большого количества изображений. Установка: pip install aiohttp. Требует использования asyncio и асинхронного контекста. Существенно ускоряет парсинг при большом объёме данных.

httpx – гибрид синхронного и асинхронного клиента. Устанавливается через pip install httpx. Имеет современный API, совместим с asyncio и позволяет легко переключаться между режимами. Поддерживает HTTP/2, что важно для скорости при работе с CDN.

Дополнительно может потребоваться fake-useragent (pip install fake-useragent) для генерации случайных заголовков User-Agent при обходе защиты сайтов от парсинга. Для обработки ссылок удобна beautifulsoup4 (pip install beautifulsoup4), но она не участвует в самой загрузке изображений.

Для устойчивой работы используйте timeout и проверку кода ответа status_code перед сохранением файла. Это предотвращает сохранение HTML вместо изображений при ошибках запроса.

Извлечение URL-адресов изображений из HTML-кода страницы

Извлечение URL-адресов изображений из HTML-кода страницы

Для получения ссылок на изображения из HTML-разметки используйте библиотеку BeautifulSoup. Она позволяет точно находить теги <img> и извлекать значения атрибута src.

Перед парсингом загрузите страницу с помощью requests:


import requests
from bs4 import BeautifulSoup

url = "https://example.com"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")

image_tags = soup.find_all("img")
image_urls = [img.get("src") for img in image_tags if img.get("src")]

Если изображения загружаются с относительными путями, нормализуйте их через urllib.parse.urljoin:


from urllib.parse import urljoin

absolute_urls = [urljoin(url, img_url) for img_url in image_urls]

Фильтруйте нерелевантные данные, например, SVG или спрайты, проверяя расширение или шаблон ссылки:


filtered_urls = [u for u in absolute_urls if u.lower().endswith((".jpg", ".jpeg", ".png", ".gif", ".webp"))]

Избегайте использования регулярных выражений для парсинга HTML – они ненадёжны при вложенных структурах и изменениях DOM.

Обработка относительных и абсолютных путей к изображениям

Обработка относительных и абсолютных путей к изображениям

При парсинге изображений с HTML-страниц часто встречаются как абсолютные, так и относительные пути. Абсолютный путь начинается с протокола (http://, https://), тогда как относительный указывает на ресурс внутри текущего домена, например /images/logo.png.

  • Чтобы привести относительный путь к абсолютному, используйте urljoin из модуля urllib.parse:
from urllib.parse import urljoin
base_url = 'https://example.com'
relative_path = '/media/img.jpg'
absolute_url = urljoin(base_url, relative_path)
  • Для корректного формирования base_url извлекайте его из тега <base>, если он есть. При его отсутствии используйте URL страницы, с которой был получен HTML.
  • Не доверяйте внешнему виду ссылок: путь ../assets/img.png может указывать на родительский каталог. urljoin корректно обрабатывает такие случаи.
  • Перед скачиванием изображений проверяйте наличие схемы в URL. Если путь остался относительным, requests.get вызовет ошибку:
if not image_url.startswith(('http://', 'https://')):
image_url = urljoin(base_url, image_url)
  • При использовании библиотек вроде BeautifulSoup путь к изображению можно получить так:
img_src = soup.find('img')['src']
full_url = urljoin(base_url, img_src)
  • Избегайте использования os.path.join для работы с URL – он предназначен для файловых путей и не учитывает специфику URL-синтаксиса.

Загрузка изображений на диск с сохранением формата

Загрузка изображений на диск с сохранением формата

Для сохранения изображений с сайта в оригинальном формате необходимо учитывать тип контента, указанный в HTTP-заголовках ответа. Это позволяет избежать лишних преобразований и сохранять расширение файла точно таким, каким оно представлено на сервере.

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

import requests
import os
url = "https://example.com/image.jpg"
response = requests.get(url, stream=True)
if response.status_code == 200:
content_type = response.headers.get("Content-Type", "")
extension = content_type.split("/")[-1].split(";")[0]
filename = f"downloaded_image.{extension}"
with open(filename, "wb") as f:
for chunk in response.iter_content(1024):
f.write(chunk)

stream=True позволяет загружать большие файлы по частям без лишнего потребления памяти. Расширение определяется из Content-Type, что защищает от ошибок при сохранении файлов без расширения или с неверным форматом.

Если путь загрузки задан вручную, убедитесь, что директория существует:

directory = "images"
os.makedirs(directory, exist_ok=True)
filepath = os.path.join(directory, filename)

Файл сохраняется в указанную папку с оригинальным расширением, что упрощает последующую обработку или просмотр без необходимости в дополнительных преобразованиях или проверках формата.

Работа с изображениями, загружаемыми динамически через JavaScript

Работа с изображениями, загружаемыми динамически через JavaScript

Если изображения подгружаются с помощью JavaScript, стандартные библиотеки вроде requests и BeautifulSoup становятся бесполезными, так как они не исполняют JS-код. В этом случае необходимо использовать инструменты, способные работать с реальными браузерами.

Наиболее эффективный способ – использовать Selenium с драйвером Chrome или Firefox. Убедитесь, что установлены selenium и соответствующий веб-драйвер. Пример:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time
import requests
service = Service('path/to/chromedriver')
driver = webdriver.Chrome(service=service)
driver.get("https://example.com")
time.sleep(5)  # дождаться полной загрузки JS
images = driver.find_elements(By.TAG_NAME, "img")
urls = [img.get_attribute('src') for img in images if img.get_attribute('src')]
for i, url in enumerate(urls):
r = requests.get(url)
with open(f'image_{i}.jpg', 'wb') as f:
f.write(r.content)
driver.quit()

Если изображения загружаются по событию (например, скроллу), имитируйте его:

from selenium.webdriver.common.action_chains import ActionChains
element = driver.find_element(By.ID, "footer")
ActionChains(driver).move_to_element(element).perform()
time.sleep(3)

Альтернативный подход – анализировать сетевые запросы через DevTools Protocol с использованием undetected-chromedriver и перехватывать запросы к CDN, если изображения подгружаются асинхронно. Также можно использовать playwright – он быстрее и устойчивее, чем Selenium.

from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://example.com")
page.wait_for_timeout(5000)
img_urls = page.eval_on_selector_all("img", "elements => elements.map(e => e.src)")
for i, url in enumerate(img_urls):
r = requests.get(url)
with open(f'image_{i}.jpg', 'wb') as f:
f.write(r.content)
browser.close()

При работе с динамическими сайтами важно использовать инструменты, поддерживающие рендеринг DOM после выполнения JavaScript. Обход этого требования возможен только при наличии прямых API-запросов к источникам изображений.

Обход ограничений и защита от блокировок при парсинге

Парсинг сайтов сталкивается с множеством ограничений, направленных на защиту от злоупотреблений, таких как ограничения по количеству запросов, капчи и блокировки по IP. Чтобы эффективно обойти эти препятствия, необходимо использовать ряд методов и инструментов, которые помогут минимизировать риск блокировок и обеспечить стабильную работу парсера.

Вот несколько техник, которые можно применить для обхода ограничений и защиты от блокировок:

  • Использование прокси-серверов: Прокси помогают скрыть реальный IP-адрес и распределить нагрузку запросов через разные адреса. Это предотвращает блокировки по IP. Прокси можно использовать в ротации, чтобы эффективно маскировать источник запросов.
  • Ротация User-Agent: Частая смена User-Agent заголовка позволяет сделать запросы более разнообразными, что предотвращает блокировки, связанные с подозрением на использование автоматизированных инструментов. Библиотеки, такие как fake_useragent, позволяют легко генерировать случайные User-Agent строки.
  • Ожидание между запросами: Чрезмерно быстрые запросы к серверу могут вызвать подозрение. Рекомендуется внедрять случайные задержки между запросами с помощью функции time.sleep(), чтобы имитировать поведение реального пользователя.
  • Использование сессий: Важно поддерживать сессию с сервером через библиотеку requests, чтобы сохранить cookies и заголовки, необходимые для работы с сайтом. Это помогает избежать блокировок, вызванных изменением сессий между запросами.
  • Использование CAPTCHA-обходов: Некоторые сайты защищены капчей, которая блокирует автоматизированный доступ. В таких случаях можно использовать сервисы для обхода капчи, такие как 2Captcha, AntiCaptcha, которые автоматически решают капчи за деньги.
  • Периодический анализ блокировок: Необходимо отслеживать ответы сервера. Если сайт начинает активно блокировать запросы, стоит проанализировать причины блокировки и адаптировать стратегию, например, уменьшив частоту запросов или изменив IP через прокси.
  • Использование API, если доступно: Некоторые сайты предлагают API для получения данных. Вместо того, чтобы парсить HTML-код, гораздо эффективнее и безопаснее использовать официальные API, которые не ограничены такими строгими мерами защиты.

Правильное применение этих методов позволяет снизить вероятность блокировок и повысить устойчивость парсера к внешним ограничениям, обеспечив долгосрочную работу парсинга.

Вопрос-ответ:

Какие библиотеки Python могут помочь спарсить изображение с сайта?

Для парсинга изображений с веб-сайтов в Python часто используются библиотеки BeautifulSoup и Requests. BeautifulSoup позволяет извлекать данные с HTML-страниц, а Requests используется для отправки HTTP-запросов и получения изображений. Для работы с изображениями также можно использовать библиотеку Pillow для обработки и сохранения изображений после их скачивания.

Ссылка на основную публикацию