diff --git a/docs.json b/docs.json index a89271b..def92e1 100644 --- a/docs.json +++ b/docs.json @@ -111,6 +111,12 @@ "integrations/vercel" ] }, + { + "group": "Migrations", + "pages": [ + "migrations/scrapybara" + ] + }, { "group": "Community", "pages": [ diff --git a/migrations/scrapybara.mdx b/migrations/scrapybara.mdx new file mode 100644 index 0000000..c107a17 --- /dev/null +++ b/migrations/scrapybara.mdx @@ -0,0 +1,172 @@ +--- +title: "Scrapybara" +--- + +[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. + +## Key Concepts + +| Feature | Scrapybara | Kernel | +|---------|-----------|--------| +| **Start Browser** | `client.start_browser()` | `client.browsers.create()` | +| **Standby Mode** | `instance.pause()` / `instance.resume()` | Automatic standby mode | +| **CDP URL** | `instance.get_cdp_url().cdp_url` | Returns `cdp_ws_url` in create response | +| **Live View** | `instance.get_stream_url().stream_url` | Returns `browser_live_view_url` in create response | +| **Stealth Mode** | ❌ Not available | Create browser with `stealth: true` | +| **Replays** | ❌ Not available | `client.browsers.replays.start()` and `client.browsers.replays.stop()` | +| **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})` | + +## How to migrate + +### Basic Browser Creation + +**Scrapybara** +```python +from scrapybara import Scrapybara +from playwright.async_api import async_playwright + +client = Scrapybara(api_key="your_api_key") +instance = client.start_browser(timeout_hours=1) +cdp_url = instance.get_cdp_url().cdp_url + +async with async_playwright() as p: + browser = await p.chromium.connect_over_cdp(cdp_url) + page = browser.contexts[0].pages[0] + await page.goto("https://example.com") + await browser.close() + +instance.stop() +``` + +**Kernel** +```python +from kernel import Kernel +from playwright.async_api import async_playwright + +client = Kernel(api_key="your_api_key") +kernel_browser = client.browsers.create(timeout_seconds=3600) +cdp_url = kernel_browser.cdp_ws_url + +async with async_playwright() as p: + browser = await p.chromium.connect_over_cdp(cdp_url) + page = browser.contexts[0].pages[0] + await page.goto("https://example.com") + await browser.close() + +await client.browsers.delete_by_id(kernel_browser.session_id) +``` + +### Save & Reuse Authentication + +**Scrapybara** +```python +# First session - save auth +instance = client.start_browser() +# ... login to website via Playwright ... +auth_state = instance.browser.save_auth(name="my-login") +instance.stop() + +# Second session - load auth +instance2 = client.start_browser() +instance2.browser.authenticate(auth_state_id=auth_state.auth_state_id) +# ... browser now has saved cookies ... +``` + +**Kernel** +```python +# First session - save auth +profile = await client.profiles.create(name="my-login") +browser1 = await client.browsers.create( + profile={"name": "my-login", "save_changes": True} +) +# ... login to website via Playwright ... +await client.browsers.delete_by_id(browser1.session_id) + +# Second session - load auth +browser2 = await client.browsers.create( + profile={"name": "my-login"} +) +# ... browser now has saved cookies ... +``` + +### File Download + +**Scrapybara** +```python +instance = client.start_browser() +# ... trigger download in browser ... +# Then use file operations +downloaded_file = instance.file(command="read", path="/download/path") +``` + +**Kernel** +```python +browser = await client.browsers.create() +# ... trigger download in browser via Playwright ... +# Then read from filesystem +file_response = await client.browsers.fs.read_file( + browser.session_id, + path="/tmp/downloads/file.pdf" +) +await file_response.write_to_file("local-file.pdf") +``` + +### Long-Running Sessions + +**Scrapybara** +```python +# Pause/resume for long-running sessions +instance = client.start_browser(timeout_hours=24) +# ... do some work ... +instance.pause() # Pause to save costs +# ... later ... +instance.resume() # Resume work +``` + +**Kernel** +```python +# Automatic standby mode + persistence +browser = await client.browsers.create( + persistence={"id": "my-long-session"} +) +# ... do some work ... +# Browser enters standby mode between connections + +# Later - reuse the exact browser instance with full state +browser2 = await client.browsers.create( + persistence={"id": "my-long-session"} +) +``` + + +## Full API Comparison + +| Feature | Scrapybara | Kernel | +|---------|-----------|--------| +| **Create Browser** | `client.start_browser()` | `client.browsers.create()` | +| **Get CDP URL** | `instance.get_cdp_url().cdp_url` | Returns `cdp_ws_url` in create response | +| **Get Live View** | `instance.get_stream_url().stream_url` | Returns `browser_live_view_url` in create response | +| **Delete Browser** | `instance.stop()` | `client.browsers.delete_by_id(session_id)` | +| **List Browsers** | `client.get_instances()` | `client.browsers.list()` | +| **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})` | +| **Load Auth State** | `instance.browser.authenticate(auth_state_id="xyz")` | `kernel.browsers.create(profile={"name": "profile1"})` | +| **Pause/Resume** | `instance.pause()` / `instance.resume()` | Automatic standby mode | +| **Screenshot** | `instance.screenshot()` | Use Playwright or Puppeteer | +| **Timeout Config** | `timeout_hours` parameter | `timeout_seconds` parameter | +| **Stealth Mode** | ❌ Not available | Create browser with `stealth: true` | +| **Headless Mode** | ❌ Not available | Create browser with `headless: true` | +| **Session Persistence** | Auth state only | Full browser state via creating browser with `persistence={"id": "persist-id"}` | +| **Video Replays** | ❌ Not available | `client.browsers.replays.start()` and `client.browsers.replays.stop()` | +| **File Upload** | `instance.upload()` | `client.browsers.fs.upload()` or Playwright | +| **File Download** | Via browser, then `instance.file()` | `client.browsers.fs.read_file()` | +| **Process Control** | `instance.bash()` | `client.browsers.process.*` | +| **Proxy Support** | ❌ Not available | Create [Proxy](/proxies/overview#1-create-a-proxy). Then create browser with `client.browsers.create(proxy_id=proxy.id)` | + +--- + +## Need Help? + +* **Contact Us** on [Discord](https://discord.gg/FBrveQRcud) +* **Sign-Up** [here](https://dashboard.onkernel.com/sign-up) +* **Check out** our open source repos [here](https://github.com/onkernel/kernel-images) +