Перейти к содержимому

Практическое занятие 6: Первый веб-скрапер

Создать первый веб-скрапер для сбора данных с веб-страниц и сохранения их в формате JSON.

Виртуальное окружение позволяет изолировать зависимости проекта от системных зависимостей Python.

Окно терминала
# Создание виртуального окружения
python -m venv venv
# или
python3 -m venv venv

Windows:

Окно терминала
venv\Scripts\activate

macOS/Linux:

Окно терминала
source venv/bin/activate

После активации в начале командной строки появится (venv).

Окно терминала
deactivate

Библиотека requests используется для выполнения HTTP-запросов.

Окно терминала
pip install requests

Библиотека BeautifulSoup (из пакета beautifulsoup4) используется для парсинга HTML.

Окно терминала
pip install beautifulsoup4

Сохраните список установленных библиотек в файл requirements.txt:

Окно терминала
pip freeze > requirements.txt

Установка зависимостей из файла:

Окно терминала
pip install -r requirements.txt

Создайте файл scraper.py:

import requests
from bs4 import BeautifulSoup
# URL для скрапинга
url = "https://example.com"
# Выполнение GET-запроса
response = requests.get(url)
# Проверка успешности запроса
if response.status_code == 200:
print("Успешно подключились к странице")
print(f"Код ответа: {response.status_code}")
else:
print("Ошибка при подключении")
print(f"Код ответа: {response.status_code}")
import requests
from bs4 import BeautifulSoup
url = "https://example.com"
response = requests.get(url)
# Парсинг HTML
soup = BeautifulSoup(response.text, "html.parser")
# Вывод заголовка страницы
title = soup.title
print(f"Заголовок страницы: {title.text}")
# Вывод всех ссылок
links = soup.find_all("a")
print(f"\nНайдено ссылок: {len(links)}")
for link in links[:5]: # Первые 5 ссылок
href = link.get("href")
text = link.text.strip()
print(f"{text}: {href}")
import requests
from bs4 import BeautifulSoup
url = "https://example.com"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
# Поиск элемента по тегу
h1 = soup.find("h1")
if h1:
print(f"H1: {h1.text}")
# Поиск по id
element = soup.find(id="content")
if element:
print("Элемент с id='content' найден")
# Поиск по классу
elements = soup.find_all(class_="example")
for elem in elements:
print(f"Элемент с классом 'example': {elem.text}")
# Комбинированный поиск
divs = soup.find_all("div", class_="container")
for div in divs[:3]:
print(f"Div с классом 'container': {div.text.strip()}")
import requests
from bs4 import BeautifulSoup
url = "https://example.com"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
# Получение всех ссылок
links = soup.find_all("a")
data = []
for link in links:
href = link.get("href")
text = link.text.strip()
title = link.get("title", "")
data.append({
"текст": text,
"ссылка": href,
"заголовок": title
})
print(f"Собрано {len(data)} ссылок")
import json
data = {
"имя": "Анна",
"возраст": 25,
"город": "Москва"
}
# Сохранение в JSON файл
with open("data.json", "w", encoding="utf-8") as file:
json.dump(data, file, ensure_ascii=False, indent=4)
print("Данные сохранены в data.json")
import json
# Чтение из JSON файла
with open("data.json", "r", encoding="utf-8") as file:
data = json.load(file)
print(data)

Создайте файл advanced_scraper.py:

import requests
from bs4 import BeautifulSoup
import json
def scrape_website(url):
"""Собирает данные с веб-сайта"""
response = requests.get(url)
if response.status_code != 200:
print(f"Ошибка: код ответа {response.status_code}")
return None
soup = BeautifulSoup(response.text, "html.parser")
# Сбор заголовка
title = soup.title.text.strip() if soup.title else "Без заголовка"
# Сбор ссылок
links = []
for link in soup.find_all("a"):
href = link.get("href")
text = link.text.strip()
if href and text:
links.append({
"текст": text,
"ссылка": href
})
# Сбор изображений
images = []
for img in soup.find_all("img"):
src = img.get("src")
alt = img.get("alt", "")
if src:
images.append({
"источник": src,
"описание": alt
})
return {
"url": url,
"заголовок": title,
"ссылок": len(links),
"ссылки": links[:10], # Первые 10 ссылок
"изображений": len(images),
"изображения": images[:5] # Первые 5 изображений
}
def save_to_json(data, filename):
"""Сохраняет данные в JSON файл"""
with open(filename, "w", encoding="utf-8") as file:
json.dump(data, file, ensure_ascii=False, indent=4)
print(f"Данные сохранены в {filename}")
# Основной код
if __name__ == "__main__":
url = "https://example.com"
print(f"Скрапинг: {url}")
data = scrape_website(url)
if data:
print(f"Заголовок: {data['заголовок']}")
print(f"Найдено ссылок: {data['ссылок']}")
print(f"Найдено изображений: {data['изображений']}")
save_to_json(data, "scraped_data.json")
import requests
from requests.exceptions import RequestException
url = "https://example.com"
try:
response = requests.get(url, timeout=10)
response.raise_for_status() # Проверка на ошибки HTTP
print("Успешный запрос")
print(f"Размер страницы: {len(response.text)} байт")
except RequestException as e:
print(f"Ошибка запроса: {e}")
except Exception as e:
print(f"Неожиданная ошибка: {e}")
import requests
url = "https://example.com"
# Заголовки для имитации браузера
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7"
}
response = requests.get(url, headers=headers)
print(f"Статус: {response.status_code}")
  1. Создайте скрапер, который собирает заголовки (h1, h2, h3) с выбранной вами веб-страницы.

  2. Напишите скрапер, который собирает все таблицы с веб-страницы и сохраняет их данные в JSON.

  3. Создайте функцию для сохранения результатов скрапинга с автоматическим именованием файла (например, data_2024-03-07.json).

  4. Реализуйте обработку ошибок для всех возможных ситуаций (ошибка сети, ошибка парсинга, ошибка записи файла).

  5. Добавьте логирование для отслеживания процесса скрапинга.

import requests
from bs4 import BeautifulSoup
import json
def scrape_headers(url):
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
headers = []
for level in ["h1", "h2", "h3"]:
for header in soup.find_all(level):
headers.append({
"уровень": level,
"текст": header.text.strip()
})
return headers
url = "https://example.com"
headers = scrape_headers(url)
for header in headers:
print(f"{header['уровень']}: {header['текст']}")
# Сохранение
with open("headers.json", "w", encoding="utf-8") as file:
json.dump(headers, file, ensure_ascii=False, indent=4)

На следующем занятии мы изучим работу с базами данных SQLite и сохранение данных в таблицы.