@ubirust

Selenium при парсинге Авито выдает разный результат (блок по ip), в чем дело?

При парсинге Авито возникает не понятная ситуация. Когда я на сервере запускаю отдельно конкретный скрипт:
через python generate_avito.py, то у меня скрипт отрабатывает правильно.
65757dc732985919981284.jpeg
НО! Когда же этот скрипт (функция) срабатывает непосредственно в работе моего парсера, то у меня возникает блок по IP.
65757d9dbc247672033127.jpeg
Пробовал по разному запускать. И через thread и через Celery уже настроил задачу.

Вкратце, это функция генерит из обычной категорийно ссылки в ссылку api.

Я не понимаю в чем дело. Как может один и тот же скрипт работать по разному?

Это один и тот же скрипт. Под отдельным запуском я подразумеваю, когда скрипт запускается так: python generate_avito.py, просто через консоль. И всё работает отлично.

В работе, это когда происходит запуск через телеграм бот. Когда пользователь нажимает определенную кнопку в боте, то создается новый поток, в котором этот скрипт выполняется. И в этом случае в большинстве случаев возникают проблемы (иногда тоже получается без блока пройти, но очень редко).

Но я же пробовал скрипт тоже отдельно запускать через поток (threads), добавил threads в generate_avito.py и запустил через python generate_avito.py. Всё работает.

Далее я подумал, может быть дело в оболочке aiogram, как-то конфликтует.

Попробовал подключить Celery, чтобы этот скрипт не имел никакого значения к боту. Это отдельный python процесс. Но даже так в большинстве случаев выходит блок по ip.

Я вообще не понимаю как это возможно.

При этом запускал для теста ОДНОВРЕМЕННО через python generate_avito.py и в тоже время этот же скрипт как задачу в Celery.

В первом случае всё срабатывает, во втором выходит блок.

И мне кажется, что когда запуск идет отдельно, то скрипт выполняется и полностью останавливается.

А когда этот скрипт "в работе" как будто бы используется всегда один и тот же экземпляр драйвера. Либо есть какие-то ограничения, которых нет при запуске этого скрипта отдельно. Мб при запуске скрипта отдельно используются все ресурсы, а когда через Celery, то не все и Авито это видит и считает подозрительным. Это мои догадки.

Я пробовал и прокси подключать. Всё тоже самое, отдельно скрипт работает правильно, в ином случае выходит блок по ip.

В чем может быть дело?

