Привет! Сегодня поговорим о том, как парсить сайты, которые ведут себя как капризные подростки — постоянно меняются, загружают контент через JavaScript и вообще не хотят отдавать данные просто так. Но мы-то знаем, как с ними договориться! 🚀
Почему обычный requests не работает?
Знакомо? Открываешь сайт в браузере — всё видно. Пытаешься спарсить через requests — получаешь пустую страницу или HTML без нужных данных. В чём подвох?
Дело в том, что многие современные сайты используют JavaScript для динамической загрузки контента. Когда ты делаешь обычный GET-запрос, сервер отдаёт только "скелет" страницы, а весь контент подгружается потом через JS. Вот тут-то и нужен Selenium — он умеет управлять настоящим браузером!
Устанавливаем всё необходимое
Для начала установим Selenium и драйвер для браузера. Я рекомендую Chrome, но можно и Firefox — дело вкуса.
# Установка через pip
pip install selenium
# Для автоматического управления драйверами
pip install webdriver-manager
Первый скрипт: "Привет, мир!" парсинга
Давай напишем простой скрипт, который откроет страницу и подождёт, пока загрузится контент:
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 webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
import time
# Настройка драйвера (webdriver-manager сам скачает нужную версию)
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
try:
# Открываем страницу
driver.get("https://example.com")
# Ждём, пока загрузится нужный элемент (максимум 10 секунд)
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "h1"))
)
# Получаем текст
print(element.text)
finally:
driver.quit() # Важно! Закрываем браузер
Ждём, ждём, ждём... Или как не сойти с ума
Самая частая ошибка новичков — пытаться сразу получить данные, не дождавшись загрузки. Selenium работает быстрее, чем JavaScript на странице, поэтому нужно использовать ожидания (waits).
# Плохо: сразу пытаемся получить элемент
title = driver.find_element(By.TAG_NAME, "h1") # Может упасть!
# Хорошо: ждём появления элемента
title = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "h1"))
)
Реальный пример: парсим новости
Давай напишем скрипт, который парсит заголовки новостей с сайта, где контент загружается динамически:
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 webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
try:
driver.get("https://example-news-site.com")
# Ждём загрузки списка новостей
WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.CLASS_NAME, "news-item"))
)
# Прокручиваем страницу вниз, чтобы загрузились все новости
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(2) # Даём время на подгрузку
# Находим все заголовки
news_items = driver.find_elements(By.CLASS_NAME, "news-item")
for item in news_items:
title = item.find_element(By.TAG_NAME, "h2").text
link = item.find_element(By.TAG_NAME, "a").get_attribute("href")
print(f"{title}: {link}")
finally:
driver.quit()
Полезные фишки
1. Headless режим (без окна браузера)
Если не хочешь видеть, как открывается браузер (и работать быстрее):
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless') # Работает без окна
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome(service=service, options=options)
2. Ожидание загрузки JavaScript
Иногда нужно дождаться, пока JavaScript полностью выполнится:
# Ждём, пока document.readyState станет 'complete'
WebDriverWait(driver, 10).until(
lambda d: d.execute_script('return document.readyState') == 'complete'
)
3. Обработка ошибок
Всегда обрабатывай исключения — сайты могут быть недоступны или изменить структуру:
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "content"))
)
except TimeoutException:
print("Элемент не загрузился за 10 секунд")
except Exception as e:
print(f"Что-то пошло не так: {e}")
Итоги
Selenium — это мощный инструмент для парсинга динамических сайтов. Главное помнить:
- Всегда используй ожидания (waits) вместо
time.sleep() - Закрывай браузер через
driver.quit() - Обрабатывай исключения
- Используй headless режим для продакшена
Удачи в парсинге! Если что-то не работает — не расстраивайся, это нормально. Даже опытные разработчики тратят часы на отладку скриптов. Главное — не сдаваться! 💪