-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Version
1.46.0
Steps to reproduce
I want to know the correct usage of Clock. Is it to use context.clock.install() and then perform page.clock.run_for() on each page under the context, or is it necessary to also use page.clock.install() on each page?
Here is my code, and you can supplement it with test cases as needed. I am not clear about the usage of Clock in asynchronous scenarios, so my program behaves unexpectedly and produces an error: Clock.run_for: TypeError: Cannot read properties of undefined (reading 'controller'), or it produces the error: Clock.run_for: Target page, context or browser has been closed. These issues are intermittent and cannot be consistently reproduced 100% of the time.
import asyncio
import logging
import json
from playwright.async_api import async_playwright
logger = logging.getLogger(__name__)
class HeadlessWorker:
def __init__(self,
browser_name="chromium"):
# init
self.browser_name = browser_name
self.playwright = None
self.browser = None
self.context = None
async def launch_browser(self) -> None:
try:
self.playwright = await async_playwright().start()
self.browser = await self.playwright[self.browser_name].launch(headless=True)
self.context = await self.browser.new_context(
accept_downloads=False,
)
**_await self.context.clock.install()_**
except Exception as err:
logger.warning("[HeadlessWorker] error info:{}".format(err))
async def close_browser(self) -> None:
try:
await self.browser.close()
await self.playwright.stop()
except Exception as err:
logger.error(
"close browser failed and err info:{}".format(err))
async def listen_download_event(self, url: dict) -> bool:
async with asyncio.Semaphore(5):
# listen data
lis_data_tmp = {
"is_download": False, "download_url": set()
}
try:
page = await self.context.new_page()
except Exception as err:
logger.error(
"create new page for url:{} and error info: {}".format(
url, err))
return False
def process_download(download, record) -> None:
try:
record["is_download"] = True
record["download_url"].add(download.url)
except Exception as err:
logger.error(
"[Error] error info: {}.".format(err)
)
try:
page.on(
"download",
lambda download: process_download(
download,
lis_data_tmp))
except Exception as err:
logger.error(
"error info: {}".format(err)
)
_**try:
await page.clock.install()
except Exception as err:
logger.warning(
"[Clock] Install Failed, err info: {}".format(err))
return False**_
try:
await page.goto(url, timeout=6000)
**_await page.clock.run_for(50000)_**
await page.wait_for_load_state("networkidle", timeout=15000)
await asyncio.sleep(1)
except Exception as err:
if "net::ERR_ABORTED" in str(err):
pass
else:
logger.error(
"url:{},[Navigator] error info: {}".format(url, err)
)
await page.close()
print("*url:{}, download info:{}".format(url, lis_data_tmp))
return True
async def run(self, tasks):
try:
coroutines = []
for task in tasks:
coroutines.append(
asyncio.create_task(
self.listen_download_event(task)))
await asyncio.gather(*coroutines)
except Exception as err:
logger.error("async error msg: {}".format(err))
if __name__ == "__main__":
async def start():
Worker = HeadlessWorker()
await Worker.launch_browser()
urls= [
]
await Worker.run(urls)
await Worker.close_browser()
asyncio.run(start())
I couldn't find any effective demos in the official documentation; I need a complete example.
Expected behavior
has no error
Actual behavior
error happened
Additional context
No response
Environment
- Operating System: [Windows 10]
- CPU: [intel]
- Browser: [Chromium]
- Python Version: [3.8.5]
- Other info: