Metadata-Version: 2.1
Name: autowk
Version: 0.3.7
Summary: 基于WebKit的自动化浏览器框架
Home-page: https://github.com/LoseNine/AutoWK
Author: ruyi
Author-email: losenine@163.com
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: Microsoft :: Windows
Requires-Python: >=3.7
Description-Content-Type: text/markdown

## AutoWK 自动化浏览器框架
> 🚀 一个基于原生 WebKit二次开发的自动化浏览器框架，自带指纹反检测浏览器，支持命令行参数控制窗口位置与代理配置，并通过 Python 客户端驱动自动操作浏览器。
<p align="center">
  <img src="icon.png" alt="AutoWK Logo" width="230">
</p>

## ✨ 项目亮点

- ✅ 🧠 基于 `WebKit` 源码构建，小而精致的浏览器内核
- ✅ 🛠️ 支持全屏幕截图，`长图`自动一键截图
- ✅ 📜 支持命令行传参（窗口位置、尺寸、代理类型、代理认证）
- ✅ 💪 网络改造，支持 `HTTP/SOCKS5` 等代理模式
- ✅ 📏 `Python API` 调用控制浏览器行为
- ✅ 🧪 人类行为模拟，底层行为重写，自定义行为动作都是`isTrusted`
- ✅ 📁 每个`窗口隔离`，支持自定义缓存、数据库、本地存储和Cookie路径
- ✅ 🧿 关键`指纹`修改，规避指纹检测，动态修改指纹
- ✅ 🪄 实现对`shadow root`的访问，包括closed的节点，过shadowroot检测
- ✅ 👻 实现`无头模式`，不渲染窗体，WebKit 基础上再添极致性能

---


## 快速开始
> 🚀 交流群QQ：391116392
1. 安装依赖：

   ```bash
   pip install autowk==0.3.7
   ```

2. 编写代码，启动自动化：

### 示例代码 ：过steam的定制5s盾
```python
from autowk.AutoWkDriverClient import AutoWK
import time

if __name__ == "__main__":
    client = AutoWK(lang="en-US",timezone="America/Chicago")
    try:
        client.create_session()

        print("[STATUS]", client.status())

        client.set_timeouts({"pageLoad": 10000})
        print("[GET TIMEOUTS]", client.get_timeouts())
        
        client.navigate(r"https://steamdb.info/")
        print("[URL]", client.get_current_url())

        time.sleep(10)
        #坐标直接用操作系统的截图，然后画板打开看x和y坐标，浏览器左上角是坐标0,0
        client.click_pos_by_win(266,326)
        print('拖拽完毕')


    except Exception as e:
        print(e)

    finally:
        time.sleep(500)
        client.delete_session()
        client.close()
```
### 示例代码 ：过12306滑块验证码
```python
from autowk.AutoWkDriverClient import AutoWK
import time

"""自动化1236滑块验证码"""
client = AutoWK(lang="en-US",timezone="America/Chicago")try:
client.create_session()

print("[STATUS]", client.status())

client.set_timeouts({"pageLoad": 10000})
print("[GET TIMEOUTS]", client.get_timeouts())

client.navigate(r"https://www.12306.cn/index/view/infos/ticket_check.html")
print("[URL]", client.get_current_url())

#输入座次
input_ele=client.find_element_by_css_selector("input#ticket_check_trainNum").input("1462")

time.sleep(3)
#选择地点
drap=client.find_element_by_css_selector("div.model-select-text")
drap.set_attribute("data-value","TXP")
print('attr:', drap.get_attribute("data-value"))
print('选择完毕')

time.sleep(3)
#拖拽滑块验证码
btn=client.find_element_by_css_selector("li a.btn.btn-primary").click()
time.sleep(5)
#拖拽滑块验证码，这里用的是拖拽模拟人类行为，所以用的是drag_and_drop_pos_human方法
#坐标需要自己定位一下
client.drag_and_drop_pos_human(525,436,848,436)
print('拖拽完毕')
```
### 示例代码 ：切换iframe，并操作iframe元素
```python
from autowk.AutoWkDriverClient import AutoWK
import time

client = AutoWK()
client.create_session()

print("[STATUS]", client.status())

client.set_timeouts({"pageLoad": 10000})
print("[GET TIMEOUTS]", client.get_timeouts())
client.navigate(r"")

#本地测试html文件，需要自己改成自己的路径，可以从testhtml获取HTML文件路径
client.navigate(r"file://D:\\Python\\pycode\\2025\\autowk\\testhtml\\frame.html")
print("[URL]", client.get_current_url())

time.sleep(2)
frame_ele=client.find_element_by_css_selector("#innerFrame")
print("[FRAME]", frame_ele)
res=client.switch_to_frame(frame_ele)
print("[SWITCH TO FRAME]", res)

input_ele=client.find_element_by_css_selector("#ruyi")
input_ele.input("ruyiinput")

cli_ele=client.find_element_by_css_selector("#ruyiclick")
cli_ele.click()
print("clicked")
time.sleep(3)
input_ele.clear()
```

