1

我正在编写我的第一个电报机器人,但现在我必须同时为多个用户提供服务。

这段代码只是一小部分,但它应该可以帮助我在 selenium 中使用多线程

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)

当机器人收到任何消息时,它会启动一个调用此函数的 selenium 会话:

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

如果用户未登录,则尝试使用用户名和密码登录用户

所以,基本上,当我用一个帐户在机器人上写东西时,一切都很好,但是如果我从两个不同的帐户写给机器人,它会打开两个浏览器,但它只控制一个。

我的意思是,例如,一个窗口保留在谷歌页面上,然后另一个窗口接收命令的两倍,所以,即使它必须写用户名,它也会写两次用户名

如何与多个会话进行交互?

4

1 回答 1

1

WebDriver 不是线程安全的。话虽如此,如果您可以序列化对底层驱动程序实例的访问,则可以在多个线程中共享一个引用。这是不可取的。但是您总是可以为每个线程实例化一个 WebDriver 实例。

理想情况下,线程安全问题不在您的代码中,而在实际的浏览器绑定中。他们都假设一次只会有一个命令(例如,像一个真实的用户)。但另一方面,您始终可以为每个线程实例化一个WebDriver实例,该实例将启动多个浏览选项卡/窗口。到目前为止,您的程序似乎很完美。

现在,不同的线程可以在同一个Webdriver上运行,但是测试的结果不会是你所期望的。背后的原因是,当您使用多线程在不同的选项卡/窗口上运行不同的测试时,需要一点线程安全编码,否则您将执行的操作就像click()send_keys()将转到当前打开的选项卡/窗口一样无论您希望运行的线程如何,都将成为焦点。这实质上意味着所有测试将在具有焦点不在预期的选项卡/窗口上的同一选项卡/窗口上同时运行。


参考

您可以在以下位置找到相关的详细讨论:

于 2019-03-16T21:43:11.043 回答