Парсер на Selenium пропускает username и link_to_profile: причины и решение
При разработке скрипта для сбора данных с сайта sc2arcade.com вы столкнулись с проблемой: поля username и link_to_profile иногда остаются пустыми, хотя map_url добавляется всегда, а social_media - только при наличии. В этой статье мы подробно разберём причины такого поведения и предложим конкретные исправления.
Почему парсер пропускает username и link_to_profile?
Основная причина - использование блока try/except, который перехватывает любые исключения и присваивает полям пустые строки. Если на странице автора не находится элемент с селектором .h1.flex-grow-1.font-weight-regular или возникает ошибка при переходе по ссылке, скрипт молча заполняет данные пустышками. Также проблема может быть связана с неверными ожиданиями загрузки элементов или с динамической подгрузкой контента.
Основные ошибки в коде
- Глобальный except без логирования: вы не видите, какая именно ошибка произошла - отсутствие элемента, таймаут или проблема с навигацией.
- Дублирование кода: блоки для карт с кириллицей и латиницей практически идентичны, что усложняет поддержку.
- Неявное ожидание элементов:
presence_of_element_locatedне гарантирует, что элемент видим или кликабелен. - Сброс URL после каждой итерации: вы заново загружаете страницу списка, что может приводить к потере состояния.
Как исправить парсер, чтобы он гарантированно добавлял username и link_to_profile?
Для надёжного сбора данных используйте следующие подходы.
1. Логируйте исключения
Замените пустой except на конструкцию с выводом ошибки в консоль:
try:
username = driver.find_element(By.CSS_SELECTOR, '.h1.flex-grow-1.font-weight-regular').text
except Exception as e:
print(f'Ошибка получения username: {e}')
username = ''Это поможет понять, на каком этапе возникает проблема.
2. Используйте явные ожидания с условиями
Примените WebDriverWait с visibility_of_element_located для элементов, которые должны быть видны:
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
username_element = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, '.h1.flex-grow-1.font-weight-regular')))
username = username_element.text3. Проверяйте корректность селекторов
Убедитесь, что селектор .player-link > span действительно возвращает ссылку на профиль. Возможно, на странице автора он отсутствует для некоторых карт. В таком случае добавьте fallback-логику: если элемент не найден, пробуйте альтернативные селекторы или пропускайте карту.
4. Убедитесь, что страница автора загрузилась полностью
После перехода по author_name добавьте ожидание, что URL изменился и страница готова:
driver.get(author_name)
wait.until(lambda d: d.current_url != driver.current_url)Пример исправленного участка кода
Вместо дублирования блоков для кириллицы и латиницы, объедините логику:
def get_author_data(driver):
try:
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.player-link > span')))
author_href = driver.find_element(By.CSS_SELECTOR, '.player-link').get_attribute('href')
driver.get(author_href)
username = wait.until(EC.visibility_of_element_located(
(By.CSS_SELECTOR, '.h1.flex-grow-1.font-weight-regular'))).text
link_to_profile = driver.current_url
driver.back()
social_media = driver.find_element(
By.XPATH, './/*[@id="app"]/div/main/div/div/div/div[1]/div[1]/dl/dd[5]/a/span'
).text.lower()
return username, link_to_profile, social_media
except Exception as e:
print(f'Не удалось получить данные автора: {e}')
return '', '', ''Рекомендации по дальнейшей оптимизации
- Используйте
Setдля хранения уже обработанных карт, чтобы избежать дублирования. - Добавьте обработку пагинации: раскомментируйте блок с
next_page_buttonи настройте его правильно. - Замените
time.sleep(5)на динамические ожидания, чтобы ускорить работу. - Сохраняйте промежуточные результаты в Excel после каждой итерации, чтобы не терять данные при сбое.
Следуя этим советам, вы сможете исправить парсер и гарантированно получать все необходимые поля: username, link_to_profile, map_url и social_media.