{"flag":true,"single":true,"pageTitle":"Patchright Tutorial installation + basic code async, sync","post":{"id":340,"user_id":"1","slug":"patchright-tutorial-zglc","title":"Patchright Tutorial installation + basic code async, sync","body":"<p>Patchright provides a stealth-focused (websites cannot easily detect that a bot (like Playwright\/Selenium)) browser automation solution that maintains full API compatibility with Playwright.<\/p>\r\n<p>Use: web scraping of protected sites, automated testing against security systems, and browser automation tasks where avoiding detection is critical.<\/p>\r\n<p>simply change <strong>`from playwright.sync_api` to `from patchright.sync_api`<\/strong> (or the async equivalent).&nbsp;<\/p>\r\n<p>1. Create virtual Enviorment (optional)<\/p>\r\n<pre class=\"language-markup\"><code>pip install virtualenv\r\nvirtualenv venv\r\nvenv\\Scripts\\activate<\/code><\/pre>\r\n<p>2. install patchright<\/p>\r\n<pre class=\"language-markup\"><code>pip install patchright<\/code><\/pre>\r\n<p>3. install browser<\/p>\r\n<pre class=\"language-markup\"><code>patchright install chrome\r\n#or\r\npatchright install chromium<\/code><\/pre>\r\n<p>4. make file abc.py SYNC<\/p>\r\n<pre class=\"language-markup\"><code>from patchright.sync_api import sync_playwright\r\n\r\nwith sync_playwright() as p:\r\n    browser = p.chromium.launch(\r\n        channel=\"chrome\",\r\n        headless=False\r\n    )\r\n\r\n    page = browser.new_page()\r\n    page.goto(\"https:\/\/example.com\")\r\n\r\n    print(page.title())\r\n\r\n    browser.close()<\/code><\/pre>\r\n<p>OR ASYNC<\/p>\r\n<pre class=\"language-markup\"><code>import asyncio\r\nimport os\r\nfrom patchright.async_api import async_playwright\r\n\r\nasync def main():\r\n    async with async_playwright() as p:\r\n        # Define where to store browser data (cookies, cache, etc.)\r\n        user_data_dir = os.path.join(os.getcwd(), \"chrome_profile\")\r\n        \r\n        # Best Practice: Launching a persistent context with Chrome\r\n        # This bypasses standard fingerprinting by using a real browser channel\r\n        context = await p.chromium.launch_persistent_context(\r\n            user_data_dir=user_data_dir,\r\n            channel=\"chrome\",  # Uses the actual Chrome browser installed on your system\r\n            headless=False,    # Headful is generally harder to detect\r\n            no_viewport=True,  # Allows the window to dictate size, preventing scaling mismatches\r\n            # Avoid adding custom user_agent or extra_headers here to maintain a clean fingerprint\r\n        )\r\n\r\n        # In a persistent context, a page is usually opened automatically\r\n        page = context.pages[0] if context.pages else await context.new_page()\r\n\r\n        # Navigate and perform actions\r\n        await page.goto('https:\/\/playwright.dev')\r\n        print(f\"Title: {await page.title()}\")\r\n        \r\n        # Take the screenshot\r\n        await page.screenshot(path=f'example-chrome-stealth.png')\r\n\r\n        # Close the context properly\r\n        await context.close()\r\n\r\nif __name__ == \"__main__\":\r\n    asyncio.run(main())\r\n<\/code><\/pre>\r\n<p>&nbsp;<\/p>\r\n<p>with async:<br><strong>1. open multiple pages<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>import asyncio\r\nimport os\r\nfrom patchright.async_api import async_playwright\r\n\r\nurls = [\r\n    \"https:\/\/example.com\",\r\n    \"https:\/\/example.org\",\r\n    \"https:\/\/example.net\"\r\n]\r\n\r\nasync def open_page(context, url):\r\n    page = await context.new_page()\r\n    await page.goto(url)\r\n    print(f\"{url} &rarr; {await page.title()}\")\r\n\r\nasync def main():\r\n    async with async_playwright() as p:\r\n        user_data_dir = os.path.join(os.getcwd(), \"chrome_profile\")\r\n        context = await p.chromium.launch_persistent_context(\r\n            user_data_dir=user_data_dir,\r\n            channel=\"chrome\",\r\n            headless=False,\r\n            no_viewport=True,\r\n        )\r\n        # ???? PARALLEL execution, * unpack list, gather accept list\r\n        await asyncio.gather(*[\r\n            open_page(context, url) for url in urls\r\n        ])\r\n        await context.close()\r\nasyncio.run(main())<\/code><\/pre>\r\n<p>2. auto google search<\/p>\r\n<pre class=\"language-markup\"><code>import asyncio\r\nimport os\r\nfrom patchright.async_api import async_playwright\r\n\r\nasync def main():\r\n    async with async_playwright() as p:\r\n        user_data_dir = os.path.join(os.getcwd(), \"chrome_profile\")\r\n        context = await p.chromium.launch_persistent_context(\r\n            user_data_dir=user_data_dir,\r\n            channel=\"chrome\",  # Uses the actual Chrome browser installed on your system\r\n            headless=False,    # Headful is generally harder to detect\r\n            no_viewport=True,  # Allows the window to dictate size, preventing scaling mismatches\r\n        )\r\n        page = context.pages[0] if context.pages else await context.new_page()\r\n\r\n        await page.goto(\"https:\/\/www.google.com\")\r\n\r\n        await page.wait_for_timeout(2000)\r\n        await page.fill(\"textarea[name='q']\", \"Patchright tutorial\")\r\n\r\n        await page.wait_for_timeout(1000)\r\n        await page.keyboard.press(\"Enter\")\r\n\r\n        await page.wait_for_timeout(3000)\r\n        print(\"Searched:\", \"Patchright tutorial\"-)\r\n\r\nif __name__ == \"__main__\":\r\n    asyncio.run(main())\r\n<\/code><\/pre>\r\n<p>3. login attempt<\/p>\r\n<pre class=\"language-markup\"><code>import asyncio\r\nimport os\r\nfrom patchright.async_api import async_playwright\r\n\r\nasync def login(page):\r\n    await page.goto(\"https:\/\/practicetestautomation.com\/practice-test-login\/\")\r\n\r\n    await page.fill(\"#username\", \"student\")\r\n    await page.fill(\"#password\", \"Password123\")\r\n\r\n    await page.click(\"#submit\")\r\n    await page.wait_for_timeout(3000)\r\n\r\n    print(\"Login attempted\")\r\n\r\nasync def main():\r\n    async with async_playwright() as p:\r\n        user_data_dir = os.path.join(os.getcwd(), \"chrome_profile\")\r\n        context = await p.chromium.launch_persistent_context(\r\n            user_data_dir=user_data_dir,\r\n            channel=\"chrome\",  # Uses the actual Chrome browser installed on your system\r\n            headless=False,    # Headful is generally harder to detect\r\n            no_viewport=True,  # Allows the window to dictate size, preventing scaling mismatches\r\n        )\r\n        page = context.pages[0] if context.pages else await context.new_page()\r\n        await login(page)\r\n\r\nif __name__ == \"__main__\":\r\n    asyncio.run(main())\r\n\r\n\r\n<\/code><\/pre>\r\n<p>4. data scraping&nbsp;<\/p>\r\n<pre class=\"language-markup\"><code>import asyncio\r\nimport os\r\nfrom patchright.async_api import async_playwright\r\n\r\nasync def scrape_titles(page):\r\n    await page.goto(\"https:\/\/news.ycombinator.com\")\r\n\r\n    titles = await page.locator(\".titleline &gt; a\").evaluate_all(\r\n        \"els =&gt; els.map(el =&gt; el.textContent)\"\r\n    )\r\n\r\n    for t in titles:\r\n        print(\"Title:\", t)\r\n\r\nasync def main():\r\n    async with async_playwright() as p:\r\n        user_data_dir = os.path.join(os.getcwd(), \"chrome_profile\")\r\n        context = await p.chromium.launch_persistent_context(\r\n            user_data_dir=user_data_dir,\r\n            channel=\"chrome\",  # Uses the actual Chrome browser installed on your system\r\n            headless=False,    # Headful is generally harder to detect\r\n            no_viewport=True,  # Allows the window to dictate size, preventing scaling mismatches\r\n        )\r\n        page = context.pages[0] if context.pages else await context.new_page()\r\n        await scrape_titles(page)\r\n\r\nif __name__ == \"__main__\":\r\n    asyncio.run(main())\r\n\r\n\r\n<\/code><\/pre>","category_id":"37","is_private":"0","created_at":"2026-04-02T02:43:12.000000Z","updated_at":"2026-04-02T04:30:19.000000Z","category":{"id":37,"user_id":"1","name":"Playwright","slug":"playwright-c2zf","parent_id":null,"created_at":"2025-03-05T22:35:12.000000Z","updated_at":"2025-03-05T22:35:12.000000Z"},"user":{"id":1,"name":"R GONDAL","email":"rizikmw@gmail.com","email_verified_at":null,"two_factor_confirmed_at":null,"current_team_id":"1","profile_photo_path":null,"created_at":"2023-03-12T10:49:33.000000Z","updated_at":"2025-01-10T12:59:00.000000Z","profile_photo_url":"https:\/\/ui-avatars.com\/api\/?name=R+G&color=7F9CF5&background=EBF4FF"}},"pageDesc":"Patchright provides a stealth-focused (websites cannot easily detect that a bot (like Playwright\/Selenium)) browser automation solution that - Patchright Tutorial installation + basic code async, sync (Updated: April 2, 2026) - Read more about Patchright Tutorial installation + basic code async, sync at my programming site [SITE]","categories":[]}