I am using the Playwright synchronous API in completely separate scripts and they all work fine when I run them at different times, but if I try to run the scripts at the same time, the script that started first seems to take ownership of the browser and the second (and subsequent) script fails with a message about "Opening in existing browser session". I would have thought that Playwright could start separate browsers for each script so they would be completely independent, but it doesn't seem to.
I should say I also need to use the persistent browser context to ensure the scripts authenticate against various systems as me and that seems to be part of the issue.
Has anyone else encountered this issue and do you know if there's a way to have the scripts run concurrently (without using Playwright asynchronously as this will introduce a lot more complexity).
Here's the code each script uses to start a context :
import os
from playwright.sync_api import Playwright, sync_playwright
def get_cookies(context):
"""
Checks for new cookies. This function running is critical to pages loading
properly, or else the pages will look like they are only partially loading.
"""
global cookies
cookie_set = {tempdict['name'] for tempdict in cookies}
new_cookies = context.cookies()
context_cookie_set = {tempdict['name'] for tempdict in new_cookies}
new_cookie_set = context_cookie_set - cookie_set
if len(new_cookie_set) == 0:
return 0
else:
pass
cookies = new_cookies
return len(new_cookie_set)
cookies = []
playwright = sync_playwright().start()
username = os.environ.get('USERNAME')
context_location = rf'C:\Users\{username}\AppData\Local\Microsoft\Edge\User Data\Default'
context = playwright.chromium.launch_persistent_context(context_location,
headless=False,
channel='msedge')
get_cookies(context)
context.on('requestfinished', lambda r: get_cookies(context))
context.on('requestfailed', lambda r: get_cookies(context))
page = context.new_page()
page.goto('https://playwright.dev/python/')
page.wait_for_load_state(state='networkidle')
while get_cookies(context) > 0:
print('.')
pass
# Simulate an action with a time delay
seconds = 30
page.wait_for_timeout(seconds * 1000)
I know I can pass in different startup arguments, but I haven't seen an arg that lets me start separate browsers.
Here's an example of the output I get from a command window:
Traceback (most recent call last):
File "E:\OLD_STUFF\Miscellaneous_Scripts\playwright_test.py", line 28, in <module>
context = playwright.chromium.launch_persistent_context(context_location,
File "c:\programdata\miniconda3\lib\site-packages\playwright\sync_api\_generated.py", line 14662, in launch_persistent_context
self._sync(
File "c:\programdata\miniconda3\lib\site-packages\playwright\_impl\_sync_base.py", line 104, in _sync
return task.result()
File "c:\programdata\miniconda3\lib\site-packages\playwright\_impl\_browser_type.py", line 155, in launch_persistent_context
from_channel(await self._channel.send("launchPersistentContext", params)),
File "c:\programdata\miniconda3\lib\site-packages\playwright\_impl\_connection.py", line 44, in send
return await self._connection.wrap_api_call(
File "c:\programdata\miniconda3\lib\site-packages\playwright\_impl\_connection.py", line 419, in wrap_api_call
return await cb()
File "c:\programdata\miniconda3\lib\site-packages\playwright\_impl\_connection.py", line 79, in inner_send
result = next(iter(done)).result()
playwright._impl._api_types.Error: Browser closed.
==================== Browser output: ====================
<launching> C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe --disable-field-trial-config --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,DialMediaRouteProvider,AcceptCHFrame,AutoExpandDetailsElement,CertificateTransparencyComponentUpdater,AvoidUnnecessaryBeforeUnloadCheckSync,Translate --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --no-sandbox --user-data-dir=C:\Users\****\AppData\Local\Microsoft\Edge\User Data\Default --remote-debugging-pipe about:blank
<launched> pid=529300
[pid=529300][out] Opening in existing browser session.
[pid=529300] <process did exit: exitCode=0, signal=null>
[pid=529300] starting temporary directories cleanup
=========================== logs ===========================
<launching> C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe --disable-field-trial-config --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,DialMediaRouteProvider,AcceptCHFrame,AutoExpandDetailsElement,CertificateTransparencyComponentUpdater,AvoidUnnecessaryBeforeUnloadCheckSync,Translate --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --no-sandbox --user-data-dir=C:\Users\****\AppData\Local\Microsoft\Edge\User Data\Default --remote-debugging-pipe about:blank
<launched> pid=529300
[pid=529300][out] Opening in existing browser session.
[pid=529300] <process did exit: exitCode=0, signal=null>
[pid=529300] starting temporary directories cleanup
============================================================
Thanks.
Your usage of option user_data_dir is wrong.
user_data_dir Union[str, pathlib.Path]
Path to a User Data Directory, which stores browser session data like cookies and local storage. More details for Chromium and Firefox. Note that Chromium's user data directory is the parent directory of the "Profile Path" seen at chrome://version. Pass an empty string to use a temporary directory instead.
context = playwright.chromium.launch_persistent_context(
# context_location,
user_data_dir="",
headless=False,
channel="msedge",
)
If you want to keep User Data Directory, please make it unique each run, for eaxmple use random:
random_string = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(16))
context_location = (
rf"C:\Users\{username}\AppData\Local\Microsoft\Edge\User Data\Default_{random_string}"
)
print(f"context_location: {context_location}")
context = playwright.chromium.launch_persistent_context(
context_location,
# user_data_dir="",
headless=False,
channel="msedge",
)