# 纯视觉网页自动化示例

真实世界中基于纯视觉的网页自动化任务示例。

---

## 示例 1：在百度搜索

**任务**：在百度搜索"人工智能"并验证结果

```python
from vision_browser.browser import Browser

browser = Browser(headless=False, window_width=1280, window_height=800)
browser.start()

# 步骤 1：导航到百度
browser.goto("https://www.baidu.com")

# 步骤 2：截取带网格的截图以找到搜索框
grid_img = browser.screenshot_with_grid(cols=16, rows=10)
# 分析：搜索框中心大约在 (640, 350)

# 步骤 3：点击并输入搜索查询
browser.click_and_type(640, 350, "人工智能", clear=True)

# 步骤 4：按回车键搜索
browser.press_key("enter")

# 步骤 5：验证结果已加载
result_img = browser.screenshot_base64()
# 分析：结果页面成功加载

browser.close()
```

**关键点**：
- 首先使用网格截图识别坐标
- 瞄准搜索输入框的中心
- 输入前清除现有内容
- 用截图验证每一步

---

## 示例 2：表单填写和提交

**任务**：填写联系表单，包括姓名、邮箱、消息，然后提交

```python
from vision_browser.browser import Browser

browser = Browser(headless=False)
browser.start()
browser.goto("https://example.com/contact")

# 分析页面布局
img = browser.screenshot_with_grid()
# 识别的坐标：
# 姓名字段：(400, 250)
# 邮箱字段：(400, 320)
# 消息文本框：(640, 450)
# 提交按钮：(640, 600)

# 填写姓名
browser.click_and_type(400, 250, "张三")

# 填写邮箱
browser.click_and_type(400, 320, "zhangsan@example.com")

# 填写消息
browser.click_and_type(640, 450, "这是一条测试消息")

# 截图验证所有字段已填写
browser.save_screenshot("/tmp/form_filled.png")

# 提交表单
browser.click(640, 600)

# 验证提交
browser.screenshot_base64()
# 在截图中检查成功消息

browser.close()
```

**关键点**：
- 对每个输入字段使用 `click_and_type()`
- 保存中间截图用于调试
- 提交前验证表单状态

---

## 示例 3：滚动并点击元素

**任务**：向下滚动找到"加载更多"按钮并点击它

```python
from vision_browser.browser import Browser

browser = Browser()
browser.start()
browser.goto("https://example.com/gallery")

# 初始截图
img1 = browser.screenshot_base64()
# "加载更多"还不可见

# 向下滚动 500 像素
browser.scroll(direction="down", pixels=500)

# 检查按钮现在是否可见
img2 = browser.screenshot_with_grid()
# 按钮在 (640, 700) 处找到

# 点击"加载更多"
browser.click(640, 700)

# 验证更多内容已加载
browser.screenshot_base64()
# 新项目出现了

browser.close()
```

**关键点**：
- 滚动以显示屏幕外元素
- 滚动后使用网格截图找到新坐标
- 点击后验证内容变化

---

## 示例 4：多步导航

**任务**：导航 GitHub → 搜索仓库 → 打开第一个结果

```python
from vision_browser.browser import Browser

browser = Browser(window_width=1280, window_height=800)
browser.start()

# 步骤 1：前往 GitHub
browser.goto("https://github.com")
browser.screenshot_with_grid()
# 搜索框在 (640, 80)

# 步骤 2：搜索"web automation"
browser.click_and_type(640, 80, "web automation")
browser.press_key("enter")

# 步骤 3：等待结果页面
browser.screenshot_with_grid()
# 第一个结果标题在 (350, 250)

# 步骤 4：点击第一个结果
browser.click(350, 250)

# 步骤 5：验证仓库页面已加载
final_url = browser.get_url()
print(f"最终 URL: {final_url}")

browser.close()
```

**关键点**：
- 为复杂工作流链接多个操作
- 使用 `get_url()` 验证导航
- 在每个导航步骤截取网格截图

---

## 示例 5：下拉菜单/选择交互

**任务**：打开下拉菜单并选择一个选项

