Metadata-Version: 2.4
Name: HydroOJ
Version: 0.0.3
Summary: A Python SDK for interacting with HydroOJ via Selenium
Author-email: YANGRENRUIYRR <yangrenruiyrr@yeah.net>
Keywords: HydroOJ,selenium,online judge
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: selenium

# HydroOJ

基于Selenium开发的HydroOJ自动化操作库，内置真人行为模拟、反自动化检测配置，支持账号登录、题目/比赛管理、附件上传、自定义JS执行等全套自动化操作。

## 安装方法

### PyPI在线安装

```bash
pip install HydroOJ
```

## 依赖列表

```
selenium
```

支持浏览器：Edge、Chrome、Firefox、Ie、Safari、WebKitGTK

## 快速使用示例

```python
from HydroOJ import HydroOJ, LoginFailedError

# 初始化客户端
client = HydroOJ(
    url="https://hydro.ac/",
    webdriver_id="Chrome",
    headless=True,
    enable_random_delay=True,
    enable_human_click=True
)

# 登录账号
try:
    client.Login("用户名", "密码")
    print("登录成功")
except LoginFailedError:
    print("登录失败，账号或密码错误")

# 获取第一页题目列表
print(client.ViewProblemList(page=1))

# 查看题目内容
client.ViewProblem("1001")

# 创建新题目
client.CreateProblem(
    pid="1002",
    title="A+B Problem",
    content="# 题目\n输入两个整数，输出和",
    tag=["入门", "模拟"],
    difficulty=1,
    hidden=False
)

# 给题目上传文本附件
client.UploadFileToProblem("1002", "readme.txt", "本题输入输出样例说明")

# 获取比赛列表
print(client.ViewContestList(page=1))

# 查看单场比赛详情
client.ViewContest("10")

# 执行自定义JS脚本
res = client.RunJavaScript("return document.title")
print("页面标题：", res)

# 释放浏览器资源
client.Quit()
```

## API 说明

### HydroOJ 完整初始化参数

```python
HydroOJ(
    url="https://hydro.ac/",
    webdriver_id="Edge",
    webdriver_path=None,
    headless=True,
    disable_blink=True,
    enable_random_delay=True,
    enable_human_click=True,
    hide_automation=True
)
```

- url：HydroOJ站点根地址，会自动补全末尾斜杠
- webdriver_id：浏览器标识，支持 Edge / Chrome / Firefox / Ie / Safari / WebKitGTK
- webdriver_path：浏览器驱动本地路径，留空自动匹配驱动
- headless：是否启用无头模式，True 不弹出浏览器窗口
- disable_blink：关闭blink自动化检测特征，降低拦截概率
- enable_random_delay：开启随机操作延时，模拟真人浏览间隔
- enable_human_click：真人偏移点击，避免标准点击被识别为爬虫
- hide_automation：全套反自动化隐藏配置（参数屏蔽、CDP脚本覆盖webdriver标识）

### 全部可用方法

1. `Logined()`
   检测当前浏览器登录状态，返回布尔值；True=已登录，False=未登录
2. `Login(username, password)`
   传入用户名密码登录站点，登录校验失败抛出 `LoginFailedError`
3. `ViewProblemList(page=1)`
   获取指定页码的题目列表文本，无题目数据抛出 `ProblemListNotFoundError`
4. `ViewProblem(problem_id)`
   打开并打印指定ID题目多语言题面，题目不存在抛出 `ProblemNotFoundError`
5. `CreateProblem(pid, title, content, tag=[], difficulty=None, hidden=False)`
   新建题目，支持题号、标题、题面、多标签、难度、隐藏状态配置；操作异常抛出 `CreateProblemFailedError`
6. `ViewContestList(page=1)`
   获取指定页码比赛列表（含比赛名称与ID），无比赛数据抛出 `ContestListNotFoundError`
7. `ViewContest(contest_id)`
   打开并打印指定ID比赛说明文档，比赛不存在抛出 `ContestNotFoundError`
8. `UploadFileToProblem(problem_id, file_name, file_content)`
   为指定题目创建并上传文本附件，弹窗/保存失败抛出 `UploadFileFailedError`
9. `GotoPage(url)`
   浏览器直接跳转至任意自定义链接
10. `RunJavaScript(script)`
    在当前页面执行原生JS脚本，返回脚本执行结果
11. `Quit()`
    关闭浏览器进程，释放所有内存资源，程序结束必须调用

### 内置异常类

统一捕获各类操作失败场景，方便上层异常捕获处理：

- `LoginFailedError`：账号密码登录校验失败
- `ProblemNotFoundError`：访问的目标题目ID不存在
- `CreateProblemFailedError`：新建题目页面填写/提交异常
- `ProblemListNotFoundError`：题目列表页面加载无数据
- `ContestListNotFoundError`：比赛列表页面加载无数据
- `ContestNotFoundError`：访问的目标比赛ID不存在
- `UploadFileFailedError`：题目附件弹窗创建、写入、保存操作失败

## 使用注意事项

1. 批量循环创建题目、上传附件时库内自带随机延时，无需额外sleep；若超高频操作可手动增加延时规避网站风控
2. 程序正常/异常退出都必须调用 `Quit()`，否则浏览器后台驱动进程残留占用大量内存
3. 仅适配原版HydroOJ默认前端页面，自行二次魔改、修改DOM元素的部署站点会出现元素定位失败
4. `UploadFileToProblem` 仅支持纯文本文件上传，二进制文件暂不支持
5. 无头模式下部分旧版浏览器可能存在弹窗兼容性问题，调试阶段可设置 `headless=False` 可视化排查

## License

MIT