### 示例代码 ：切换shadowroot，并操作shadow元素
```python
from autowk.AutoWkDriverClient import AutoWK
import time

client = AutoWK()
client.create_session()

print("[STATUS]", client.status())

client.set_timeouts({"pageLoad": 10000})
print("[GET TIMEOUTS]", client.get_timeouts())
client.navigate(r"")

client.navigate(r"file://D:\\Python\\pycode\\2025\\autowk\\testhtml\\shadowroot.html")
print("[URL]", client.get_current_url())

time.sleep(2)
#open状态的shadowroot
# host_ele=client.find_element_by_css_selector("#host").get_shadow_root()
# print("[SHADOW]", host_ele)
# cli_ele=host_ele.find_element_by_css_selector("#clickable").click()
# print("[CLICKABLE]",cli_ele)

#closed状态的shadowroot
host_ele=client.get_closed_shadow_root("#host")
print("[SHADOW CLOSED]", host_ele)
host_ele.find_element_by_css_selector("#clickable").click()
print("[CLOSED CLICKABLE]")
```
---

#### 支持的启动命令行参数（MiniBrowser.exe）

| 参数                 | 示例                                                                 | 说明                         |
|--------------------|--------------------------------------------------------------------|----------------------------|
| `--x=`             | `--x=100`                                                          | 设置窗口左上角 X 坐标               |
| `--y=`             | `--y=200`                                                          | 设置窗口左上角 Y 坐标               |
| `--width=`         | `--width=1280`                                                     | 设置窗口宽度                     |
| `--height=`        | `--height=720`                                                     | 设置窗口高度                     |
| `--height=`        | `--height=720`                                                     | 设置窗口高度                     |
| 语言时区               | ----------------------------------                                 | -------------------------- |
| `--lang=`          | `--lang=en-US`                                                     | 设置浏览器内部所有语言                |
| `--timezone=`      | `--timezone=America/Chicago`                                       | 设置浏览器内部时区                  |
| 密码代理               | ----------------------------------                                 | -------------------------- |
| `--proxyType=`     | `--proxyType=HTTP`                                                 | 代理类型：`HTTP` / `SOCKS5` 等   |
| `--proxyHost=`     | `--proxyHost=127.0.0.1`                                            | 代理服务器地址                    |
| `--proxyPort=`     | `--proxyPort=1080`                                                 | 代理端口                       |
| `--proxyUsername=` | `--proxyUsername=admin`                                            | 代理认证用户名                    |
| `--proxyPassword=` | `--proxyPassword=123456`                                           | 代理认证密码                     |
| 启动页面               | ----------------------------------                                 | -------------------------- |
| `--url=`           | `--url=https://www.baidu.com`                                      | 设置启动页面                     |
| 窗口数据隔离             | ----------------------------------                                 | -------------------------- |
| `--userDataDir=`   | `--userDataDir=C://webdata//1` <br/>`--userDataDir=C://webdata//2` | 设置用户缓存目录                   |
| 指纹修改配置文件           | ----------------------------------                                 | -------------------------- |
| `--fpfile=`        | `--fpfile=C:\webkit\fp_config1.txt`                                | 设置指纹配置文件                   |
| 设置UA               | ----------------------------------                                 | -------------------------- |
| `--userAgent=`     | `--userAgent=webkit` | 设置UA                       |
| 无头模式               | ----------------------------------                                 | -------------------------- |
| `--headless`       | `--headless` | 直接添加即开启无头模式                |