```python
from vision_browser.browser import Browser

browser = Browser()
browser.start()
browser.goto("https://example.com/form")

# 步骤 1：识别下拉菜单
browser.screenshot_with_grid()
# 下拉菜单在 (500, 350)

# 步骤 2：点击打开下拉菜单
browser.click(500, 350)

# 步骤 3：等待并截取打开的下拉菜单
browser.screenshot_with_grid()
# 选项"高级"在 (500, 420)

# 步骤 4：点击所需选项
browser.click(500, 420)

# 步骤 5：验证选择
browser.screenshot_base64()
# 下拉菜单现在显示"高级"

browser.close()
```

**关键点**：
- 首先点击下拉菜单以显示选项
- 下拉菜单打开后截取新截图
- 根据选项在打开菜单中的位置点击

---

## 示例 6：错误恢复 - 使用不同坐标重试

**任务**：处理第一次点击尝试失败的情况

```python
from vision_browser.browser import Browser

browser = Browser()
browser.start()
browser.goto("https://example.com")

# 第一次尝试
browser.screenshot_with_grid()
browser.click(640, 400)  # 尝试点击按钮

# 验证操作是否成功
browser.screenshot_base64()
# 分析：按钮未被点击，没有状态变化

# 第二次尝试，调整坐标
browser.screenshot_with_grid()  # 重新分析
browser.click(650, 410)  # 稍微不同的位置

# 再次验证
browser.screenshot_base64()
# 成功：按钮被点击，状态改变了

browser.close()
```

**关键点**：
- 始终用截图验证操作
- 如果第一次尝试失败，用调整后的坐标重试
- 使用网格截图细化坐标估计

---

## 示例 7：悬停显示隐藏菜单

**任务**：悬停在导航项上显示子菜单，然后点击

```python
from vision_browser.browser import Browser

browser = Browser()
browser.start()
browser.goto("https://example.com")

# 步骤 1：识别导航项
browser.screenshot_with_grid()
# "产品"菜单在 (300, 60)

# 步骤 2：悬停显示子菜单
browser.hover(300, 60)

# 步骤 3：捕获子菜单
browser.screenshot_with_grid()
# "产品 A"子菜单项在 (320, 120)

# 步骤 4：点击子菜单项
browser.click(320, 120)

# 验证导航
print(f"导航到: {browser.get_url()}")

browser.close()
```

**关键点**：
- 对下拉菜单使用 `hover()`
- 悬停后截图查看显示的元素
- 悬停后快速点击子菜单项

---

## 调试技巧

### 使用标注截图
```python
# 标记你即将点击的位置
annotated = browser.annotated_screenshot(640, 400, "登录按钮")
# 保存以供检查
with open("/tmp/debug.png", "wb") as f:
    import base64
    f.write(base64.b64decode(annotated))
```

### 保存网格截图
```python
# 保存网格截图作为坐标参考
grid = browser.screenshot_with_grid()
with open("/tmp/grid.png", "wb") as f:
    import base64
    f.write(base64.b64decode(grid))
# 打开 /tmp/grid.png 查看坐标标签
```

### 记录操作
```python
import logging
logging.basicConfig(level=logging.INFO)
# Browser 类已经记录所有带坐标的操作
```

---

## 常见模式

### 模式 1：等待元素
```python
# 滚动直到目标可见
for _ in range(5):
    browser.screenshot_base64()
    # 检查元素在截图中是否可见
    if element_visible:
        break
    browser.scroll("down", 300)
```

### 模式 2：多字段表单
```python
fields = [
    (400, 200, "张三"),
    (400, 280, "zhang@example.com"),
    (400, 360, "1234567890"),
]
for x, y, text in fields:
    browser.click_and_type(x, y, text)
```

### 模式 3：验证状态变化
```python
before = browser.screenshot_base64()
browser.click(640, 400)
after = browser.screenshot_base64()
# 比较截图以验证操作效果
```

---

## 与视觉模型集成

```python
from anthropic import Anthropic
from vision_browser.browser import Browser
import base64

client = Anthropic()
browser = Browser()
browser.start()
browser.goto("https://example.com")

# 获取截图
img_b64 = browser.screenshot_with_grid()

# 询问视觉模型该做什么
response = client.messages.create(
    model="claude-4-6",
    max_tokens=1024,
    messages=[{
        "role": "user",
        "content": [
            {
                "type": "image",
                "source": {
                    "type": "base64",
                    "media_type": "image/png",
                    "data": img_b64,
                },
            },
            {
                "type": "text",
                "text": "找到登录按钮并告诉我它的坐标，格式为：x,y"
            }
        ],
    }]
)

# 解析坐标并执行
# coords = parse_response(response.content[0].text)
# browser.click(coords[0], coords[1])

browser.close()
```