Вот сам скрипт:
def generate_avito_data(link_avito, user_id):
    path = '.....' # здесь путь до driver, он заполнен у меня, не душните
    print('Код здесь')
    options = webdriver.ChromeOptions()
    options.binary_location = "/home/..."  # здесь путь до chrome
    user_agents = [
    "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1",
    "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-G973F) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/15.0 Chrome/90.0.4430.82 Mobile Safari/537.36",
    "Mozilla/5.0 (Linux; Android 11; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36",
    "Mozilla/5.0 (Linux; Android 11; IN2013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.105 Mobile Safari/537.36",
    "Mozilla/5.0 (Linux; Android 9; ELE-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36",
    "Mozilla/5.0 (Linux; U; Android 10; ru-ru; MI 9 Build/QKQ1.190825.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.157 Mobile Safari/537.36",
    "Mozilla/5.0 (Linux; Android 10; Xperia 1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.105 Mobile Safari/537.36",
    "Mozilla/5.0 (Linux; Android 9; LM-G710) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36"
    ]
    random_user_agent = random.choice(user_agents)
    options.add_argument(f'--user-agent={random_user_agent}')   
    # доп. настройки
        # Установите желаемые размеры окна
    desired_width = 1920
    desired_height = 1080
    options.add_argument(f'--window-size={desired_width},{desired_height}')
    options.add_argument("--headless")  # Запуск Chrome в headless режиме (без графического интерфейса)
    options.add_argument("--disable-extensions")
    options.add_argument('--disable-application-cache')
    options.add_argument('--disable-gpu')
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-setuid-sandbox")
    options.add_argument("--disable-dev-shm-usage")
    options.add_argument("--disable-popup-blocking")  # Отключение блокировки всплывающих окон
    options.add_argument("--disable-geolocation")  # Отключение геолокации
    options.add_argument("--disable-logging")  # Отключение журналирования
    options.add_argument("--disable-crash-reporter")  # Отключение отчетов об ошибках
    options.add_argument("--disable-default-apps")  # Отключение стандартных приложений

    # Отключение автоматического управления браузером Selenium
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option("useAutomationExtension", False)


    #web = "https://m.avito.ru/moskva/kvartiry/sdam/na_dlitelnyy_srok-ASgBAgICAkSSA8gQ8AeQUg?radius=0&s=104&user=1&presentationType=serp"
    web = link_avito
    logging.info(f"Ссылка web:{web}")

    
    driver = webdriver.Chrome(options=options, service=webdriver.chrome.service.Service(path))
    api_link = None # добавил для повторного запроса
    attempt_count = 0  # Счетчик попыток
    while api_link is None and attempt_count < 5:  # Проверяем, что api_link None и количество попыток < 5
        driver.get(web)
        print(id(driver))        
        try:
            # ждем появления кнопки
            print("Ждем появления первой кнопки")
            driver.save_screenshot('screenone.png')
            button = WebDriverWait(driver, 10).until(
                EC.presence_of_element_located(
                    (By.XPATH, '//*[@id="app"]/div/div[1]/div/div/div[1]/div[2]/div[1]/div[2]/button[2]'))
            )
            button.click()
            # ждем появления второй кнопки
            print("Ждем появления второй кнопки")
            time.sleep(5)
            button2 = WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, 'button[data-marker="search-form/apply"]'))
            )
            driver.save_screenshot('screentwo.png')
            button2.click()
            time.sleep(3)
            print("Вторая кнопка нашлась")
            # driver.refresh()
            # time.sleep(2)
            api_link = None
            for entry in driver.execute_script("return window.performance.getEntries()"):
                if 'api/11/items' in entry['name']:
                    if 'page=1' in entry['name']:
                        api_link = entry['name']
                        to_bd(user_id, api_link, link_avito)
                        break
                    elif 'lastStamp' in entry['name'] and 'display' in entry['name'] and 'limit' in entry['name']:
                        api_link = entry['name']
                        to_bd(user_id, api_link, link_avito)
                        break
        except TimeoutException:
            logging.info(f"Не удалось найти элемент. Увеличьте время ожидания или проверьте селектор. Ошибка у {user_id}")
            attempt_count += 1  # Увеличиваем счетчик попыток
            continue
        except selenium.common.exceptions.ElementClickInterceptedException:
            continue

    if attempt_count == 5:  # Если было сделано 5 попыток
        api_link = 'не сгенерировалась'
        to_bd(user_id, api_link, link_avito)

    # Браузер будет закрыт только после завершения цикла
    driver.quit()

    print(api_link)
    return api_link

link_avito = 'https://www.avito.ru/tyumenskaya_oblast/kvartiry/prodam/vtorichka-ASgBAgICAkSSA8YQ5geMUg?f=ASgBAgICA0SSA8YQ5geMUpC~DZauNQ&presentationType=serp&s=104'
user_id = 1
generate_avito_data(link_avito, user_id)
  • Вопрос задан
  • 218 просмотров
Пригласить эксперта
Ответы на вопрос 1
@rPman
Добавь логирование в свой скрипт, может ты его дважды запускаешь!?

Попробуй так, твой скрипт доделал до работы в режиме ожидания заданий, выполнения и сохранения результата, а телеграм пусть работает с ним через создания задания и ожидание результата.

Задания можно хранить в базе данных а можно просто на файлах сколхозить, по файлу на задание
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы