Python Многопоточность Selenium Chrome Экземпляры - PullRequest
2 голосов
/ 01 мая 2020

Я пишу код в python, который открывает 20 потоков (каждый проходит через одну и ту же функцию), каждый поток открывает отдельный экземпляр браузера селена, каждому потоку присваивается отдельный URL-адрес в качестве параметра. Итак, у меня открыто 20 браузеров с селеном, каждый на 20 разных URL. Это прекрасно работает, пока я не добавлю параметр user-data-dir selenium chrome для каждого браузера в функции потока. Я делаю это, потому что я хочу, чтобы браузер селена открывался на том же значке chrome на панели задач (чтобы он не мешал пользователю визуально). Но проблема в том, что теперь у меня открыто 20 различных браузеров селена, но все команды потоков выполняются только на одном (этот единственный браузер переходит на все 20 заданных URL, оставляя остальные 19, в основном, ничего не делая). Как я могу решить эту проблему? Могу ли я по-разному смешивать браузеры селена в одном значке chrome? Это очень странно, и я искал это несколько дней, но, похоже, ничто не решило мою проблему. Я действительно хочу решить эту проблему, и если кто-нибудь знает, в чем может быть проблема, я был бы очень признателен за помощь. (Надеюсь, вы понимаете вопрос.)

РЕДАКТИРОВАТЬ : Поскольку { ссылка } упоминается в комментариях, я попытался использовать ProcessPoolExecutor, но это не помогло Потому что моя программа также имеет приложение tkinter GUI, поэтому при реализации этого метода она зависает. Поэтому я решил, что мне следует использовать многопроцессорную программу basi c. Работало нормально: 20 драйверов открылись, с опцией user-data-dir, GUI не зависало. Но моя программа также содержит кнопку close_browser для каждого драйвера, которая закрывает указанный драйвер c. Проблема в том, что я не могу получить доступ к полю driver, которое инициируется после. Я надеюсь, что этот код объясняет мою проблему (Примечание: я сократил его до одного драйвера, чтобы избежать сложностей). Это код:

import tkinter as tk
import os
import time
import multiprocessing
import queue

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

class Browser():
    pass

def close_browser():
    print("Closing browser...")
    browser.driver.close()




def start_browser_process(browser):
    print("Starting browser...")
    browser.driver = webdriver.Chrome(ChromeDriverManager().install())

    while True:
        browser.driver.get(browser.url)
        time.sleep(5)

def start_browser():

    browser.process = multiprocessing.Process(target=start_browser_process, args=(browser,))
    browser.process.start()

if __name__=='__main__':

    browser = Browser()
    browser.url = 'https://facebook.com'


    root = tk.Tk()                    
    button_start_browser = tk.Button(root, command=start_browser, width=50, height=4, bg='red', text='Start Browser')
    button_start_browser.pack()

    button_close_browser = tk.Button(root, width=50, height=7, bg='red', command=close_browser, text='Close Browser')
    button_close_browser.pack()

    root.mainloop()

Итак, сначала я создаю экземпляр Browser, который пока что , имеет только одно поле (URL) и инициализирует приложение Tkinter GUI. Затем я нажимаю кнопку Start Browser, которая открывает для меня драйвер sh selenium на https://facebook.com, который продолжает вводить этот URL каждые 5 секунд, а также я назначаю новое поле экземпляру Browser: driver. Но затем, когда я нажимаю кнопку Close Browser, я хочу получить доступ к этому полю browser.driver, чтобы закрыть его, они выдают мне эту ошибку: AttributeError: 'Browser' object has no attribute 'driver'. Это означает, что я должен динамически разделять поле driver между процессами. Я попробовал это с Queue, но это все равно не сработало, так как python не позволяет передавать объекты очереди в качестве аргументов процесса. Как я могу разделить переменные между процессами, в этом случае? Есть ли другой способ? Я искал 4 дня, но так и не нашел ответа. Любой ответ высоко ценится. Если у вас есть вопросы по моей проблеме, пожалуйста, сообщите мне, чтобы я мог отредактировать вопрос.

...