# Proxy Relay - 代理中转器
[](https://python.org)
[](LICENSE)
代理协议转换工具,支持 HTTP/HTTPS/SOCKS5/SOCKS5H 互转。
**主要应用场景**: Playwright/Selenium 等自动化工具的代理中转
## 特性
- 协议互转: 支持 8 种协议组合
- 同步/异步API: 适配不同使用场景
- 自动清理: 进程退出时自动释放资源
- 线程安全: 支持多线程/多进程并发
- 零依赖: 纯Python实现
## 安装
```bash
pip install git+https://github.com/huazz233/proxy_relay.git
```
## 快速开始
```python
from proxy_relay import create_proxy
import requests
# 创建本地代理
url = create_proxy("socks5://user:pass@proxy.com:1080")
# 使用代理
resp = requests.get("https://api.ipify.org/", proxies={'http': url, 'https': url})
print(resp.text)
```
## 使用场景
### 脚本/测试
```python
from proxy_relay import create_proxy
url = create_proxy("http://proxy.com:8080")
# 使用代理...
# 进程退出时自动清理
```
### 长期运行服务
```python
from proxy_relay import create_proxy, cleanup
url = create_proxy("http://proxy.com:8080")
# 使用代理...
cleanup() # 手动清理
```
### 异步应用
```python
import asyncio
from proxy_relay import create_proxy_async, HttpProxy
async def main():
# 简单方式
url = await create_proxy_async("http://proxy.com:8080")
# 上下文管理器
async with HttpProxy("http://proxy.com:8080") as proxy:
url = proxy.get_local_url()
# 使用代理...
asyncio.run(main())
```
### Playwright集成
```python
import asyncio
from proxy_relay import create_proxy_async
from playwright.async_api import async_playwright
async def main():
url = await create_proxy_async("socks5://user:pass@proxy.com:1080")
async with async_playwright() as p:
browser = await p.chromium.launch(proxy={"server": url})
page = await browser.new_page()
await page.goto('https://api.ipify.org/')
await browser.close()
asyncio.run(main())
```
## API参考
### 同步API
```python
# 创建代理
create_proxy(upstream_url, local_type='http', connect_timeout=30.0, idle_timeout=300.0, timeout=30.0)
create_http_proxy(upstream_url, ...) # 快捷方法
create_socks5_proxy(upstream_url, ...) # 快捷方法
# 清理代理 (可选,进程退出时自动清理)
cleanup()
```
### 异步API
```python
# 创建代理
await create_proxy_async(upstream_url, local_type='http', ...)
await create_http_proxy_async(upstream_url, ...)
await create_socks5_proxy_async(upstream_url, ...)
# 上下文管理器
async with HttpProxy(upstream_url) as proxy:
url = proxy.get_local_url()
async with Socks5Proxy(upstream_url) as proxy:
url = proxy.get_local_url()
```
### 高级API
```python
# ProxyManager - 管理多个代理
with ProxyManager() as manager:
url = manager.create(upstream_url, local_type='http')
manager.stop(url) # 停止单个
manager.stop_all() # 停止所有
```
## 支持的协议
| 上游协议 | 本地协议 | 示例 |
|---------|---------|------|
| HTTP/HTTPS | HTTP/SOCKS5 | `http://proxy.com:8080` |
| SOCKS5 | HTTP/SOCKS5 | `socks5://user:pass@proxy.com:1080` |
| SOCKS5H | HTTP/SOCKS5 | `socks5h://proxy.com:1080` |
## 参数说明
- `upstream_url`: 上游代理URL
- `local_type`: 本地代理类型 (`'http'` 或 `'socks5'`)
- `connect_timeout`: 连接超时(秒),默认30
- `idle_timeout`: 空闲超时(秒),默认300
- `timeout`: 创建超时(秒),默认30
## 多进程/多线程
- 完全线程安全
- 多进程安全 (Windows/macOS默认spawn模式)
- Linux fork模式: 建议在fork前不要创建代理
## 常见问题
**Q: 代理会一直运行吗?**
A: 会,直到进程结束或手动调用 `cleanup()`
**Q: 长期运行的服务如何避免资源累积?**
A: 定期调用 `cleanup()` 或使用 `ProxyManager`
**Q: 同步API和异步API有什么区别?**
A: 同步API适合脚本,异步API适合异步应用(如FastAPI)
## 许可证
MIT License
Raw data
{
"_id": null,
"home_page": "https://github.com/huazz233/proxy_relay",
"name": "proxy-relay",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "proxy, socks5, http, https, relay, asyncio, protocol-conversion",
"author": "huazz233",
"author_email": "huazz233 <huazz233@163.com>",
"download_url": "https://files.pythonhosted.org/packages/e6/ee/6a3bc3d9935f046be1a798be9dc63b105e4c887741c7b09f9dafaf3188bd/proxy_relay-1.1.0.tar.gz",
"platform": null,
"description": "# Proxy Relay - \u4ee3\u7406\u4e2d\u8f6c\u5668\n\n[](https://python.org)\n[](LICENSE)\n\n\u4ee3\u7406\u534f\u8bae\u8f6c\u6362\u5de5\u5177,\u652f\u6301 HTTP/HTTPS/SOCKS5/SOCKS5H \u4e92\u8f6c\u3002\n\n**\u4e3b\u8981\u5e94\u7528\u573a\u666f**: Playwright/Selenium \u7b49\u81ea\u52a8\u5316\u5de5\u5177\u7684\u4ee3\u7406\u4e2d\u8f6c\n\n## \u7279\u6027\n\n- \u534f\u8bae\u4e92\u8f6c: \u652f\u6301 8 \u79cd\u534f\u8bae\u7ec4\u5408\n- \u540c\u6b65/\u5f02\u6b65API: \u9002\u914d\u4e0d\u540c\u4f7f\u7528\u573a\u666f\n- \u81ea\u52a8\u6e05\u7406: \u8fdb\u7a0b\u9000\u51fa\u65f6\u81ea\u52a8\u91ca\u653e\u8d44\u6e90\n- \u7ebf\u7a0b\u5b89\u5168: \u652f\u6301\u591a\u7ebf\u7a0b/\u591a\u8fdb\u7a0b\u5e76\u53d1\n- \u96f6\u4f9d\u8d56: \u7eafPython\u5b9e\u73b0\n\n## \u5b89\u88c5\n\n```bash\npip install git+https://github.com/huazz233/proxy_relay.git\n```\n\n## \u5feb\u901f\u5f00\u59cb\n\n```python\nfrom proxy_relay import create_proxy\nimport requests\n\n# \u521b\u5efa\u672c\u5730\u4ee3\u7406\nurl = create_proxy(\"socks5://user:pass@proxy.com:1080\")\n\n# \u4f7f\u7528\u4ee3\u7406\nresp = requests.get(\"https://api.ipify.org/\", proxies={'http': url, 'https': url})\nprint(resp.text)\n```\n\n## \u4f7f\u7528\u573a\u666f\n\n### \u811a\u672c/\u6d4b\u8bd5\n\n```python\nfrom proxy_relay import create_proxy\n\nurl = create_proxy(\"http://proxy.com:8080\")\n# \u4f7f\u7528\u4ee3\u7406...\n# \u8fdb\u7a0b\u9000\u51fa\u65f6\u81ea\u52a8\u6e05\u7406\n```\n\n### \u957f\u671f\u8fd0\u884c\u670d\u52a1\n\n```python\nfrom proxy_relay import create_proxy, cleanup\n\nurl = create_proxy(\"http://proxy.com:8080\")\n# \u4f7f\u7528\u4ee3\u7406...\ncleanup() # \u624b\u52a8\u6e05\u7406\n```\n\n### \u5f02\u6b65\u5e94\u7528\n\n```python\nimport asyncio\nfrom proxy_relay import create_proxy_async, HttpProxy\n\nasync def main():\n # \u7b80\u5355\u65b9\u5f0f\n url = await create_proxy_async(\"http://proxy.com:8080\")\n\n # \u4e0a\u4e0b\u6587\u7ba1\u7406\u5668\n async with HttpProxy(\"http://proxy.com:8080\") as proxy:\n url = proxy.get_local_url()\n # \u4f7f\u7528\u4ee3\u7406...\n\nasyncio.run(main())\n```\n\n### Playwright\u96c6\u6210\n\n```python\nimport asyncio\nfrom proxy_relay import create_proxy_async\nfrom playwright.async_api import async_playwright\n\nasync def main():\n url = await create_proxy_async(\"socks5://user:pass@proxy.com:1080\")\n\n async with async_playwright() as p:\n browser = await p.chromium.launch(proxy={\"server\": url})\n page = await browser.new_page()\n await page.goto('https://api.ipify.org/')\n await browser.close()\n\nasyncio.run(main())\n```\n\n\n\n## API\u53c2\u8003\n\n### \u540c\u6b65API\n\n```python\n# \u521b\u5efa\u4ee3\u7406\ncreate_proxy(upstream_url, local_type='http', connect_timeout=30.0, idle_timeout=300.0, timeout=30.0)\ncreate_http_proxy(upstream_url, ...) # \u5feb\u6377\u65b9\u6cd5\ncreate_socks5_proxy(upstream_url, ...) # \u5feb\u6377\u65b9\u6cd5\n\n# \u6e05\u7406\u4ee3\u7406 (\u53ef\u9009,\u8fdb\u7a0b\u9000\u51fa\u65f6\u81ea\u52a8\u6e05\u7406)\ncleanup()\n```\n\n### \u5f02\u6b65API\n\n```python\n# \u521b\u5efa\u4ee3\u7406\nawait create_proxy_async(upstream_url, local_type='http', ...)\nawait create_http_proxy_async(upstream_url, ...)\nawait create_socks5_proxy_async(upstream_url, ...)\n\n# \u4e0a\u4e0b\u6587\u7ba1\u7406\u5668\nasync with HttpProxy(upstream_url) as proxy:\n url = proxy.get_local_url()\n\nasync with Socks5Proxy(upstream_url) as proxy:\n url = proxy.get_local_url()\n```\n\n### \u9ad8\u7ea7API\n\n```python\n# ProxyManager - \u7ba1\u7406\u591a\u4e2a\u4ee3\u7406\nwith ProxyManager() as manager:\n url = manager.create(upstream_url, local_type='http')\n manager.stop(url) # \u505c\u6b62\u5355\u4e2a\n manager.stop_all() # \u505c\u6b62\u6240\u6709\n```\n\n## \u652f\u6301\u7684\u534f\u8bae\n\n| \u4e0a\u6e38\u534f\u8bae | \u672c\u5730\u534f\u8bae | \u793a\u4f8b |\n|---------|---------|------|\n| HTTP/HTTPS | HTTP/SOCKS5 | `http://proxy.com:8080` |\n| SOCKS5 | HTTP/SOCKS5 | `socks5://user:pass@proxy.com:1080` |\n| SOCKS5H | HTTP/SOCKS5 | `socks5h://proxy.com:1080` |\n\n## \u53c2\u6570\u8bf4\u660e\n\n- `upstream_url`: \u4e0a\u6e38\u4ee3\u7406URL\n- `local_type`: \u672c\u5730\u4ee3\u7406\u7c7b\u578b (`'http'` \u6216 `'socks5'`)\n- `connect_timeout`: \u8fde\u63a5\u8d85\u65f6(\u79d2),\u9ed8\u8ba430\n- `idle_timeout`: \u7a7a\u95f2\u8d85\u65f6(\u79d2),\u9ed8\u8ba4300\n- `timeout`: \u521b\u5efa\u8d85\u65f6(\u79d2),\u9ed8\u8ba430\n\n## \u591a\u8fdb\u7a0b/\u591a\u7ebf\u7a0b\n\n- \u5b8c\u5168\u7ebf\u7a0b\u5b89\u5168\n- \u591a\u8fdb\u7a0b\u5b89\u5168 (Windows/macOS\u9ed8\u8ba4spawn\u6a21\u5f0f)\n- Linux fork\u6a21\u5f0f: \u5efa\u8bae\u5728fork\u524d\u4e0d\u8981\u521b\u5efa\u4ee3\u7406\n\n## \u5e38\u89c1\u95ee\u9898\n\n**Q: \u4ee3\u7406\u4f1a\u4e00\u76f4\u8fd0\u884c\u5417?**\nA: \u4f1a,\u76f4\u5230\u8fdb\u7a0b\u7ed3\u675f\u6216\u624b\u52a8\u8c03\u7528 `cleanup()`\n\n**Q: \u957f\u671f\u8fd0\u884c\u7684\u670d\u52a1\u5982\u4f55\u907f\u514d\u8d44\u6e90\u7d2f\u79ef?**\nA: \u5b9a\u671f\u8c03\u7528 `cleanup()` \u6216\u4f7f\u7528 `ProxyManager`\n\n**Q: \u540c\u6b65API\u548c\u5f02\u6b65API\u6709\u4ec0\u4e48\u533a\u522b?**\nA: \u540c\u6b65API\u9002\u5408\u811a\u672c,\u5f02\u6b65API\u9002\u5408\u5f02\u6b65\u5e94\u7528(\u5982FastAPI)\n\n## \u8bb8\u53ef\u8bc1\n\nMIT License\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "\u591a\u534f\u8bae\u4ee3\u7406\u4e2d\u8f6c\u5668\uff0c\u652f\u6301HTTP/HTTPS/SOCKS5/SOCKS5H\u534f\u8bae\u4e92\u8f6c\uff0c\u672c\u5730\u4ee3\u7406\u65e0\u9700\u8d26\u5bc6\u8ba4\u8bc1",
"version": "1.1.0",
"project_urls": {
"Homepage": "https://github.com/huazz233/proxy_relay",
"Issues": "https://github.com/huazz233/proxy_relay/issues",
"Repository": "https://github.com/huazz233/proxy_relay"
},
"split_keywords": [
"proxy",
" socks5",
" http",
" https",
" relay",
" asyncio",
" protocol-conversion"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "8bf21240e271117373095af056870372c176e82cdc9ced9fba9866ac619af1af",
"md5": "ed8416778bc57f842cf0002747f1ecbd",
"sha256": "d713ab7bf8919309548f96e1c5a1caf120411405b4b1e294f3677d3fae90ecb4"
},
"downloads": -1,
"filename": "proxy_relay-1.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ed8416778bc57f842cf0002747f1ecbd",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 9579,
"upload_time": "2025-10-30T07:21:33",
"upload_time_iso_8601": "2025-10-30T07:21:33.707866Z",
"url": "https://files.pythonhosted.org/packages/8b/f2/1240e271117373095af056870372c176e82cdc9ced9fba9866ac619af1af/proxy_relay-1.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "e6ee6a3bc3d9935f046be1a798be9dc63b105e4c887741c7b09f9dafaf3188bd",
"md5": "f166c1511ef8ef1a8cbf5fb7dff5f1d4",
"sha256": "ae6c8dbbcb1473b2a792a919b26f0eb9d4eb52f83d42669084d4670a6fe7d813"
},
"downloads": -1,
"filename": "proxy_relay-1.1.0.tar.gz",
"has_sig": false,
"md5_digest": "f166c1511ef8ef1a8cbf5fb7dff5f1d4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 11415,
"upload_time": "2025-10-30T07:21:35",
"upload_time_iso_8601": "2025-10-30T07:21:35.108817Z",
"url": "https://files.pythonhosted.org/packages/e6/ee/6a3bc3d9935f046be1a798be9dc63b105e4c887741c7b09f9dafaf3188bd/proxy_relay-1.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-30 07:21:35",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "huazz233",
"github_project": "proxy_relay",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "proxy-relay"
}