#### 无密码代理
```bash
minibrowser.exe --proxyType=http  --proxyHost=127.0.0.1  --proxyPort=7890 
```
#### 密码代理
```cmd
例子:minibrowser.exe --proxyType=SOCKS5  --proxyHost=1.1.1.1  --proxyPort=1000 --proxyUsername=ruyi  --proxyPassword=wifi 
```
---

### 指纹修改配置文件支持的指纹（启动参数中的指纹修改配置文件）
| 参数                 | 示例           | 说明                     |
|--------------------|--------------|------------------------|
| `unmasked_renderer` | `Apple GPU`  | 设置显卡版本                 |
| `unmasked_vendor`   | `Apple Inc.` | 设置显卡厂商                 |
| `canvas_noise`      | `10`         | 设置canvas随机种子，任意数字      |
| `clientrect_noise`   | `2`          | 设置clientrect随机种子，int数字 |
| `hardwareConcurrency` | `8`          | 设置计算机核心数               |
| `maxTouchPoints` | `5`          | 设置触摸屏                  |
fp_config1.txt配置文件示例：

```txt
unmasked_renderer=Apple GPU
unmasked_vendor=Apple Inc.
canvas_noise=500
clientrect_noise=20
hardwareConcurrency=16
maxTouchPoints=0
```
##### ** 如果是手机UA的话，maxTouchPoints需要设置，如果是PC，maxTouchPoints设置0

---

# `AutoWK` 接口方法说明

继承自 `AutoWKBase`，`AutoWkDriverClient`提供了 WebKit 浏览器的自动化操作封装。

---

## ✅ 初始化方法

### `__init__(host="127.0.0.1", port=12345, x=0, y=0, width=10, height=10, lang="en-US", timezone="America/Chicago")`
初始化 WebKit 实例，连接到指定端口并设置视图和语言。

---

## 🍪 Cookie 操作

### `get_all_cookies()`
获取当前会话所有 Cookie。

### `get_cookie_by_name(name)`
获取指定名称的 Cookie。

- `name`: Cookie 名称（字符串）

### `add_cookie(cookie)`
添加一个 Cookie。

- `cookie`: 字典，需包含 name、value、domain、path 等键

### `delete_cookie(name)`
删除指定名称的 Cookie。

### `delete_all_cookies()`
删除当前页面的所有 Cookie。

---

## 💾 存储与清理

### `clear_websitedata()`
清理网站数据。

---

## 🔄 会话与状态

### `status()`
获取 WebDriver 服务状态。

### `get_timeouts()`
获取当前超时设置。

### `set_timeouts(timeouts)`
设置超时时间。

- `timeouts`: 包含 `script`, `pageLoad`, `implicit` 的字典

### `wait_for_element(using, selector,timeout: float = 10.0, interval: float = 0.5)`
等待元素出现，返回等待的元素。

- `using`: 包含 `css selector`, `xpath`两种模式
- `selector`: 使用的具体查询规则
- `timeout`: 等待时间
- `interval`: 轮询间隔

---

## 🌐 页面控制

### `navigate(url)`
跳转到指定 URL。

### `get_current_url()`
获取当前页面 URL。

### `get_useragent()`
获取当前 User-Agent。

### `set_useragent(useragent_name)`
设置 User-Agent。

---

## 🔙 页面导航

### `back()`
浏览器后退。

### `forward()`
浏览器前进。

### `refresh()`
刷新当前页面。

---

## 📄 页面信息

### `get_title()`
获取页面标题。

### `get_page_source()`
获取页面 HTML 源码。

---

## 🪟 窗口控制

### `maximize_window()`
最大化窗口。

### `minimize_window()`
最小化窗口。

### `get_window_rect()`
获取窗口的位置和大小。

### `set_window_rect(x=None, y=None, width=None, height=None)`
设置窗口的位置和大小。

### `get_window_handles()`
获取所有窗口句柄。

### `get_window_handle()`
获取当前窗口句柄。

### `close_window()`
关闭当前窗口。

### `switch_to_window(handle)`
切换到指定窗口。

### `new_window(window_type="tab")`
创建新窗口或标签页。

---

## 📜 脚本执行

### `execute_script(script, args=[])`
执行 JavaScript 脚本并返回结果。

---
### `get_closed_shadow_root(self,css_selector)`
- **说明**：获取关闭状态的shadow root。
- **参数**：获取节点的css语法规则。
- **返回**：shadowroot节点。

---

## 📷 截图

### `take_screenshot(filename="screenshot.png")`
对当前页面截图保存为文件。

