Парсер на 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.text

    3. Проверяйте корректность селекторов

    Убедитесь, что селектор .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.

    Часто задаваемые вопросы