|
| 1 | +--- |
| 2 | +title: "Scrapybara" |
| 3 | +--- |
| 4 | + |
| 5 | +[Scrapybara](https://scrapybara.com/) is shutting down their virtual desktop and browser service on **October 15, 2025**. If you're currently using Scrapybara for browser automation, Kernel is here to help you migrate seamlessly. |
| 6 | + |
| 7 | +## Key Concepts |
| 8 | + |
| 9 | +| Feature | Scrapybara | Kernel | |
| 10 | +|---------|-----------|--------| |
| 11 | +| **Start Browser** | `client.start_browser()` | `client.browsers.create()` | |
| 12 | +| **Standby Mode** | `instance.pause()` / `instance.resume()` | Automatic standby mode | |
| 13 | +| **CDP URL** | `instance.get_cdp_url().cdp_url` | Returns `cdp_ws_url` in create response | |
| 14 | +| **Live View** | `instance.get_stream_url().stream_url` | Returns `browser_live_view_url` in create response | |
| 15 | +| **Stealth Mode** | ❌ Not available | Create browser with `stealth: true` | |
| 16 | +| **Replays** | ❌ Not available | `client.browsers.replays.start()` and `client.browsers.replays.stop()` | |
| 17 | +| **Save Auth** | `instance.browser.save_auth(name="default")` | Create [Profile](/browsers/profiles). Then create browser with `kernel.browsers.create(profile={"name": "profile1", "save_changes": True})` | |
| 18 | + |
| 19 | +## How to migrate |
| 20 | + |
| 21 | +### Basic Browser Creation |
| 22 | + |
| 23 | +**Scrapybara** |
| 24 | +```python |
| 25 | +from scrapybara import Scrapybara |
| 26 | +from playwright.async_api import async_playwright |
| 27 | + |
| 28 | +client = Scrapybara(api_key="your_api_key") |
| 29 | +instance = client.start_browser(timeout_hours=1) |
| 30 | +cdp_url = instance.get_cdp_url().cdp_url |
| 31 | + |
| 32 | +async with async_playwright() as p: |
| 33 | + browser = await p.chromium.connect_over_cdp(cdp_url) |
| 34 | + page = browser.contexts[0].pages[0] |
| 35 | + await page.goto("https://example.com") |
| 36 | + await browser.close() |
| 37 | + |
| 38 | +instance.stop() |
| 39 | +``` |
| 40 | + |
| 41 | +**Kernel** |
| 42 | +```python |
| 43 | +from kernel import Kernel |
| 44 | +from playwright.async_api import async_playwright |
| 45 | + |
| 46 | +client = Kernel(api_key="your_api_key") |
| 47 | +kernel_browser = client.browsers.create(timeout_seconds=3600) |
| 48 | +cdp_url = kernel_browser.cdp_ws_url |
| 49 | + |
| 50 | +async with async_playwright() as p: |
| 51 | + browser = await p.chromium.connect_over_cdp(cdp_url) |
| 52 | + page = browser.contexts[0].pages[0] |
| 53 | + await page.goto("https://example.com") |
| 54 | + await browser.close() |
| 55 | + |
| 56 | +await client.browsers.delete_by_id(kernel_browser.session_id) |
| 57 | +``` |
| 58 | + |
| 59 | +### Save & Reuse Authentication |
| 60 | + |
| 61 | +**Scrapybara** |
| 62 | +```python |
| 63 | +# First session - save auth |
| 64 | +instance = client.start_browser() |
| 65 | +# ... login to website via Playwright ... |
| 66 | +auth_state = instance.browser.save_auth(name="my-login") |
| 67 | +instance.stop() |
| 68 | + |
| 69 | +# Second session - load auth |
| 70 | +instance2 = client.start_browser() |
| 71 | +instance2.browser.authenticate(auth_state_id=auth_state.auth_state_id) |
| 72 | +# ... browser now has saved cookies ... |
| 73 | +``` |
| 74 | + |
| 75 | +**Kernel** |
| 76 | +```python |
| 77 | +# First session - save auth |
| 78 | +profile = await client.profiles.create(name="my-login") |
| 79 | +browser1 = await client.browsers.create( |
| 80 | + profile={"name": "my-login", "save_changes": True} |
| 81 | +) |
| 82 | +# ... login to website via Playwright ... |
| 83 | +await client.browsers.delete_by_id(browser1.session_id) |
| 84 | + |
| 85 | +# Second session - load auth |
| 86 | +browser2 = await client.browsers.create( |
| 87 | + profile={"name": "my-login"} |
| 88 | +) |
| 89 | +# ... browser now has saved cookies ... |
| 90 | +``` |
| 91 | + |
| 92 | +### File Download |
| 93 | + |
| 94 | +**Scrapybara** |
| 95 | +```python |
| 96 | +instance = client.start_browser() |
| 97 | +# ... trigger download in browser ... |
| 98 | +# Then use file operations |
| 99 | +downloaded_file = instance.file(command="read", path="/download/path") |
| 100 | +``` |
| 101 | + |
| 102 | +**Kernel** |
| 103 | +```python |
| 104 | +browser = await client.browsers.create() |
| 105 | +# ... trigger download in browser via Playwright ... |
| 106 | +# Then read from filesystem |
| 107 | +file_response = await client.browsers.fs.read_file( |
| 108 | + browser.session_id, |
| 109 | + path="/tmp/downloads/file.pdf" |
| 110 | +) |
| 111 | +await file_response.write_to_file("local-file.pdf") |
| 112 | +``` |
| 113 | + |
| 114 | +### Long-Running Sessions |
| 115 | + |
| 116 | +**Scrapybara** |
| 117 | +```python |
| 118 | +# Pause/resume for long-running sessions |
| 119 | +instance = client.start_browser(timeout_hours=24) |
| 120 | +# ... do some work ... |
| 121 | +instance.pause() # Pause to save costs |
| 122 | +# ... later ... |
| 123 | +instance.resume() # Resume work |
| 124 | +``` |
| 125 | + |
| 126 | +**Kernel** |
| 127 | +```python |
| 128 | +# Automatic standby mode + persistence |
| 129 | +browser = await client.browsers.create( |
| 130 | + persistence={"id": "my-long-session"} |
| 131 | +) |
| 132 | +# ... do some work ... |
| 133 | +# Browser enters standby mode between connections |
| 134 | + |
| 135 | +# Later - reuse the exact browser instance with full state |
| 136 | +browser2 = await client.browsers.create( |
| 137 | + persistence={"id": "my-long-session"} |
| 138 | +) |
| 139 | +``` |
| 140 | + |
| 141 | + |
| 142 | +## Full API Comparison |
| 143 | + |
| 144 | +| Feature | Scrapybara | Kernel | |
| 145 | +|---------|-----------|--------| |
| 146 | +| **Create Browser** | `client.start_browser()` | `client.browsers.create()` | |
| 147 | +| **Get CDP URL** | `instance.get_cdp_url().cdp_url` | Returns `cdp_ws_url` in create response | |
| 148 | +| **Get Live View** | `instance.get_stream_url().stream_url` | Returns `browser_live_view_url` in create response | |
| 149 | +| **Delete Browser** | `instance.stop()` | `client.browsers.delete_by_id(session_id)` | |
| 150 | +| **List Browsers** | `client.get_instances()` | `client.browsers.list()` | |
| 151 | +| **Save Auth State** | `instance.browser.save_auth(name="default")` | Create [Profile](/browsers/profiles). Then create browser with `kernel.browsers.create(profile={"name": "profile1", "save_changes": True})` | |
| 152 | +| **Load Auth State** | `instance.browser.authenticate(auth_state_id="xyz")` | `kernel.browsers.create(profile={"name": "profile1"})` | |
| 153 | +| **Pause/Resume** | `instance.pause()` / `instance.resume()` | Automatic standby mode | |
| 154 | +| **Screenshot** | `instance.screenshot()` | Use Playwright or Puppeteer | |
| 155 | +| **Timeout Config** | `timeout_hours` parameter | `timeout_seconds` parameter | |
| 156 | +| **Stealth Mode** | ❌ Not available | Create browser with `stealth: true` | |
| 157 | +| **Headless Mode** | ❌ Not available | Create browser with `headless: true` | |
| 158 | +| **Session Persistence** | Auth state only | Full browser state via creating browser with `persistence={"id": "persist-id"}` | |
| 159 | +| **Video Replays** | ❌ Not available | `client.browsers.replays.start()` and `client.browsers.replays.stop()` | |
| 160 | +| **File Upload** | `instance.upload()` | `client.browsers.fs.upload()` or Playwright | |
| 161 | +| **File Download** | Via browser, then `instance.file()` | `client.browsers.fs.read_file()` | |
| 162 | +| **Process Control** | `instance.bash()` | `client.browsers.process.*` | |
| 163 | +| **Proxy Support** | ❌ Not available | Create [Proxy](/proxies/overview#1-create-a-proxy). Then create browser with `client.browsers.create(proxy_id=proxy.id)` | |
| 164 | + |
| 165 | +--- |
| 166 | + |
| 167 | +## Need Help? |
| 168 | + |
| 169 | +* **Contact Us** on [Discord](https://discord.gg/FBrveQRcud) |
| 170 | +* **Sign-Up** [here](https://dashboard.onkernel.com/sign-up) |
| 171 | +* **Check out** our open source repos [here](https://github.com/onkernel/kernel-images) |
| 172 | + |
0 commit comments