Многопоточность с Selenium с использованием Python и Telpot

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

Этот код всего лишь небольшая часть, но он должен помочь мне использовать многопоточность с селеном.

class MessageCounter(telepot.helper.ChatHandler):
    def __init__(self, *args, **kwargs):
        super(MessageCounter, self).__init__(*args, **kwargs)

    def on_chat_message(self, msg):
        content_type, chat_type, chat_id = telepot.glance(msg)
        chat_id = str(chat_id)

        browser = browserSelenium.start_browser(chat_id)
        userIsLogged = igLogin.checkAlreadyLoggedIn(browser, chat_id)
        print(userIsLogged)

TOKEN = "***"

bot = telepot.DelegatorBot(TOKEN, [
    pave_event_space()(
        per_chat_id(), create_open, MessageCounter, timeout=10),
])
MessageLoop(bot).run_as_thread()

while 1:
    time.sleep(10)

когда бот получает какое-либо сообщение, он запускает сеанс селена, вызывая эту функцию:

def start_browser(chat_id):
    global browser

    try:
        browser.get('https://www.google.com')
        #igLogin.checkAlreadyLoggedIn(browser)
        #links = telegram.getLinks(24)
        #instagramLikes(browser, links)

    except Exception as e:
        print("type error: " + str(e))
        print('No such session! starting webDivers!')
        sleep(3)

        # CLIENT CONNECTION !!
        chrome_options = Options()
        chrome_options.add_argument('user-data-dir=/home/ale/botTelegram/users/'+ chat_id +'/cookies')
        chrome_options.add_argument('--no-sandbox')
        chrome_options.add_argument('--lang=en')
        print("Starting WebDrivers")
        browser = webdriver.Chrome(options=chrome_options)

        start_browser(chat_id)

    return browser

а затем этот проверяет, зарегистрирован ли пользователь:

def checkAlreadyLoggedIn(browser, chat_id):
    browser.get('https://www.instagram.com/instagram/')
    try:
        WebDriverWait(browser, 5).until(EC.element_to_be_clickable(
            (By.XPATH, instagramClicks.buttonGoToProfile))).click()
        print('User already Logged')
        return True
    except:
        print('User not Logged')
        userLogged = login(browser, chat_id)
        return userLogged

и если пользователь не вошел в систему, попробуйте войти в систему с именем пользователя и паролем

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

Я имею в виду, что, например, одно окно остается над страницей google, а затем другое окно получает команду дважды, поэтому, даже когда ему нужно написать имя пользователя, оно пишет имя пользователя два раза.

Как я могу взаимодействовать с несколькими сеансами?

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

pguardiario 17.03.2019 04:07
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
429
1

Ответы 1

WebDriver is not thread-safe. Having said that, if you can serialise access to the underlying driver instance, you can share a reference in more than one thread. This is not advisable. But you can always instantiate one WebDriver instance for each thread.

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

Теперь разные потоки можно запускать на одном и том же Вебдрайвер, но тогда результаты тестов будут не такими, как вы ожидаете. Причина в том, что когда вы используете многопоточность для запуска разных тестов на разных вкладках/окнах, требуется немного кодирования безопасности потоков, иначе действия, которые вы будете выполнять, например click() или send_keys(), перейдут на открытую вкладку/окно, которое в настоящее время имеет фокус независимо от нить, который вы ожидаете запустить. По сути, это означает, что все тесты будут выполняться одновременно на одной и той же вкладке/окне с фокус, но нет на предполагаемой вкладке/окне.


Ссылка

Вы можете найти соответствующее подробное обсуждение в:

Другие вопросы по теме