本文档记录了从 go-playwright 到 py-playwright 的迁移过程,展示了 Go 代码和 Python 代码的对应关系。
| Go 文件 | Python 文件 | 说明 |
|---|---|---|
chrome.go |
chrome.py |
Chrome 浏览器启动和关闭 |
ext_playwright.go |
ext_playwright.py |
Playwright 核心配置 |
ext_browser_context.go |
ext_browser_context.py |
浏览器上下文管理 |
ext_page.go |
ext_page.py |
页面操作扩展 |
ext_locator.go |
ext_locator.py |
元素定位器扩展 |
chrome_test.go |
test_chrome.py |
Chrome 测试 |
scripts/shell/install.sh |
scripts/shell/install.sh |
安装脚本 |
scripts/shell/driver.sh |
scripts/shell/driver.sh |
驱动脚本 |
scripts/shell/browsers.sh |
scripts/shell/browsers.sh |
浏览器脚本 |
scripts/shell/chrome.sh |
scripts/shell/chrome.sh |
Chrome 启动脚本 |
Go:
func StartChrome(debugPort int) (*exec.Cmd, string, error) {
homeDir, _ := os.UserHomeDir()
userDataDir := homeDir + "/ChromeProfile"
// ...
}Python:
def start_chrome(debug_port: int = 0) -> Tuple[Optional[subprocess.Popen], str]:
home_dir = os.path.expanduser("~")
user_data_dir = os.path.join(home_dir, "ChromeProfile")
# ...Go:
type ExtPlaywrightOption struct {
SkipInstallBrowsers bool `json:"skipInstallBrowsers"`
Headless bool `json:"headless"`
BrowserType string `json:"browserType"`
// ...
}Python:
class ExtPlaywrightOption:
def __init__(
self,
skip_install_browsers: bool = False,
headless: bool = False,
browser_type: str = BrowserTypeNames.Chrome,
# ...
):
self.skip_install_browsers = skip_install_browsers
self.headless = headless
self.browser_type = browser_type
# ...Go:
type ExtPage struct {
playwright.Page
extBC *ExtBrowserContext
locked bool
suspended bool
}
func (p *ExtPage) NavigateWithLoadedState(ctx *dgctx.DgContext, url string) error {
// ...
}Python:
class ExtPage:
def __init__(self, page: Page, ext_bc: ExtBrowserContext, locked: bool = False):
self.page = page
self.ext_bc = ext_bc
self.locked = locked
self.suspended = False
def navigate_with_loaded_state(self, url: str):
# ...Go:
type ExtLocator struct {
extPage *ExtPage
playwright.Locator
selectors []string
}
func (l *ExtLocator) MustInnerText(ctx *dgctx.DgContext) string {
if !l.Exists(ctx) {
return ""
}
// ...
}Python:
class ExtLocator:
def __init__(self, ext_page: ExtPage, locator: Locator, selectors: List[str]):
self.ext_page = ext_page
self.locator = locator
self.selectors = selectors
def must_inner_text(self) -> str:
if not self.exists():
return ""
# ...- Go: 使用
PascalCase导出的函数和类型 - Python: 使用
snake_case函数和方法
- Go: 返回
(result, error)元组 - Python: 使用异常
try/except
- Go: 使用
context.Context传递上下文 - Python: 使用
with语句和上下文管理器
- Go: 使用 goroutines 和 channels
- Python: 使用
threading模块
- Go: 使用
go.mod和go.sum - Python: 使用
requirements.txt和pyproject.toml
| Go 依赖 | Python 依赖 |
|---|---|
github.com/playwright-community/playwright-go |
playwright |
github.com/gorilla/websocket |
websocket-client |
github.com/go-ole/go-ole |
winreg (Windows only) |
github.com/darwinOrg/go-logger |
logging |
github.com/darwinOrg/go-common |
自定义工具函数 |
所有 Go 版本的核心功能都已迁移到 Python 版本:
- ✅ Chrome 浏览器启动和关闭
- ✅ CDP 连接支持
- ✅ 扩展浏览器上下文
- ✅ 扩展页面操作
- ✅ 扩展定位器操作
- ✅ 随机等待功能
- ✅ 暂停/继续功能
- ✅ 页面重连功能
- ✅ 跨平台支持(Windows、macOS、Linux)
extPwOpt := &ExtPlaywrightOption{
Headless: false,
BrowserType: MyBrowserType.Chrome,
}
extBC, err := NewDebugExtBrowserContext(ctx, extPwOpt)
if err != nil {
log.Fatal(err)
}
extPage, err := extBC.GetOrNewExtPage(ctx)
if err != nil {
log.Fatal(err)
}
err = extPage.NavigateWithLoadedState(ctx, "https://example.com")
if err != nil {
log.Fatal(err)
}ext_pw_opt = ExtPlaywrightOption(
headless=False,
browser_type=BrowserTypeNames.Chrome
)
ext_bc = ExtBrowserContext.new_debug_ext_browser_context(ext_pw_opt)
ext_page = ext_bc.get_or_new_ext_page()
ext_page.navigate_with_loaded_state("https://example.com")go test -vpytest test_chrome.py -v
# 或
python test_chrome.pygo get github.com/darwinOrg/go-playwrightpip install -r requirements.txt
playwright install --with-depsPython 版本保持了与 Go 版本相同的 API 设计和功能特性,同时遵循 Python 的语言习惯和最佳实践。所有核心功能都已完整迁移,可以直接使用。