Корректные методы веб-скрейпинга
Соблюдение robots.txt, заголовки агента пользователя, задержки между запросами и кэширование.
«Корректные методы веб-скрейпинга» — бесплатный урок AI Agents на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Agents, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Agents содержит 4 уроков всего.
Почему важно собирать данные бережно
Сбор данных с веб-сайтов может перегружать серверы, нарушать условия использования и привести к блокировке IP-адреса Вашего агента. Ответственные инструменты сбора данных соблюдают ограничения частоты запросов, представляются и следуют правилам, опубликованным сайтами.
В этом уроке рассматриваются инструменты и методы этичного и устойчивого сбора данных.
Проверка robots.txt
Каждый веб-сайт может опубликовать файл robots.txt, указывающий, к каким путям автоматизированные агенты могут или не могут обращаться. Стандартная библиотека Python включает urllib.robotparser для разбора этого файла.
Всегда проверяйте robots.txt перед сбором данных с сайта.
import urllib.robotparser
rp = urllib.robotparser.RobotFileParser()
rp.set_url('https://example.com/robots.txt')
rp.read()
# Check if our bot can fetch a specific path
can_fetch = rp.can_fetch('MyAgent/1.0', 'https://example.com/public-data')
print(f'Can fetch: {can_fetch}') # True or False
cannot_fetch = rp.can_fetch('*', 'https://example.com/private/admin')
print(f'Admin allowed: {cannot_fetch}') # Often FalseНастройка информативного User-Agent
Заголовок User-Agent протокола идентифицирует отправителя запроса. Честное значение User-Agent позволяет администраторам сайта понять, что это за бот и как связаться с Вами при возникновении проблем. Маскировка под браузер для обхода блокировок вызывает этические вопросы.
import httpx
headers = {
# Honest, descriptive User-Agent
'User-Agent': 'MyResearchBot/1.0 (contact: me@example.com; purpose: academic research)'
}
response = httpx.get(
'https://example.com/data',
headers=headers,
timeout=10.0
)
print(response.status_code)Ограничение частоты с помощью time.sleep()
Отправка сотен запросов в секунду может перегрузить сервер и часто расценивается как атака типа «отказ в обслуживании». Добавляйте задержки между запросами с помощью time.sleep(). Используйте random.uniform(), чтобы задержка выглядела менее механической и больше напоминала действия человека.
import time
import random
import httpx
urls = [
'https://example.com/page/1',
'https://example.com/page/2',
'https://example.com/page/3'
]
for url in urls:
response = httpx.get(url, timeout=10.0)
print(f'Fetched {url}: {response.status_code}')
# Wait between 1 and 3 seconds before the next request
delay = random.uniform(1, 3)
print(f'Sleeping {delay:.1f}s...')
time.sleep(delay)Соблюдение заголовков Retry-After
Когда сервер отвечает кодом 429 Too Many Requests, он часто добавляет заголовок Retry-After, указывающий, сколько секунд нужно ждать. Ваш агент должен прочитать это значение и соблюдать его, а не повторять запрос немедленно.
import time
import httpx
def fetch_with_retry(url: str) -> httpx.Response:
while True:
response = httpx.get(url, timeout=10.0)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 5))
print(f'Rate limited. Waiting {retry_after}s...')
time.sleep(retry_after)
continue # retry
response.raise_for_status()
return responseКэширование ответов во избежание повторных запросов
Кэширование запросов автоматически сохраняет ответы веб-запросов на диске. Если Вашему агенту нужно несколько раз получить один и тот же адрес (например, во время разработки или повторных запусков), сохранённые ответы возвращаются мгновенно, без обращения к серверу.
# pip install requests-cache
import requests_cache
# Install the cache globally — cached responses expire after 1 hour
requests_cache.install_cache(
'agent_cache',
backend='sqlite',
expire_after=3600 # seconds
)
import requests
# First call: fetches from network and caches
response = requests.get('https://api.example.com/data')
print(response.from_cache) # False
# Second call: returns cached result instantly
response2 = requests.get('https://api.example.com/data')
print(response2.from_cache) # TrueРучное кэширование в файлах с помощью клиента для веб-запросов
Если Вы предпочитаете не использовать кэширование запросов, хорошо работает простой кэш на основе файлов. Сохраняйте ответы в файлах JSON, используя хеш адреса как ключ, и загружайте их повторно, если файл ещё достаточно свежий.
import hashlib
import json
import os
import time
import httpx
CACHE_DIR = '/tmp/agent_cache'
os.makedirs(CACHE_DIR, exist_ok=True)
def cached_get(url: str, ttl_seconds: int = 3600) -> dict:
key = hashlib.md5(url.encode()).hexdigest()
cache_file = os.path.join(CACHE_DIR, key + '.json')
if os.path.exists(cache_file):
age = time.time() - os.path.getmtime(cache_file)
if age < ttl_seconds:
with open(cache_file) as f:
return json.load(f)
response = httpx.get(url, timeout=10.0)
response.raise_for_status()
data = response.json()
with open(cache_file, 'w') as f:
json.dump(data, f)
return dataЧтение условий использования
Перед сбором данных с любого сайта прочитайте его условия использования. Во многих из них прямо запрещены автоматизированный доступ или коммерческое использование данных. Нарушение условий использования может привести к судебному разбирательству, а не только к блокировке IP-адреса.
Если существует официальный программный интерфейс, всегда предпочитайте его сбору HTML — он быстрее, стабильнее и безопаснее с юридической точки зрения.
Экспоненциальная задержка при ошибках
Если запрос завершился ошибкой, не повторяйте его немедленно. Используйте экспоненциальную задержку: подождите 1 секунду, затем 2 секунды, затем 4 секунды и так далее. Это не позволяет перегружать сервер, который уже испытывает трудности, и является профессиональным подходом для рабочих агентов.
import time
import httpx
def fetch_with_backoff(url: str, max_retries: int = 4) -> dict:
for attempt in range(max_retries):
try:
response = httpx.get(url, timeout=10.0)
response.raise_for_status()
return response.json()
except (httpx.HTTPStatusError, httpx.RequestError) as e:
if attempt == max_retries - 1:
raise
wait = 2 ** attempt # 1, 2, 4, 8 seconds
print(f'Attempt {attempt+1} failed: {e}. Retrying in {wait}s...')
time.sleep(wait)
return {}Сбор только необходимых данных
Снижайте нагрузку на сервер, загружая только то, что действительно нужно Вашему агенту. Не скачивайте целые страницы, если небольшой программный интерфейс возвращает те же данные. Используйте запросы HEAD, чтобы проверить, изменился ли ресурс, прежде чем загружать его содержимое полностью.
import httpx
def has_page_changed(url: str, last_etag: str = None) -> bool:
headers = {}
if last_etag:
headers['If-None-Match'] = last_etag
response = httpx.head(url, headers=headers, timeout=5.0)
if response.status_code == 304: # Not Modified
return False
new_etag = response.headers.get('ETag')
print(f'New ETag: {new_etag}')
return TrueКраткие правила бережного сбора данных
Краткий список проверок перед тем, как Ваш агент начнёт собирать данные с сайта:
- Проверьте
robots.txtи соблюдайте правила запрета доступа - Установите честный и информативный
User-Agent - Добавляйте случайные задержки между запросами (
time.sleep(random.uniform(1,3))) - Соблюдайте заголовки
Retry-Afterв ответах 429 - Кэшируйте ответы, чтобы избежать повторных запросов
- Прочитайте условия использования сайта
- При наличии предпочитайте официальные программные интерфейсы сбору данных из HTML
Проверка знаний: бережный сбор данных
Проверьте, насколько хорошо Вы понимаете этичные и бережные методы сбора данных.
Итоги: практика бережного сбора данных
Теперь у Вас есть полный набор инструментов для ответственного сбора данных:
robotparserдля проверки разрешённого доступа- Информативные заголовки
User-Agent, идентифицирующие Вашего бота time.sleep(random.uniform(1,3))между запросамиrequests-cacheили ручное кэширование для предотвращения повторных запросов- Экспоненциальная задержка для обработки ошибок
- Правовая осведомлённость: всегда проверяйте условия использования
Ответственный сбор данных делает веб здоровее и позволяет Вашим агентам работать без блокировок.
Часто задаваемые вопросы
Урок «Корректные методы веб-скрейпинга» бесплатный?
Да — полный текст урока «Корректные методы веб-скрейпинга» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Agents, подпишись на CoddyKit PRO. Курс AI Agents содержит 4 уроков всего.
Чему я научусь в уроке «Корректные методы веб-скрейпинга»?
Соблюдение robots.txt, заголовки агента пользователя, задержки между запросами и кэширование. Ты практикуешь AI Agents с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать AI Agents?
Предыдущий опыт не требуется. AI Agents на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Корректные методы веб-скрейпинга»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке AI Agents?
Да. Каждый урок AI Agents включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- HTTP-клиенты для агентов: httpx и requests
- Разбор HTML с помощью BeautifulSoup
- Обработка разбиения на страницы и динамического содержимого
- Корректные методы веб-скрейпинга