Как подключиться к одному профилю chrome из нескольких потоков с selenium'ом?

Сделал отдельную папку для профиля, в котором настроены несколько параметров, вроде загрузки изображений для сайта (сделал "настройки сайта" -> "картинки"="блокировать" для сайта), пути для загрузки файлов и.т.п.

Делаю запуск Selenium:

options = webdriver.ChromeOptions()
# в этом профиле уже настроены нужные мне настройки, оно все сохраняется и подцепляется
options.add_argument(r"--user-data-dir=D:\selenium_chrome_profile")
driver = webdriver.Chrome(options=options)

Все запускается и работает.
Но стоит мне попробовать это запихнуть в многопоточность/многопроцессорность, как 2+ потоки отваливаются с какой то сложной ошибкой в которой куча строк (No symbol) [0x0000...], и подчеркнутым указанием на ошибку в строке webdriver.Chrome(options=options).

Есть ли возможность все это дело как то оформить без оформления N-штук папок профиля и настраивания настроек в каждом?
(Понятное дело, что оно можно закинуть shutil.copytree если не os.path.exists для каждого нумерованного профиля из оригинального, но держать много профилей по 500мб каждый это... как то, да...)
Или может быть можно это как то стартануть в соседних вкладках одного окна одного профиля, но с подключением каждого потока к своей вкладке? Или это будет сильная потеря производительности?

Рабочий пример кода (при how_many = 1 работает, при > 1 выдает ошибки):

from selenium import webdriver
from threading import Thread


def go_visiting():
    options = webdriver.ChromeOptions()
    options.add_argument(r"--user-data-dir=D:\selenium_chrome_profile")

    driver = webdriver.Chrome(options=options)
    driver.get(url="https://ru.stackoverflow.com/")
    driver.close()
    driver.quit()


if __name__ == '__main__':
    how_many = 3
    threads = []
    
    for _ in range(how_many):
        i = Thread(target=go_visiting)
        i.start()
        threads.append(i)

    for i in threads:
        i.join()

    print("Fin!")

PS Пробовал делать то же самое через multiprocessing Pool, отвалилось с той же ошибкой. Пока не уверен через что в итоге буду делать, как разберусь с тем как оно работает буду делать тесты.


Ответы (1 шт):

Автор решения: Сергей Ш

Попробуйте Playwright - асинхронный аналог selenium. Пример:

import asyncio
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as pl:
        browser = await pl.chromium.launch_persistent_context('user_data', headless=False)
        urls = "https://www.google.com", "http://playwright.dev", "https://ru.stackoverflow.com/questions"
        tasks = []
        for url in urls:
            p = await browser.new_page()
            tasks.append(p.goto(url))
        await asyncio.gather(*tasks)

        all_pages = browser.pages
        for x in all_pages:
            print(await x.title())

        await browser.close()

asyncio.run(main())

# Google
# Fast and reliable end-to-end testing for modern web apps | Playwright
# Новые вопросы - Stack Overflow на русском

доки Playwright

→ Ссылка