Собесов

Сценарий: скрейпинг таблицы с веб-страницы для еженедельного отчёта

PythonJSON и веб-скрейпингСредняяMiddle

Условие

На сайте партнёра еженедельно публикуется HTML-таблица с курсами товаров (без API). Нужно автоматизировать сбор и сохранение в CSV.

Решение

Быстрый путь — pandas.read_html

import pandas as pd
 
tables = pd.read_html('https://partner.example/prices', encoding='utf-8')
df = tables[0]   # обычно нужная — первая
df.to_csv('prices.csv', index=False)

Работает, если на странице есть <table> и она статичная.

Когда нужен requests + BeautifulSoup

Если таблица — не настоящий <table>, а сетка из <div>:

import requests
from bs4 import BeautifulSoup
 
resp = requests.get(
    'https://partner.example/prices',
    headers={'User-Agent': 'Mozilla/5.0 ...'},
    timeout=10,
)
resp.raise_for_status()
 
soup = BeautifulSoup(resp.text, 'lxml')
 
rows = []
for row in soup.select('div.price-row'):
    rows.append({
        'name': row.select_one('.name').get_text(strip=True),
        'price': row.select_one('.price').get_text(strip=True),
    })
 
df = pd.DataFrame(rows)

Если контент JS-рендерится

requests получит «болванку» без данных — нужен 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://partner.example/prices')
    page.wait_for_selector('.price-row')
    html = page.content()
    browser.close()

Хорошие манеры

  • robots.txt уважать.
  • User-Agent указывать честный.
  • Между запросами — time.sleep(1).
  • Кешировать HTML в файл, чтобы не дёргать сервер при отладке.

Подводные камни

  1. Сайт может вернуть капчу/403 при частых запросах — нужна retry-стратегия (tenacity) с backoff.
  2. Кодировка не всегда UTF-8: resp.encoding = resp.apparent_encoding.
  3. Структура HTML может меняться без предупреждения — селекторы хрупкие. Покрывать тестами «парсинг последней версии».
  4. read_html иногда возвращает несколько таблиц — индекс может «съехать» после редизайна.
  5. Скрейпинг данных без разрешения может нарушать ToS — уточнять с легал-командой.

Эталонный ответ

Сначала пробовать pd.read_html; если не подходит — requests + BeautifulSoup; для JS-рендера — Playwright. Уважать robots.txt, retry с backoff, проверять кодировку.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти