Я пишу код в Tkinter с кнопкой, которая запускает 6 экземпляров chrome селена, каждый из которых имеет свой URL. Цель состоит в том, чтобы драйверы запускались как можно быстрее, и каждый экземпляр драйвера должен повторно вводить свой указанный c url (refre sh) каждые 4 секунды. Каждый драйвер связан с классом, который содержит требуемый URL. Я пробовал это с потоками:
import tkinter as tk
import threading
import os
import time
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
browsers = []
class Browser:
def __init__(self, url, session_file):
self.url = url
self.session_file = session_file
def manipulate_browser(browser):
browser.driver = webdriver.Chrome(ChromeDriverManager().install())
while True:
browser.driver.get(browser.url)
time.sleep(4)
def start_browsers():
for browser in browsers:
browser.thread = threading.Thread(target=manipulate_browser, args=(browser,))
browser.thread.start()
if __name__=='__main__':
lock = threading.Lock()
threads = []
urls = 'https://google.com', 'https://facebook.com', 'https://instagram.com', 'https://snapchat.com', 'https://stackoverflow.com', 'https://amazon.com', 'https://microsoft.com'#, 'https://stackoverflow.com', 'https://youtube.com', 'https://yahoo.com'
for url in urls:
session_file = 'session_' + ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(10))
newBrowser = Browser(url, session_file)
browsers.append(newBrowser)
root = tk.Tk()
button_start_browsers = tk.Button(root, command=start_browsers, width=50, height=4, bg='red', text='Start Browsers')
button_start_browsers.pack()
И это прекрасно работает, но я хочу добавить некоторые опции и возможности в драйвер в функции manipulate_browser
. Вот так:
import tkinter as tk
import threading
import os
import time
import random, string
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from multiprocessing.pool import ThreadPool
browsers = []
class Browser:
def __init__(self, url, session_file):
self.url = url
self.session_file = session_file
def manipulate_browser(browser):
global lock
with lock:
caps = DesiredCapabilities().CHROME
caps["pageLoadStrategy"] = "none"
chrome_options = webdriver.ChromeOptions();
current_dir = os.path.dirname(os.path.abspath(__file__))
os.mkdir(current_dir + '\\' + browser.session_file)
chrome_options.add_argument(r'--user-data-dir=' + current_dir + '\\' + browser.session_file + '\\selenium')
chrome_options.add_argument("--window-size=750,750")
browser.driver = webdriver.Chrome(ChromeDriverManager().install(), options=chrome_options, desired_capabilities=caps)
while True:
browser.driver.get(browser.url)
time.sleep(4)
def start_browsers():
for browser in browsers:
browser.thread = threading.Thread(target=manipulate_browser, args=(browser,))
browser.thread.start()
if __name__=='__main__':
lock = threading.Lock()
threads = []
urls = 'https://google.com', 'https://facebook.com', 'https://instagram.com', 'https://snapchat.com', 'https://stackoverflow.com', 'https://amazon.com', 'https://microsoft.com'#, 'https://stackoverflow.com', 'https://youtube.com', 'https://yahoo.com'
for url in urls:
session_file = 'session_' + ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(10))
newBrowser = Browser(url, session_file)
browsers.append(newBrowser)
root = tk.Tk()
button_start_browsers = tk.Button(root, command=start_browsers, width=50, height=4, bg='red', text='Start Browsers')
button_start_browsers.pack()
После реализации это больше не работает: имеется в виду: иногда я получаю эту ошибку selenium.common.exceptions.WebDriverException: Message: unknown error: cannot parse internal JSON template: Line: 1, column: 1, Unexpected token.
И все потоки работают только на одном драйвере (последнем) , Я полагаю, что это потому, что потоки смешиваются друг с другом, поэтому я должен использовать блокировку, но помещение этой строки browser.driver = webdriver.Chrome(ChromeDriverManager().install(), options=chrome_options, desired_capabilities=caps)
под блокировку сильно повлияет на мою скорость, которая мне нужна. Я также понимаю, что я должен использовать ThreadPool
, чтобы избежать смешивания потоков, и я попробовал это, но приложение GUI зависло. Другой вариант, который предлагают другие, - реализация очереди с потоками, с которой я не очень знаком. Я также думал о попытке многопроцессорной обработки, но максимальное количество процессов зависит от характеристик каждой машины, от моего понимания, и, возможно, я хочу запустить больше процессов, чем это. Как я могу обойти эту ситуацию, чтобы достичь своей цели? Каков наилучший способ?
(Примечание: я провел много исследований относительно своей проблемы, но все еще не мог понять ее. Любая помощь приветствуется!)
РЕДАКТИРОВАТЬ: Из-за многократного тестирования я понял, что строка chrome_options.add_argument(r'--user-data-dir=' + current_dir + '\\' + browser.session_file + '\\selenium')
может вызвать все проблемы. Эта строка хранит все chrome сессии в одном значке, и мне очень нравится эта функция, и я не хотел бы от нее избавляться. Как я могу преодолеть проблему, зная эту информацию? Любая помощь будет оценена!