Metadata-Version: 2.4
Name: pybridge-browser
Version: 0.1.0
Summary: Take over and control your already-open browser via the PyBridge extension — Playwright-style API, no debug port needed.
Author-email: Walker Deng <walker.deng@acqu.co>
License-Expression: MIT
Project-URL: Homepage, https://github.com/dengwanghui1/Personalized_browser_plug_ins/tree/master/PyBridge%20-%20Python%20WebSocket%20Bridge
Project-URL: Repository, https://github.com/dengwanghui1/Personalized_browser_plug_ins
Project-URL: Extension, https://github.com/dengwanghui1/Personalized_browser_plug_ins/tree/master/PyBridge%20-%20Python%20WebSocket%20Bridge
Project-URL: Issues, https://github.com/dengwanghui1/Personalized_browser_plug_ins/issues
Keywords: browser-automation,chrome-extension,cdp,playwright,web-automation,browser-control,no-debug-port
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: websockets>=12.0
Dynamic: license-file

# pybridge-browser

> Take over and control your already-open browser — **no debug port, no browser restart.**
> Playwright-style API backed by a lightweight Chrome extension.

> [!IMPORTANT]
> This Python package **requires the PyBridge browser extension** to work.
> Download it here: **[PyBridge - Python WebSocket Bridge](https://github.com/dengwanghui1/Personalized_browser_plug_ins/tree/master/PyBridge%20-%20Python%20WebSocket%20Bridge)**

[![Python 3.8+](https://img.shields.io/badge/Python-3.8%2B-blue)](https://www.python.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green)](LICENSE)

## Why pybridge-browser?

Traditional browser automation (Selenium, Playwright, Puppeteer) launches a **new** browser instance or connects via `--remote-debugging-port`. That means:

- ❌ You lose your login sessions, cookies, and extensions.
- ❌ You need to restart the browser with special flags.
- ❌ Anti-bot detection flags automated fingerprints.

**pybridge-browser** takes a different approach: it uses a Chrome extension (`chrome.debugger` API) to attach to your **already-running** browser — keeping everything intact.

| Feature | pybridge-browser | Playwright | Selenium |
|---|---|---|---|
| Keeps login state | ✅ | ❌ | ❌ |
| Keeps extensions | ✅ | ❌ | ❌ |
| No browser restart | ✅ | ❌ | ❌ |
| No debug port | ✅ | ❌ | ❌ |
| Playwright-style API | ✅ | ✅ | ❌ |

## Installation

```bash
pip install pybridge-browser
```

## Prerequisites (one-time setup)

> ⚠️ **Required companion extension**: This package does NOT work standalone.
> You must first install the PyBridge browser extension:
> **[PyBridge - Python WebSocket Bridge](https://github.com/dengwanghui1/Personalized_browser_plug_ins/tree/master/PyBridge%20-%20Python%20WebSocket%20Bridge)**

1. **Load the PyBridge extension** — download the extension from [PyBridge - Python WebSocket Bridge](https://github.com/dengwanghui1/Personalized_browser_plug_ins/tree/master/PyBridge%20-%20Python%20WebSocket%20Bridge), then open `chrome://extensions`, enable **Developer mode** (top-right toggle), click **Load unpacked**, and select the downloaded PyBridge extension directory.

2. **Keep your browser open** with at least one normal web page tab.

## Quick Start

```python
import pybridge_browser

# Connect to the PyBridge extension and auto-attach to the active tab
browser = pybridge_browser.connect()

page = browser.page

# Navigate
page.goto("https://example.com")

# Interact
page.click("button#submit")
page.fill("#username", "hello")
page.fill("#password", "world")

# Screenshot
page.screenshot("screenshot.png")

# Get page info
print(page.title)  # "Example Domain"
print(page.url)    # "https://example.com"

# Execute JavaScript
result = page.evaluate("document.querySelectorAll('a').length")

# Disconnect (browser stays open)
browser.close()
```

### Context manager

```python
with pybridge_browser.connect() as browser:
    page = browser.page
    page.goto("https://example.com")
    print(page.title)
# browser.close() called automatically
```

## API Reference

### `pybridge_browser.connect(port=8765, hello_timeout=100, verbose=True, auto_attach=True, tab_id=None)`

Connect to the PyBridge extension. Returns a `Browser` object.

| Parameter | Default | Description |
|---|---|---|
| `port` | `8765` | WebSocket bridge port (must match extension config) |
| `hello_timeout` | `100` | Max seconds to wait for the extension handshake |
| `verbose` | `True` | Print progress info |
| `auto_attach` | `True` | Auto-attach to the active tab on connect |
| `tab_id` | `None` | Specific tab to attach to (default: active tab) |

### `Browser`

| Method / Property | Description |
|---|---|
| `browser.page` | Get the current attached `Page` object |
| `browser.pages` | List of attached pages (always length 1) |
| `browser.list_tabs()` | List attachable tabs: `[{tabId, url, title, active}]` |
| `browser.attach(tab_id)` | Attach to a specific tab |
| `browser.detach()` | Detach from current tab (browser stays connected) |
| `browser.close()` | Detach + shut down bridge (browser stays open) |

### `Page`

| Method / Property | Description |
|---|---|
| `page.goto(url, timeout=60)` | Navigate and wait for load |
| `page.click(selector, timeout=30)` | Click element (mouse + JS fallback) |
| `page.fill(selector, value, timeout=30)` | Fill input (React-compatible) |
| `page.type_text(selector, text, timeout=30)` | Type text via CDP (keystroke-level) |
| `page.press(selector, key, timeout=30)` | Press a key on an element |
| `page.key_press(key)` | Send key to focused element |
| `page.inner_text(selector, timeout=30)` | Get element's visible text |
| `page.text_content(selector, timeout=30)` | Get element's textContent |
| `page.get_attribute(selector, name, timeout=30)` | Get element attribute |
| `page.select_option(selector, value, timeout=30)` | Set `<select>` value |
| `page.is_visible(selector, timeout=5)` | Check if element is visible |
| `page.wait_for_selector(selector, timeout=30)` | Wait for element to appear |
| `page.wait_for_load_state(state="load", timeout=60)` | Wait for page load |
| `page.screenshot(path=None, full_page=False)` | Take screenshot (PNG) |
| `page.evaluate(js, timeout=30)` | Execute JavaScript |
| `page.content()` | Get page HTML |
| `page.title` | Page title (property) |
| `page.url` | Page URL (property) |

### Exceptions

| Exception | Description |
|---|---|
| `PyBridgeError` | Base exception |
| `PyBridgeTimeoutError` | Operation timed out |
| `TimeoutError` | Alias for `PyBridgeTimeoutError` |
| `ElementNotFoundError` | Element not found within timeout |

## CLI Usage

```bash
# Connect and enter interactive console
pybridge-browser

# Or via module
python -m pybridge_browser

# List attachable tabs
python -m pybridge_browser --list

# Open URL then enter console
python -m pybridge_browser --url https://example.com

# Attach to specific tab
python -m pybridge_browser --tab 123

# Direct URL (positional argument)
python -m pybridge_browser https://example.com
```

### Console commands

```
tabs          List tabs
attach <id>   Attach to tab
nav <url>     Navigate
eval <js>     Execute JavaScript
click <sel>   Click element
fill <sel> <value>  Fill input
shot [path]   Screenshot
title         Print page title
url           Print page URL
detach        Detach from tab
quit          Exit
```

## How It Works

```
┌─────────────┐    WebSocket (ws://127.0.0.1:8765)    ┌──────────────────┐
│  Python      │◄──────────────────────────────────────►│  Chrome Extension │
│  pybridge_   │                                        │  (chrome.debugger)│
│  browser     │    CDP commands / responses            │        │
│              │◄──────────────────────────────────────►│        ▼          │
└─────────────┘                                        │  Active Tab       │
                                                       │  (your webpage)   │
                                                       └──────────────────┘
```

1. Python starts a local WebSocket server on port 8765.
2. The Chrome extension connects to it.
3. Python sends CDP (Chrome DevTools Protocol) commands through the extension's `chrome.debugger` API.
4. The extension forwards commands to the tab and returns results.

**No remote debugging port is opened. No new browser is launched.**

## Dependencies

- Python 3.8+
- [`websockets`](https://pypi.org/project/websockets/) >= 12.0

## License

[MIT](LICENSE)

## Author

Walker Deng — walker.deng@acqu.co

---

# 中文文档

## 为什么用 pybridge-browser？

传统浏览器自动化（Selenium、Playwright、Puppeteer）需要**启动新浏览器**或通过 `--remote-debugging-port` 连接，这意味着：

- ❌ 丢失登录状态、Cookie 和扩展
- ❌ 需要重启浏览器并加特殊参数
- ❌ 容易被反爬检测

**pybridge-browser** 通过 Chrome 扩展（`chrome.debugger` API）直接接管**已打开的浏览器**，保留一切现场。

## 安装

```bash
pip install pybridge-browser
```

## 前置条件（一次性）

> ⚠️ **必须搭配浏览器插件才能正常使用**：本包不能独立工作，需要先安装 PyBridge 浏览器扩展：
> **[PyBridge - Python WebSocket Bridge](https://github.com/dengwanghui1/Personalized_browser_plug_ins/tree/master/PyBridge%20-%20Python%20WebSocket%20Bridge)**

1. **加载 PyBridge 扩展** — 从 [PyBridge - Python WebSocket Bridge](https://github.com/dengwanghui1/Personalized_browser_plug_ins/tree/master/PyBridge%20-%20Python%20WebSocket%20Bridge) 下载扩展，然后打开 `chrome://extensions`，开启右上角**开发者模式**，点击**加载已解压的扩展程序**，选择下载好的 PyBridge 扩展目录。

2. **保持浏览器打开**，且至少有一个普通网页标签页。

## 快速上手

```python
import pybridge_browser

browser = pybridge_browser.connect()
page = browser.page

page.goto("https://example.com")
page.click("button#submit")
page.fill("#username", "hello")
page.screenshot("shot.png")
print(page.title, page.url)

browser.close()  # 断开接管，浏览器保持打开
```

## 工作原理

Python 启动本地 WebSocket 服务 → Chrome 扩展连接 → 通过 `chrome.debugger` API 转发 CDP 命令到标签页。**不开调试端口、不重启浏览器**。

## 依赖

- Python 3.8+
- `websockets` >= 12.0

## 许可证

[MIT](LICENSE)