---

## 🧱 Frame 操作

### `switch_to_frame(iframe)`
切换到指定 iframe。支持传入 Element 或 ID。

### `switch_to_parent_frame()`
切换到当前iframe的父窗口。
---

## 🔍 元素查找

### `find_element_by_css_selector(selector)`
通过 CSS 选择器查找元素。

### `find_elements_by_css_selector(selector)`
通过 CSS 选择器查找多个元素。

### `find_element_by_xpath(selector)`
通过 XPath 查找元素。

### `find_elements_by_xpath(selector)`
通过 XPath 查找多个元素。

---

## 🖱️ 鼠标点击

### `click_pos_by_js(x, y)`
使用 JavaScript 方式点击页面上的指定位置。

### `click_pos_by_win(x, y)`
使用 WebDriver Actions API 模拟点击。

---

## 📦 拖拽操作

### `drag_and_drop_pos(start_x, start_y, end_x, end_y)`
模拟从起点拖拽到终点（标准 WebDriver 操作）。

### `drag_and_drop_pos_human(start_x, start_y, end_x, end_y, num_steps=30)`
模拟人类手势的拖拽（使用贝塞尔曲线+缓动插值）。

---

## 📌 附加说明

- 所有函数默认使用当前 `session_id`，请确保已成功连接 WebDriver。
- 返回值通常为 `dict`，或直接返回值（如元素对象、URL、标题等）。


## Element 类方法接口说明

### `get_attribute(name)`
- **说明**：获取元素的属性值。
- **参数**：
  - `name`：属性名称。
- **返回**：属性值。

---

### `set_attribute(attribute_name, value)`
- **说明**：通过执行 JS 脚本设置元素的属性值。
- **参数**：
  - `attribute_name`：属性名称。
  - `value`：属性值。
- **返回**：`self`（链式调用）。

---

### `get_text()`
- **说明**：获取元素的文本内容。
- **返回**：字符串。

---

### `get_rect()`
- **说明**：获取元素的位置信息（x, y, width, height）。
- **返回**：字典对象。

---

### `is_displayed()`
- **说明**：判断元素是否可见。
- **返回**：布尔值。

---

### `click()`
- **说明**：模拟点击该元素。
- **返回**：响应结果。

---

### `clear()`
- **说明**：模拟清除输入框文字。
- **返回**：响应结果。

---

### `input(text)`
- **说明**：向输入框输入文字。
- **参数**：
  - `text`：要输入的文本。
- **返回**：响应结果。

---
### `get_open_shadow_root()`
- **说明**：获取开放状态的shadow root。
- **返回**：shadowroot节点。

---
### `take_element_screenshot(filename)`
- **说明**：截取元素图片。
- **返回**：None。

---

### `find_element_by_css(selector)`
- **说明**：通过 CSS 选择器查找当前元素下的第一个匹配子元素。
- **参数**：
  - `selector`：CSS 选择器字符串。
- **返回**：子元素对象或响应结果。

---

### `find_elements_by_css(selector)`
- **说明**：通过 CSS 选择器查找当前元素下的所有匹配子元素。
- **参数**：
  - `selector`：CSS 选择器字符串。
- **返回**：子元素列表或响应结果。

---

### `find_element_by_xpath(selector)`
- **说明**：通过 XPath 查找当前元素下的第一个匹配子元素。
- **参数**：
  - `selector`：XPath 表达式。
- **返回**：子元素对象或响应结果。

---

### `find_elements_by_xpath(selector)`
- **说明**：通过 XPath 查找当前元素下的所有匹配子元素。
- **参数**：
  - `selector`：XPath 表达式。
- **返回**：子元素列表或响应结果。

---

### `drag_element_by_offset_line(offset_x, offset_y)`
- **说明**：以直线方式拖拽元素指定偏移量。
- **参数**：
  - `offset_x`：水平方向偏移。
  - `offset_y`：垂直方向偏移。
- **返回**：响应结果。

---

### `drag_element_by_offset_human(offset_x, offset_y, num_steps=30)`
- **说明**：以人类操作风格（贝塞尔曲线 + ease-in-out）拖拽元素。
- **参数**：
  - `offset_x`：水平偏移。
  - `offset_y`：垂直偏移。
  - `num_steps`：拖动的步数（默认 30）。
- **返回**：响应结果。

