Я пишу свой первый телеграмм-бот, но теперь мне нужно одновременно обслуживать нескольких пользователей.
Этот код всего лишь небольшая часть, но он должен помочь мне использовать многопоточность с селеном.
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, а затем другое окно получает команду дважды, поэтому, даже когда ему нужно написать имя пользователя, оно пишет имя пользователя два раза.
Как я могу взаимодействовать с несколькими сеансами?





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(), перейдут на открытую вкладку/окно, которое в настоящее время имеет фокус независимо от нить, который вы ожидаете запустить. По сути, это означает, что все тесты будут выполняться одновременно на одной и той же вкладке/окне с фокус, но нет на предполагаемой вкладке/окне.
Вы можете найти соответствующее подробное обсуждение в:
Это похоже на то, что вы хотели бы запустить в браузере (который уже является асинхронным), но я не могу сказать, что вы пытаетесь здесь сделать.