← Назад к вопросам

Как реализуешь веб парсинг?

2.0 Middle🔥 131 комментариев
#Python Core#REST API и HTTP#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Веб парсинг в Python

Основные подходы

Веб парсинг — это извлечение данных из HTML/XML страниц. Существует несколько подходов в зависимости от сложности и характера сайта.

1. Статический парсинг с BeautifulSoup (простые сайты)

Для статических сайтов (HTML генерируется на сервере) используем BeautifulSoup:

import requests
from bs4 import BeautifulSoup

# Получаем HTML
response = requests.get("https://example.com")
html = response.text

# Парсим HTML
soup = BeautifulSoup(html, "html.parser")

# Находим элементы по селектору
title = soup.find("h1", class_="title").text
paragraphs = soup.find_all("p")

# CSS селекторы
links = soup.select("a.external")
for link in links:
    href = link.get("href")
    text = link.text
    print(f"{text}: {href}")

# Навигация по дереву
parent = soup.find("div", class_="container")
children = parent.find_all(recursive=False)  # Только прямые потомки

2. Парсинг динамических сайтов с Selenium

Для сайтов, которые используют JavaScript для загрузки данных:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup

# Инициализируем браузер
driver = webdriver.Chrome()
driver.get("https://example.com")

# Ждём загрузки элемента
wait = WebDriverWait(driver, 10)
element = wait.until(
    EC.presence_of_all_elements_located((By.CLASS_NAME, "item"))
)

# Получаем отрендереный HTML
html = driver.page_source
soup = BeautifulSoup(html, "html.parser")

# Закрываем браузер
driver.quit()

3. Асинхронный парсинг с aiohttp и Playwright

Для больших объемов данных используем асинхронность:

import asyncio
import aiohttp
from bs4 import BeautifulSoup

async def parse_page(session, url):
    async with session.get(url) as response:
        html = await response.text()
        soup = BeautifulSoup(html, "html.parser")
        return soup.find_all("a")

async def main():
    urls = [
        "https://example.com/page1",
        "https://example.com/page2",
        "https://example.com/page3",
    ]
    
    async with aiohttp.ClientSession() as session:
        tasks = [parse_page(session, url) for url in urls]
        results = await asyncio.gather(*tasks)
        
        for links in results:
            for link in links:
                print(link.get("href"))

asyncio.run(main())

4. API подход (лучший способ)

Если сайт имеет API — используйте его вместо парсинга:

import requests

# Многие сайты имеют непубличные API
response = requests.get(
    "https://api.example.com/items",
    params={"page": 1, "limit": 50},
    headers={"Authorization": "Bearer token"}
)

data = response.json()
for item in data["items"]:
    print(item["title"], item["price"])

5. Полный пример с обработкой ошибок

import requests
from bs4 import BeautifulSoup
import logging
from urllib.parse import urljoin

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def scrape_site(base_url, max_pages=5):
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
    }
    
    articles = []
    
    for page in range(1, max_pages + 1):
        try:
            url = f"{base_url}?page={page}"
            logger.info(f"Парсим: {url}")
            
            response = requests.get(url, headers=headers, timeout=10)
            response.raise_for_status()  # Проверяем статус
            
            soup = BeautifulSoup(response.text, "html.parser")
            items = soup.find_all("article")
            
            if not items:
                logger.warning("Статей не найдено")
                break
            
            for item in items:
                title = item.find("h2")
                link = item.find("a")
                
                if title and link:
                    articles.append({
                        "title": title.text.strip(),
                        "url": urljoin(base_url, link.get("href", "")),
                        "href": link.get("href", "")
                    })
        
        except requests.RequestException as e:
            logger.error(f"Ошибка при запросе: {e}")
            break
        except Exception as e:
            logger.error(f"Ошибка парсинга: {e}")
    
    return articles

# Использование
articles = scrape_site("https://example.com", max_pages=3)
for article in articles:
    print(f"{article[\"title\"]}: {article[\"url\"]}")

Лучшие практики

  1. Уважайте robots.txt и Terms of Service — проверьте, разрешен ли парсинг
  2. Используйте User-Agent — некоторые сайты блокируют скрипты
  3. Добавляйте задержки между запросами — не перегружайте сервер
  4. Кэшируйте данные — не парсьте одно и то же дважды
  5. Обрабатывайте ошибки — сеть может быть нестабильна
  6. Логируйте процесс — для отладки и мониторинга
  7. Используйте сессии — для переиспользования соединений

Инструменты

  • BeautifulSoup — парсинг HTML/XML
  • Requests — синхронные HTTP запросы
  • aiohttp — асинхронные HTTP запросы
  • Selenium — для JavaScript-heavy сайтов
  • Playwright — современная альтернатива Selenium
  • Scrapy — фреймворк для крупных проектов парсинга
  • Regex — простая текстовая обработка (осторожнее)

Выбор инструмента зависит от сложности сайта и объема данных.

Как реализуешь веб парсинг? | PrepBro