Многопоточность с помощью Selenium с использованием Python и Telpot - PullRequest
1 голос
/ 16 марта 2019

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

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

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, а затем другое получает два раза команду, поэтому, даже если ему нужно написать имя пользователя, оно пишет имя пользователя два раза

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

1 Ответ

1 голос
/ 17 марта 2019

WebDriver не является поточно-ориентированным . Сказав это, если вы можете сериализовать доступ к базовому экземпляру драйвера, вы можете поделиться ссылкой более чем в одном потоке. Это не рекомендуется. Но вы всегда можете создать один экземпляр WebDriver для каждого потока.

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

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

...