---

## 完整自动化脚本示例

### 示例：自动登录网站

```python
from vision_browser.browser import Browser
import time

def auto_login(username: str, password: str):
    """使用纯视觉自动化登录网站"""
    browser = Browser(headless=False)
    browser.start()

    try:
        # 1. 导航到登录页面
        print("导航到登录页面...")
        browser.goto("https://example.com/login")
        time.sleep(2)

        # 2. 分析页面并找到输入框
        print("分析页面布局...")
        browser.screenshot_with_grid()

        # 3. 填写用户名（假设在 640, 300）
        print("填写用户名...")
        browser.click_and_type(640, 300, username)

        # 4. 填写密码（假设在 640, 380）
        print("填写密码...")
        browser.click_and_type(640, 380, password)

        # 5. 点击登录按钮（假设在 640, 460）
        print("点击登录...")
        browser.click(640, 460)

        # 6. 等待并验证登录成功
        time.sleep(3)
        current_url = browser.get_url()
        print(f"登录后 URL: {current_url}")

        # 保存最终截图
        browser.save_screenshot("/tmp/login_result.png")
        print("✅ 登录流程完成！")

    finally:
        browser.close()

# 使用示例
if __name__ == "__main__":
    auto_login("myusername", "mypassword")
```

### 示例：电商搜索和添加购物车

```python
from vision_browser.browser import Browser

def shop_automation(search_keyword: str):
    """搜索商品并添加到购物车"""
    browser = Browser(window_width=1280, window_height=800)
    browser.start()

    try:
        # 1. 访问电商网站
        print("访问淘宝...")
        browser.goto("https://www.taobao.com")

        # 2. 搜索商品
        print(f"搜索: {search_keyword}")
        browser.screenshot_with_grid()
        browser.click_and_type(500, 100, search_keyword)
        browser.press_key("enter")

        # 3. 等待搜索结果
        browser.screenshot_with_grid()

        # 4. 点击第一个商品（坐标需根据实际页面调整）
        print("点击第一个商品...")
        browser.click(300, 350)

        # 5. 滚动查看商品详情
        browser.scroll("down", 500)
        browser.screenshot_base64()

        # 6. 点击"加入购物车"按钮
        print("添加到购物车...")
        browser.click(800, 600)

        print("✅ 商品已添加到购物车！")

    finally:
        browser.close()

# 使用示例
if __name__ == "__main__":
    shop_automation("机械键盘")
```

---

## 高级技巧

### 技巧 1：动态坐标计算

```python
# 根据视口大小动态计算坐标
width, height = browser.get_viewport_size()
center_x = width // 2
center_y = height // 2

# 点击屏幕中心
browser.click(center_x, center_y)
```

### 技巧 2：截图对比

```python
import imagehash
from PIL import Image
import io
import base64

def screenshots_differ(img1_b64: str, img2_b64: str) -> bool:
    """比较两个截图是否不同"""
    img1 = Image.open(io.BytesIO(base64.b64decode(img1_b64)))
    img2 = Image.open(io.BytesIO(base64.b64decode(img2_b64)))

    hash1 = imagehash.average_hash(img1)
    hash2 = imagehash.average_hash(img2)

    return hash1 != hash2

# 使用
before = browser.screenshot_base64()
browser.click(640, 400)
after = browser.screenshot_base64()

if screenshots_differ(before, after):
    print("✅ 页面已变化")
else:
    print("❌ 页面未变化，可能点击失败")
```

### 技巧 3：重试机制

```python
def click_with_retry(browser, x: int, y: int, max_attempts: int = 3):
    """带重试的点击"""
    for attempt in range(max_attempts):
        before = browser.screenshot_base64()
        browser.click(x, y)
        after = browser.screenshot_base64()

        if screenshots_differ(before, after):
            print(f"✅ 点击成功 (尝试 {attempt + 1})")
            return True

        print(f"⚠️ 点击可能失败，重试 {attempt + 1}/{max_attempts}")
        x += 5  # 微调坐标
        y += 5

    print("❌ 所有尝试均失败")
    return False
```

---

这些示例展示了在没有任何 DOM 访问的情况下进行纯视觉驱动的自动化。根据你的具体任务进行调整，并始终用截图验证每个操作。
