proxy-scraper-cli 1.21.0__tar.gz → 1.23.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/PKG-INFO +47 -13
  2. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/README.md +44 -11
  3. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxy_scraper_cli.egg-info/PKG-INFO +47 -13
  4. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxy_scraper_cli.egg-info/SOURCES.txt +7 -0
  5. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxy_scraper_cli.egg-info/requires.txt +1 -1
  6. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/__init__.py +1 -1
  7. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/agent.py +2 -2
  8. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/api.py +8 -6
  9. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/app.py +5 -0
  10. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/exporters.py +48 -0
  11. proxy_scraper_cli-1.23.0/proxyscraper/mirror.py +348 -0
  12. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/pages.py +17 -12
  13. proxy_scraper_cli-1.23.0/proxyscraper/preferences.py +59 -0
  14. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/publish.py +11 -3
  15. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/ranking.py +26 -2
  16. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/server/core.py +17 -7
  17. proxy_scraper_cli-1.23.0/proxyscraper/server/dashboard.html +351 -0
  18. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/server/status.py +59 -4
  19. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/site/index.html +49 -16
  20. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/sources.json +1 -0
  21. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/ui/serve.py +5 -4
  22. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/ui/widgets.py +6 -0
  23. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/pyproject.toml +3 -2
  24. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_agent.py +5 -4
  25. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_live_api.py +6 -5
  26. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_mcp_server.py +2 -1
  27. proxy_scraper_cli-1.23.0/tests/test_mirror.py +75 -0
  28. proxy_scraper_cli-1.23.0/tests/test_pac.py +116 -0
  29. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_pick.py +2 -2
  30. proxy_scraper_cli-1.23.0/tests/test_preferences.py +37 -0
  31. proxy_scraper_cli-1.23.0/tests/test_serve_dashboard.py +234 -0
  32. proxy_scraper_cli-1.23.0/tests/test_survival_ranking.py +58 -0
  33. proxy_scraper_cli-1.21.0/proxyscraper/preferences.py +0 -24
  34. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/LICENSE +0 -0
  35. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxy_scraper_cli.egg-info/dependency_links.txt +0 -0
  36. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxy_scraper_cli.egg-info/entry_points.txt +0 -0
  37. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxy_scraper_cli.egg-info/top_level.txt +0 -0
  38. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/__main__.py +0 -0
  39. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/action.py +0 -0
  40. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/asndb.py +0 -0
  41. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/blocklist.py +0 -0
  42. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/charts.py +0 -0
  43. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/checker.py +0 -0
  44. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/cli.py +0 -0
  45. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/compat.py +0 -0
  46. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/completion.py +0 -0
  47. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/fetchcache.py +0 -0
  48. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/geo.py +0 -0
  49. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/geodb.py +0 -0
  50. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/handshake.py +0 -0
  51. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/history.py +0 -0
  52. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/judges.py +0 -0
  53. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/mcp_entry.py +0 -0
  54. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/mcp_server.py +0 -0
  55. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/netio.py +0 -0
  56. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/options.py +0 -0
  57. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/output.py +0 -0
  58. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/parsing.py +0 -0
  59. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/paths.py +0 -0
  60. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/pipeline.py +0 -0
  61. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/proxypages.py +0 -0
  62. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/report.py +0 -0
  63. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/runsteps.py +0 -0
  64. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/server/__init__.py +0 -0
  65. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/server/api.py +0 -0
  66. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/server/http.py +0 -0
  67. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/server/pool.py +0 -0
  68. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/server/socks.py +0 -0
  69. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/server/upstream.py +0 -0
  70. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/site/apple-touch-icon.png +0 -0
  71. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/site/googleaac1161b7853c5b5.html +0 -0
  72. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/site/logo.png +0 -0
  73. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/site/og.png +0 -0
  74. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/sites.py +0 -0
  75. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/sources.py +0 -0
  76. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/speed.py +0 -0
  77. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/targets.py +0 -0
  78. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/ui/__init__.py +0 -0
  79. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/ui/dashboard.py +0 -0
  80. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/ui/keys.py +0 -0
  81. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/ui/report.py +0 -0
  82. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/proxyscraper/ui/wizard.py +0 -0
  83. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/setup.cfg +0 -0
  84. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_action.py +0 -0
  85. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_api.py +0 -0
  86. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_app.py +0 -0
  87. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_asndb.py +0 -0
  88. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_auth.py +0 -0
  89. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_blocklist.py +0 -0
  90. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_charts.py +0 -0
  91. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_checker.py +0 -0
  92. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_compat.py +0 -0
  93. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_completion.py +0 -0
  94. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_discovery_growth.py +0 -0
  95. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_exporters.py +0 -0
  96. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_fetchcache.py +0 -0
  97. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_geodb.py +0 -0
  98. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_judges.py +0 -0
  99. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_learning.py +0 -0
  100. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_mine_sources.py +0 -0
  101. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_options.py +0 -0
  102. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_output_stdout.py +0 -0
  103. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_own_sources.py +0 -0
  104. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_packaging.py +0 -0
  105. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_pages.py +0 -0
  106. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_parsing.py +0 -0
  107. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_parsing_fuzz.py +0 -0
  108. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_paths.py +0 -0
  109. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_pipeline.py +0 -0
  110. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_proxy_pages.py +0 -0
  111. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_proxy_sources.py +0 -0
  112. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_publish.py +0 -0
  113. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_report.py +0 -0
  114. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_robustness.py +0 -0
  115. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_rotator.py +0 -0
  116. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_serve_api.py +0 -0
  117. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_serve_password.py +0 -0
  118. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_serve_refill.py +0 -0
  119. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_serve_v2.py +0 -0
  120. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_server.py +0 -0
  121. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_server_closed_writer.py +0 -0
  122. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_server_fixes.py +0 -0
  123. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_sites.py +0 -0
  124. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_sources_json.py +0 -0
  125. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_speed.py +0 -0
  126. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_speed_ranking.py +0 -0
  127. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_tamper.py +0 -0
  128. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_targets.py +0 -0
  129. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_ui.py +0 -0
  130. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_uptime.py +0 -0
  131. {proxy_scraper_cli-1.21.0 → proxy_scraper_cli-1.23.0}/tests/test_wizard.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: proxy-scraper-cli
3
- Version: 1.21.0
3
+ Version: 1.23.0
4
4
  Summary: Finds free HTTP, SOCKS4 and SOCKS5 proxies that actually work: 700+ sources, real checks, honeypot filtering and a rotating local proxy server.
5
5
  Author: Maximilian Feix
6
6
  License-Expression: MIT
@@ -22,6 +22,7 @@ Classifier: Programming Language :: Python :: 3.10
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
24
  Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Programming Language :: Python :: 3.14
25
26
  Classifier: Topic :: Internet :: Proxy Servers
26
27
  Classifier: Topic :: System :: Networking
27
28
  Requires-Python: >=3.9
@@ -36,7 +37,7 @@ Requires-Dist: mcp<3,>=2.2; python_version >= "3.10" and extra == "mcp"
36
37
  Provides-Extra: dev
37
38
  Requires-Dist: pytest; extra == "dev"
38
39
  Requires-Dist: hypothesis; extra == "dev"
39
- Requires-Dist: ruff==0.16.8; extra == "dev"
40
+ Requires-Dist: ruff==0.16.9; extra == "dev"
40
41
  Dynamic: license-file
41
42
 
42
43
  <div align="center">
@@ -51,16 +52,19 @@ Dynamic: license-file
51
52
  [![Release](https://img.shields.io/github/v/release/maximilianfeix/proxy-scraper?style=flat-square&color=D4F77A&labelColor=121113)](https://github.com/maximilianfeix/proxy-scraper/releases/latest)
52
53
  [![Live proxies](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fmaximilianfeix%2Fproxy-scraper%2Fproxy-list%2Fbadges%2Ftotal.json&style=flat-square&labelColor=121113)](#live-list)
53
54
  [![PyPI](https://img.shields.io/pypi/v/proxy-scraper-cli?style=flat-square&color=D4F77A&labelColor=121113&label=pypi)](https://pypi.org/project/proxy-scraper-cli/)
54
- [![Python](https://img.shields.io/badge/python-3.9–3.13-D4F77A?style=flat-square&labelColor=121113)](pyproject.toml)
55
+ [![Python](https://img.shields.io/badge/python-3.9–3.14-D4F77A?style=flat-square&labelColor=121113)](pyproject.toml)
55
56
  [![Stars](https://img.shields.io/github/stars/maximilianfeix/proxy-scraper?style=flat-square&color=D4F77A&labelColor=121113)](https://github.com/maximilianfeix/proxy-scraper/stargazers)
56
57
  [![License](https://img.shields.io/badge/license-MIT-D4F77A?style=flat-square&labelColor=121113)](LICENSE)
57
58
 
58
59
  <a href="https://maximilianfeix.github.io/proxy-scraper/"><img src="https://img.shields.io/badge/Browse_the_live_list-D4F77A?style=for-the-badge&labelColor=121113" alt="Browse the live list"></a>
60
+ <a href="https://github.com/maximilianfeix/free-proxy-list"><img src="https://img.shields.io/badge/Just_the_lists-121113?style=for-the-badge" alt="Just the lists: free-proxy-list"></a>
59
61
  <a href="#install"><img src="https://img.shields.io/badge/Install-121113?style=for-the-badge" alt="Install"></a>
60
62
  <a href="#from-python"><img src="https://img.shields.io/badge/Python_API-121113?style=for-the-badge" alt="Python API"></a>
61
63
  <a href="#mcp"><img src="https://img.shields.io/badge/MCP_server-121113?style=for-the-badge" alt="MCP server for AI agents"></a>
62
64
  <a href="bot/"><img src="https://img.shields.io/badge/Discord_bot-121113?style=for-the-badge" alt="Discord bot"></a>
63
65
 
66
+ **English** · [简体中文](README.zh-CN.md)
67
+
64
68
  [Install](#install) · [Live list](#live-list) · [For AI agents](#mcp) · [Proxy server](#proxy-server) · [How it works](#how-it-works) · [Recipes](#recipes) · [Options](#options) · [FAQ](#faq)
65
69
 
66
70
  </div>
@@ -69,6 +73,8 @@ Dynamic: license-file
69
73
 
70
74
  Most free proxy lists are 95 % dead, and a good part of the rest are honeypots or proxies that inject scripts into your pages. **proxy-scraper** collects public HTTP, SOCKS4 and SOCKS5 proxies from 700+ sources and keeps only the ones that pass every check. It learns with every run which sources are worth it, and it can turn the result into a single rotating proxy.
71
75
 
76
+ **In numbers:** in one day it checked 3.6 million free proxies – 1.1 % worked, and more than half of the ones that answered failed a second request. [What's actually out there →](docs/free-proxies-in-numbers.md)
77
+
72
78
  <picture>
73
79
  <source media="(prefers-color-scheme: dark)" srcset="docs/checks-dark.svg">
74
80
  <source media="(prefers-color-scheme: light)" srcset="docs/checks-light.svg">
@@ -112,6 +118,14 @@ proxy-scraper
112
118
 
113
119
  The package is called `proxy-scraper-cli` on PyPI (the plain name is taken), the command is `proxy-scraper`.
114
120
 
121
+ **With [Homebrew](https://brew.sh)** on macOS and Linux:
122
+
123
+ ```bash
124
+ brew install maximilianfeix/tap/proxy-scraper
125
+ ```
126
+
127
+ The formula follows each release within about a day.
128
+
115
129
  <details>
116
130
  <summary><b>Other ways: Docker, pip, a faster event loop, or straight from the repo</b></summary>
117
131
  <br>
@@ -148,7 +162,7 @@ proxy-scraper --completion fish > ~/.config/fish/completions/proxy-scraper.fish
148
162
  proxy-scraper --completion powershell | Out-String | Invoke-Expression # in $PROFILE
149
163
  ```
150
164
 
151
- Installed, the learned state lives in your user data folder (`~/Library/Application Support/proxy-scraper`, `%LOCALAPPDATA%\proxy-scraper` or `~/.local/share/proxy-scraper`; override with `PROXY_SCRAPER_HOME`) and results go to `./results`. Run from a clone, both stay inside the project.
165
+ Installed, the learned state lives in your user data folder (`~/Library/Application Support/proxy-scraper`, `%LOCALAPPDATA%\proxy-scraper` or `~/.local/share/proxy-scraper`; override with `PROXY_SCRAPER_HOME`) and results go to `./results`. Run from a clone, both stay inside the project. After the second run that finds proxies it asks once for a GitHub star; `PROXY_SCRAPER_NO_STAR_HINT=1` turns that off (it never shows in CI).
152
166
 
153
167
  </details>
154
168
 
@@ -176,7 +190,9 @@ Keys: <kbd>↑</kbd><kbd>↓</kbd> select · <kbd>Space</kbd> toggle · <kbd>1</
176
190
 
177
191
  ## Live proxy list
178
192
 
179
- Don't want to scan yourself? Every hour **GitHub Actions** runs the tool and publishes the hits to the [`proxy-list`](../../tree/proxy-list) branch – every entry worked in the last run, fastest first.
193
+ Don't want to scan yourself? Every hour **GitHub Actions** runs the tool and publishes the hits to the [`proxy-list`](../../tree/proxy-list) branch – every entry worked in the last run, best first: fast ones that are likely to still be up come on top.
194
+
195
+ > **Just want the lists?** They also live in a repository of their own, **[maximilianfeix/free-proxy-list](https://github.com/maximilianfeix/free-proxy-list)** – one list per protocol, per country and per site, updated every hour, with the numbers of the last run on the front page. Watch or star it to keep it at hand.
180
196
 
181
197
  <a href="https://maximilianfeix.github.io/proxy-scraper/"><picture>
182
198
  <source media="(prefers-color-scheme: dark)" srcset="https://maximilianfeix.github.io/proxy-scraper/chart-dark.svg">
@@ -317,7 +333,7 @@ Started without arguments, the tool asks what you need using the arrow keys –
317
333
  <td valign="top">
318
334
 
319
335
  **Real verification**<br>
320
- Every hit has to fetch two independent pages – that weeds out **honeypots** that only answer check requests (in some runs 5 out of 6 “hits”). A third request catches proxies that **tamper with content**: in our measurements one in five working proxies injected a script into a plain HTML page. Plus: HTTPS through a tunnel with **verified TLS**, anonymity level *elite / anonymous / transparent* and the country of the exit IP.
336
+ Every hit has to fetch two independent pages – that weeds out **honeypots** that only answer check requests: over 3.6 million checks, 54 % of the proxies that answered the first request failed the second. A third request catches proxies that **tamper with content**: about one in 40 working proxies changed a known page, usually by injecting a script ([the numbers](docs/free-proxies-in-numbers.md)). Plus: HTTPS through a tunnel with **verified TLS**, anonymity level *elite / anonymous / transparent* and the country of the exit IP.
321
337
 
322
338
  </td>
323
339
  <td valign="top">
@@ -359,13 +375,13 @@ Speed chart, latency histogram, protocols, countries and the latest hits in real
359
375
  <td valign="top">
360
376
 
361
377
  **Runs everywhere**<br>
362
- macOS, Linux and Windows, Python 3.9 to 3.13. Only two dependencies: `rich` and `certifi`. It even notices when a firewall blocks proxies.
378
+ macOS, Linux and Windows, Python 3.9 to 3.14. Only two dependencies: `rich` and `certifi`. It even notices when a firewall blocks proxies.
363
379
 
364
380
  </td>
365
381
  <td valign="top">
366
382
 
367
383
  **Thoroughly tested**<br>
368
- 450+ tests run offline against real mini proxies and honeypots on `localhost` – on Linux, macOS and Windows with Python 3.9, 3.11 and 3.13.
384
+ 760+ tests run offline against real mini proxies and honeypots on `localhost` – on Linux, macOS and Windows with Python 3.9, 3.11, 3.13 and 3.14.
369
385
 
370
386
  </td>
371
387
  </tr>
@@ -513,7 +529,7 @@ Without a password, `--serve-host` means **anyone who reaches the port can use i
513
529
 
514
530
  - every connection goes through a different proxy (unless sticky); fast and proven ones are preferred
515
531
  - `CONNECT` for HTTPS and plain HTTP requests; HTTP, SOCKS4 and SOCKS5 proxies can sit behind it (SOCKS5 with DNS through the proxy)
516
- - HTTPS only uses proxies that passed the test with **verified TLS** – no broken encryption
532
+ - HTTPS prefers proxies that passed the test with **verified TLS**; when no such proxy fits right now – none matches a wish like `country-de`, or they have all dropped out – it uses the others – your client's own certificate check still catches a proxy that breaks the encryption, so leave it on
517
533
  - if a proxy stays silent inside the tunnel or returns an error page instead of TLS, the same first packet quietly goes to the next one
518
534
  - three failures in a row and a proxy leaves the rotation – every 5 minutes those get re-checked and come back if they work again
519
535
  - `--serve-refill 6` checks fresh proxies every 6 hours in the background (the live list with `--recheck live`, otherwise the last run + history) with the same checks and filters, and adds the hits – a server that runs for days doesn't run dry
@@ -521,6 +537,10 @@ Without a password, `--serve-host` means **anyone who reaches the port can use i
521
537
 
522
538
  In testing: 20 of 20 HTTPS requests succeeded, over 15 different exit IPs. In the wizard this is **Proxy server right away**.
523
539
 
540
+ **Live dashboard:** open `http://127.0.0.1:8899/__proxy-scraper/` in a browser – the pool, success rate, traffic, a live chart of requests, countries, the best proxies and the latest connections, refreshed every two seconds. It needs nothing from the internet, and `--serve-password` protects it like the rest.
541
+
542
+ <div align="center"><img src="docs/dashboard-live.png" alt="The live dashboard of the rotating proxy server: usable proxies, success rate, requests per second, countries and the latest connections" width="860"></div>
543
+
524
544
  <a id="pool-api"></a>
525
545
 
526
546
  ### Proxy pool API
@@ -739,6 +759,18 @@ proxychains4 -f results/latest/proxychains.conf curl https://api.ipify.org
739
759
 
740
760
  `clash.yaml` has all HTTP and SOCKS5 proxies plus a `url-test` group that always picks the fastest. `singbox.json` does the same for sing-box, SOCKS4 included, and opens a local proxy: `sing-box run -c results/latest/singbox.json`, then use `127.0.0.1:2080` as HTTP or SOCKS5 proxy. All three leave out HTTP proxies that can't tunnel (`CONNECT`), because these tools tunnel everything.
741
761
 
762
+ **Browsers and the OS** – `--export pac` writes `proxy.pac`: point Firefox, Chrome (via the system settings), FoxyProxy or macOS/Windows proxy settings at it and every request goes through the best 30 HTTP and SOCKS5 proxies in order, the browser moving on by itself when one fails. Local names and private IP addresses stay direct (a host name like `10.example.com` doesn't count as private). The file itself has no `DIRECT` fallback and resolves no host names, and SOCKS4 is left out because it would make the browser resolve names with your own DNS. Two Firefox settings matter: turn on *Proxy DNS when using SOCKS v5*, and set `network.proxy.failover_direct` to `false` in `about:config` – otherwise Firefox goes direct once every proxy has failed. No install at all: the live list publishes one every hour at `https://maximilianfeix.github.io/proxy-scraper/proxy.pac`.
763
+
764
+ **Burp Suite, OWASP ZAP, mitmproxy** – put the rotating server behind your intercepting proxy, so a scan or a brute-force test comes from many IPs while you still see every request. Start it with `proxy-scraper --recheck live --serve`, then:
765
+
766
+ | Tool | Where | Set |
767
+ |---|---|---|
768
+ | Burp Suite | *Settings → Network → Connections → Upstream proxy servers* | a rule for destination host `*`, proxy host `127.0.0.1`, port `8899`; with `--serve-password` add Basic auth (user `any` or a wish like `country-de`, the password) |
769
+ | OWASP ZAP | *Options → Network → Connection → HTTP Proxy* | host `127.0.0.1`, port `8899`, and under its authentication the user (`any` or a wish) and the password – use the HTTP setting, not SOCKS: ZAP never sends loopback addresses through its SOCKS proxy |
770
+ | mitmproxy | command line | `mitmproxy --mode upstream:http://127.0.0.1:8899 --upstream-auth country-us:x` |
771
+
772
+ Username wishes – `country-us` sends everything out through US proxies, `session-NAME` keeps one exit IP for a login flow – reach the server as the proxy login. mitmproxy sends it right away; Burp and ZAP may wait to be asked, so start the server with `--serve-password` when you rely on a wish there. **Keep your tool's upstream certificate checks on** (no `--ssl-insecure` in mitmproxy, no "ignore certificate errors" upstream in Burp or ZAP): free proxies are strangers, and that check is what stops one from reading or changing your HTTPS traffic. Tested end to end with mitmproxy 12, certificate checks on: HTTP and HTTPS through mitmproxy and the rotating server, every request out through a US proxy, and a site with an expired certificate refused. Only test what you're allowed to.
773
+
742
774
  **In a pipe** – `-o -` prints the hits to stdout, the interface moves to stderr
743
775
 
744
776
  ```bash
@@ -832,7 +864,7 @@ curl.exe -x (Get-Content "$run\all.txt" -TotalCount 1) http://api.ipify.org
832
864
  | `--serve-refill HOURS` | while serving, check fresh proxies every HOURS and add the hits to the pool |
833
865
  | `--serve [PORT]` | afterwards serve as a rotating proxy on `127.0.0.1:PORT` (default: 8899) |
834
866
  | `-o FILE` | also write all hits to this file; `-o -` prints them to stdout |
835
- | `--export FORMATS` | extra files for other tools: `proxychains`, `clash`, `singbox`, `curl` or `all` |
867
+ | `--export FORMATS` | extra files for other tools: `proxychains`, `clash`, `singbox`, `curl`, `pac` or `all` |
836
868
  | `-V`, `--version` | print the version |
837
869
  | `--completion SHELL` | print the tab completion script for bash, zsh, fish or PowerShell |
838
870
 
@@ -918,8 +950,9 @@ Only for things that don't matter. Public proxies are run by strangers who can r
918
950
 
919
951
  What's next is in the [open issues](../../issues) – ideas and wishes are welcome as an [issue](../../issues/new/choose). During Hacktoberfest there are [beginner-friendly issues](../../issues?q=is%3Aopen+label%3Ahacktoberfest) with pointers on where to start.
920
952
 
921
- - [ ] [Measure throughput, not just latency](../../issues/140)
922
- - [ ] [Daily snapshots as a dataset](../../issues/143)
953
+ Shipped in v1.22 and v1.23: a live dashboard for the rotating server, `--export pac` and an hourly `proxy.pac`, "best first" that counts how likely a proxy is still up, the lists in a repository of their own ([free-proxy-list](https://github.com/maximilianfeix/free-proxy-list)), daily snapshots on Hugging Face, `brew install`, a Chinese README, Python 3.14, and a recipe for Burp Suite, ZAP and mitmproxy.
954
+
955
+ Shipped in v1.10 to v1.21: download speed per proxy and "best first" everywhere, daily snapshots, a rotating proxy URL for requests, httpx and Playwright, `--pick` for working proxies without a scan, a proxy pool API compatible with jhao104/proxy_pool, your own lists with `--source`, a GitHub Action, a Telegram bot and an Atom feed for the weekly report.
923
956
 
924
957
  Shipped in v1.8 and v1.9: uptime per proxy and `stable.txt`, which proxies get through to Google, Reddit and Amazon, `live_proxies()` in Python, a page per proxy with its week of checks, a weekly report, live charts in this README, shareable filters on the website, sources mined from other scrapers' lists, untyped lists tried as HTTP and SOCKS5, `--export singbox`, PowerShell completion and recipes for httpx, aiohttp and Scrapy.
925
958
 
@@ -966,12 +999,13 @@ proxyscraper/
966
999
  ├── geodb.py DB-IP country database (monthly, binary search)
967
1000
  ├── targets.py target sites for --target
968
1001
  ├── output.py result files
969
- ├── exporters.py proxychains, Clash, sing-box and curl formats (--export)
1002
+ ├── exporters.py proxychains, Clash, sing-box, curl and PAC formats (--export)
970
1003
  ├── server/ rotating proxy server (--serve): pool · http · upstream · socks · status · api · core
971
1004
  ├── api.py find_proxies() / check_proxies() for Python
972
1005
  ├── agent.py MCP tools without the SDK: live list, filters, fetch through proxies
973
1006
  ├── mcp_server.py MCP server (proxy-scraper-mcp) for AI agents
974
1007
  ├── publish.py live list for GitHub Actions
1008
+ ├── mirror.py the same lists in their own repo (free-proxy-list)
975
1009
  ├── paths.py where state and results are stored
976
1010
  ├── compat.py differences between Unix and Windows
977
1011
  ├── netio.py small HTTP client on asyncio
@@ -10,16 +10,19 @@
10
10
  [![Release](https://img.shields.io/github/v/release/maximilianfeix/proxy-scraper?style=flat-square&color=D4F77A&labelColor=121113)](https://github.com/maximilianfeix/proxy-scraper/releases/latest)
11
11
  [![Live proxies](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fmaximilianfeix%2Fproxy-scraper%2Fproxy-list%2Fbadges%2Ftotal.json&style=flat-square&labelColor=121113)](#live-list)
12
12
  [![PyPI](https://img.shields.io/pypi/v/proxy-scraper-cli?style=flat-square&color=D4F77A&labelColor=121113&label=pypi)](https://pypi.org/project/proxy-scraper-cli/)
13
- [![Python](https://img.shields.io/badge/python-3.9–3.13-D4F77A?style=flat-square&labelColor=121113)](pyproject.toml)
13
+ [![Python](https://img.shields.io/badge/python-3.9–3.14-D4F77A?style=flat-square&labelColor=121113)](pyproject.toml)
14
14
  [![Stars](https://img.shields.io/github/stars/maximilianfeix/proxy-scraper?style=flat-square&color=D4F77A&labelColor=121113)](https://github.com/maximilianfeix/proxy-scraper/stargazers)
15
15
  [![License](https://img.shields.io/badge/license-MIT-D4F77A?style=flat-square&labelColor=121113)](LICENSE)
16
16
 
17
17
  <a href="https://maximilianfeix.github.io/proxy-scraper/"><img src="https://img.shields.io/badge/Browse_the_live_list-D4F77A?style=for-the-badge&labelColor=121113" alt="Browse the live list"></a>
18
+ <a href="https://github.com/maximilianfeix/free-proxy-list"><img src="https://img.shields.io/badge/Just_the_lists-121113?style=for-the-badge" alt="Just the lists: free-proxy-list"></a>
18
19
  <a href="#install"><img src="https://img.shields.io/badge/Install-121113?style=for-the-badge" alt="Install"></a>
19
20
  <a href="#from-python"><img src="https://img.shields.io/badge/Python_API-121113?style=for-the-badge" alt="Python API"></a>
20
21
  <a href="#mcp"><img src="https://img.shields.io/badge/MCP_server-121113?style=for-the-badge" alt="MCP server for AI agents"></a>
21
22
  <a href="bot/"><img src="https://img.shields.io/badge/Discord_bot-121113?style=for-the-badge" alt="Discord bot"></a>
22
23
 
24
+ **English** · [简体中文](README.zh-CN.md)
25
+
23
26
  [Install](#install) · [Live list](#live-list) · [For AI agents](#mcp) · [Proxy server](#proxy-server) · [How it works](#how-it-works) · [Recipes](#recipes) · [Options](#options) · [FAQ](#faq)
24
27
 
25
28
  </div>
@@ -28,6 +31,8 @@
28
31
 
29
32
  Most free proxy lists are 95 % dead, and a good part of the rest are honeypots or proxies that inject scripts into your pages. **proxy-scraper** collects public HTTP, SOCKS4 and SOCKS5 proxies from 700+ sources and keeps only the ones that pass every check. It learns with every run which sources are worth it, and it can turn the result into a single rotating proxy.
30
33
 
34
+ **In numbers:** in one day it checked 3.6 million free proxies – 1.1 % worked, and more than half of the ones that answered failed a second request. [What's actually out there →](docs/free-proxies-in-numbers.md)
35
+
31
36
  <picture>
32
37
  <source media="(prefers-color-scheme: dark)" srcset="docs/checks-dark.svg">
33
38
  <source media="(prefers-color-scheme: light)" srcset="docs/checks-light.svg">
@@ -71,6 +76,14 @@ proxy-scraper
71
76
 
72
77
  The package is called `proxy-scraper-cli` on PyPI (the plain name is taken), the command is `proxy-scraper`.
73
78
 
79
+ **With [Homebrew](https://brew.sh)** on macOS and Linux:
80
+
81
+ ```bash
82
+ brew install maximilianfeix/tap/proxy-scraper
83
+ ```
84
+
85
+ The formula follows each release within about a day.
86
+
74
87
  <details>
75
88
  <summary><b>Other ways: Docker, pip, a faster event loop, or straight from the repo</b></summary>
76
89
  <br>
@@ -107,7 +120,7 @@ proxy-scraper --completion fish > ~/.config/fish/completions/proxy-scraper.fish
107
120
  proxy-scraper --completion powershell | Out-String | Invoke-Expression # in $PROFILE
108
121
  ```
109
122
 
110
- Installed, the learned state lives in your user data folder (`~/Library/Application Support/proxy-scraper`, `%LOCALAPPDATA%\proxy-scraper` or `~/.local/share/proxy-scraper`; override with `PROXY_SCRAPER_HOME`) and results go to `./results`. Run from a clone, both stay inside the project.
123
+ Installed, the learned state lives in your user data folder (`~/Library/Application Support/proxy-scraper`, `%LOCALAPPDATA%\proxy-scraper` or `~/.local/share/proxy-scraper`; override with `PROXY_SCRAPER_HOME`) and results go to `./results`. Run from a clone, both stay inside the project. After the second run that finds proxies it asks once for a GitHub star; `PROXY_SCRAPER_NO_STAR_HINT=1` turns that off (it never shows in CI).
111
124
 
112
125
  </details>
113
126
 
@@ -135,7 +148,9 @@ Keys: <kbd>↑</kbd><kbd>↓</kbd> select · <kbd>Space</kbd> toggle · <kbd>1</
135
148
 
136
149
  ## Live proxy list
137
150
 
138
- Don't want to scan yourself? Every hour **GitHub Actions** runs the tool and publishes the hits to the [`proxy-list`](../../tree/proxy-list) branch – every entry worked in the last run, fastest first.
151
+ Don't want to scan yourself? Every hour **GitHub Actions** runs the tool and publishes the hits to the [`proxy-list`](../../tree/proxy-list) branch – every entry worked in the last run, best first: fast ones that are likely to still be up come on top.
152
+
153
+ > **Just want the lists?** They also live in a repository of their own, **[maximilianfeix/free-proxy-list](https://github.com/maximilianfeix/free-proxy-list)** – one list per protocol, per country and per site, updated every hour, with the numbers of the last run on the front page. Watch or star it to keep it at hand.
139
154
 
140
155
  <a href="https://maximilianfeix.github.io/proxy-scraper/"><picture>
141
156
  <source media="(prefers-color-scheme: dark)" srcset="https://maximilianfeix.github.io/proxy-scraper/chart-dark.svg">
@@ -276,7 +291,7 @@ Started without arguments, the tool asks what you need using the arrow keys –
276
291
  <td valign="top">
277
292
 
278
293
  **Real verification**<br>
279
- Every hit has to fetch two independent pages – that weeds out **honeypots** that only answer check requests (in some runs 5 out of 6 “hits”). A third request catches proxies that **tamper with content**: in our measurements one in five working proxies injected a script into a plain HTML page. Plus: HTTPS through a tunnel with **verified TLS**, anonymity level *elite / anonymous / transparent* and the country of the exit IP.
294
+ Every hit has to fetch two independent pages – that weeds out **honeypots** that only answer check requests: over 3.6 million checks, 54 % of the proxies that answered the first request failed the second. A third request catches proxies that **tamper with content**: about one in 40 working proxies changed a known page, usually by injecting a script ([the numbers](docs/free-proxies-in-numbers.md)). Plus: HTTPS through a tunnel with **verified TLS**, anonymity level *elite / anonymous / transparent* and the country of the exit IP.
280
295
 
281
296
  </td>
282
297
  <td valign="top">
@@ -318,13 +333,13 @@ Speed chart, latency histogram, protocols, countries and the latest hits in real
318
333
  <td valign="top">
319
334
 
320
335
  **Runs everywhere**<br>
321
- macOS, Linux and Windows, Python 3.9 to 3.13. Only two dependencies: `rich` and `certifi`. It even notices when a firewall blocks proxies.
336
+ macOS, Linux and Windows, Python 3.9 to 3.14. Only two dependencies: `rich` and `certifi`. It even notices when a firewall blocks proxies.
322
337
 
323
338
  </td>
324
339
  <td valign="top">
325
340
 
326
341
  **Thoroughly tested**<br>
327
- 450+ tests run offline against real mini proxies and honeypots on `localhost` – on Linux, macOS and Windows with Python 3.9, 3.11 and 3.13.
342
+ 760+ tests run offline against real mini proxies and honeypots on `localhost` – on Linux, macOS and Windows with Python 3.9, 3.11, 3.13 and 3.14.
328
343
 
329
344
  </td>
330
345
  </tr>
@@ -472,7 +487,7 @@ Without a password, `--serve-host` means **anyone who reaches the port can use i
472
487
 
473
488
  - every connection goes through a different proxy (unless sticky); fast and proven ones are preferred
474
489
  - `CONNECT` for HTTPS and plain HTTP requests; HTTP, SOCKS4 and SOCKS5 proxies can sit behind it (SOCKS5 with DNS through the proxy)
475
- - HTTPS only uses proxies that passed the test with **verified TLS** – no broken encryption
490
+ - HTTPS prefers proxies that passed the test with **verified TLS**; when no such proxy fits right now – none matches a wish like `country-de`, or they have all dropped out – it uses the others – your client's own certificate check still catches a proxy that breaks the encryption, so leave it on
476
491
  - if a proxy stays silent inside the tunnel or returns an error page instead of TLS, the same first packet quietly goes to the next one
477
492
  - three failures in a row and a proxy leaves the rotation – every 5 minutes those get re-checked and come back if they work again
478
493
  - `--serve-refill 6` checks fresh proxies every 6 hours in the background (the live list with `--recheck live`, otherwise the last run + history) with the same checks and filters, and adds the hits – a server that runs for days doesn't run dry
@@ -480,6 +495,10 @@ Without a password, `--serve-host` means **anyone who reaches the port can use i
480
495
 
481
496
  In testing: 20 of 20 HTTPS requests succeeded, over 15 different exit IPs. In the wizard this is **Proxy server right away**.
482
497
 
498
+ **Live dashboard:** open `http://127.0.0.1:8899/__proxy-scraper/` in a browser – the pool, success rate, traffic, a live chart of requests, countries, the best proxies and the latest connections, refreshed every two seconds. It needs nothing from the internet, and `--serve-password` protects it like the rest.
499
+
500
+ <div align="center"><img src="docs/dashboard-live.png" alt="The live dashboard of the rotating proxy server: usable proxies, success rate, requests per second, countries and the latest connections" width="860"></div>
501
+
483
502
  <a id="pool-api"></a>
484
503
 
485
504
  ### Proxy pool API
@@ -698,6 +717,18 @@ proxychains4 -f results/latest/proxychains.conf curl https://api.ipify.org
698
717
 
699
718
  `clash.yaml` has all HTTP and SOCKS5 proxies plus a `url-test` group that always picks the fastest. `singbox.json` does the same for sing-box, SOCKS4 included, and opens a local proxy: `sing-box run -c results/latest/singbox.json`, then use `127.0.0.1:2080` as HTTP or SOCKS5 proxy. All three leave out HTTP proxies that can't tunnel (`CONNECT`), because these tools tunnel everything.
700
719
 
720
+ **Browsers and the OS** – `--export pac` writes `proxy.pac`: point Firefox, Chrome (via the system settings), FoxyProxy or macOS/Windows proxy settings at it and every request goes through the best 30 HTTP and SOCKS5 proxies in order, the browser moving on by itself when one fails. Local names and private IP addresses stay direct (a host name like `10.example.com` doesn't count as private). The file itself has no `DIRECT` fallback and resolves no host names, and SOCKS4 is left out because it would make the browser resolve names with your own DNS. Two Firefox settings matter: turn on *Proxy DNS when using SOCKS v5*, and set `network.proxy.failover_direct` to `false` in `about:config` – otherwise Firefox goes direct once every proxy has failed. No install at all: the live list publishes one every hour at `https://maximilianfeix.github.io/proxy-scraper/proxy.pac`.
721
+
722
+ **Burp Suite, OWASP ZAP, mitmproxy** – put the rotating server behind your intercepting proxy, so a scan or a brute-force test comes from many IPs while you still see every request. Start it with `proxy-scraper --recheck live --serve`, then:
723
+
724
+ | Tool | Where | Set |
725
+ |---|---|---|
726
+ | Burp Suite | *Settings → Network → Connections → Upstream proxy servers* | a rule for destination host `*`, proxy host `127.0.0.1`, port `8899`; with `--serve-password` add Basic auth (user `any` or a wish like `country-de`, the password) |
727
+ | OWASP ZAP | *Options → Network → Connection → HTTP Proxy* | host `127.0.0.1`, port `8899`, and under its authentication the user (`any` or a wish) and the password – use the HTTP setting, not SOCKS: ZAP never sends loopback addresses through its SOCKS proxy |
728
+ | mitmproxy | command line | `mitmproxy --mode upstream:http://127.0.0.1:8899 --upstream-auth country-us:x` |
729
+
730
+ Username wishes – `country-us` sends everything out through US proxies, `session-NAME` keeps one exit IP for a login flow – reach the server as the proxy login. mitmproxy sends it right away; Burp and ZAP may wait to be asked, so start the server with `--serve-password` when you rely on a wish there. **Keep your tool's upstream certificate checks on** (no `--ssl-insecure` in mitmproxy, no "ignore certificate errors" upstream in Burp or ZAP): free proxies are strangers, and that check is what stops one from reading or changing your HTTPS traffic. Tested end to end with mitmproxy 12, certificate checks on: HTTP and HTTPS through mitmproxy and the rotating server, every request out through a US proxy, and a site with an expired certificate refused. Only test what you're allowed to.
731
+
701
732
  **In a pipe** – `-o -` prints the hits to stdout, the interface moves to stderr
702
733
 
703
734
  ```bash
@@ -791,7 +822,7 @@ curl.exe -x (Get-Content "$run\all.txt" -TotalCount 1) http://api.ipify.org
791
822
  | `--serve-refill HOURS` | while serving, check fresh proxies every HOURS and add the hits to the pool |
792
823
  | `--serve [PORT]` | afterwards serve as a rotating proxy on `127.0.0.1:PORT` (default: 8899) |
793
824
  | `-o FILE` | also write all hits to this file; `-o -` prints them to stdout |
794
- | `--export FORMATS` | extra files for other tools: `proxychains`, `clash`, `singbox`, `curl` or `all` |
825
+ | `--export FORMATS` | extra files for other tools: `proxychains`, `clash`, `singbox`, `curl`, `pac` or `all` |
795
826
  | `-V`, `--version` | print the version |
796
827
  | `--completion SHELL` | print the tab completion script for bash, zsh, fish or PowerShell |
797
828
 
@@ -877,8 +908,9 @@ Only for things that don't matter. Public proxies are run by strangers who can r
877
908
 
878
909
  What's next is in the [open issues](../../issues) – ideas and wishes are welcome as an [issue](../../issues/new/choose). During Hacktoberfest there are [beginner-friendly issues](../../issues?q=is%3Aopen+label%3Ahacktoberfest) with pointers on where to start.
879
910
 
880
- - [ ] [Measure throughput, not just latency](../../issues/140)
881
- - [ ] [Daily snapshots as a dataset](../../issues/143)
911
+ Shipped in v1.22 and v1.23: a live dashboard for the rotating server, `--export pac` and an hourly `proxy.pac`, "best first" that counts how likely a proxy is still up, the lists in a repository of their own ([free-proxy-list](https://github.com/maximilianfeix/free-proxy-list)), daily snapshots on Hugging Face, `brew install`, a Chinese README, Python 3.14, and a recipe for Burp Suite, ZAP and mitmproxy.
912
+
913
+ Shipped in v1.10 to v1.21: download speed per proxy and "best first" everywhere, daily snapshots, a rotating proxy URL for requests, httpx and Playwright, `--pick` for working proxies without a scan, a proxy pool API compatible with jhao104/proxy_pool, your own lists with `--source`, a GitHub Action, a Telegram bot and an Atom feed for the weekly report.
882
914
 
883
915
  Shipped in v1.8 and v1.9: uptime per proxy and `stable.txt`, which proxies get through to Google, Reddit and Amazon, `live_proxies()` in Python, a page per proxy with its week of checks, a weekly report, live charts in this README, shareable filters on the website, sources mined from other scrapers' lists, untyped lists tried as HTTP and SOCKS5, `--export singbox`, PowerShell completion and recipes for httpx, aiohttp and Scrapy.
884
916
 
@@ -925,12 +957,13 @@ proxyscraper/
925
957
  ├── geodb.py DB-IP country database (monthly, binary search)
926
958
  ├── targets.py target sites for --target
927
959
  ├── output.py result files
928
- ├── exporters.py proxychains, Clash, sing-box and curl formats (--export)
960
+ ├── exporters.py proxychains, Clash, sing-box, curl and PAC formats (--export)
929
961
  ├── server/ rotating proxy server (--serve): pool · http · upstream · socks · status · api · core
930
962
  ├── api.py find_proxies() / check_proxies() for Python
931
963
  ├── agent.py MCP tools without the SDK: live list, filters, fetch through proxies
932
964
  ├── mcp_server.py MCP server (proxy-scraper-mcp) for AI agents
933
965
  ├── publish.py live list for GitHub Actions
966
+ ├── mirror.py the same lists in their own repo (free-proxy-list)
934
967
  ├── paths.py where state and results are stored
935
968
  ├── compat.py differences between Unix and Windows
936
969
  ├── netio.py small HTTP client on asyncio
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: proxy-scraper-cli
3
- Version: 1.21.0
3
+ Version: 1.23.0
4
4
  Summary: Finds free HTTP, SOCKS4 and SOCKS5 proxies that actually work: 700+ sources, real checks, honeypot filtering and a rotating local proxy server.
5
5
  Author: Maximilian Feix
6
6
  License-Expression: MIT
@@ -22,6 +22,7 @@ Classifier: Programming Language :: Python :: 3.10
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
24
  Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Programming Language :: Python :: 3.14
25
26
  Classifier: Topic :: Internet :: Proxy Servers
26
27
  Classifier: Topic :: System :: Networking
27
28
  Requires-Python: >=3.9
@@ -36,7 +37,7 @@ Requires-Dist: mcp<3,>=2.2; python_version >= "3.10" and extra == "mcp"
36
37
  Provides-Extra: dev
37
38
  Requires-Dist: pytest; extra == "dev"
38
39
  Requires-Dist: hypothesis; extra == "dev"
39
- Requires-Dist: ruff==0.16.8; extra == "dev"
40
+ Requires-Dist: ruff==0.16.9; extra == "dev"
40
41
  Dynamic: license-file
41
42
 
42
43
  <div align="center">
@@ -51,16 +52,19 @@ Dynamic: license-file
51
52
  [![Release](https://img.shields.io/github/v/release/maximilianfeix/proxy-scraper?style=flat-square&color=D4F77A&labelColor=121113)](https://github.com/maximilianfeix/proxy-scraper/releases/latest)
52
53
  [![Live proxies](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fmaximilianfeix%2Fproxy-scraper%2Fproxy-list%2Fbadges%2Ftotal.json&style=flat-square&labelColor=121113)](#live-list)
53
54
  [![PyPI](https://img.shields.io/pypi/v/proxy-scraper-cli?style=flat-square&color=D4F77A&labelColor=121113&label=pypi)](https://pypi.org/project/proxy-scraper-cli/)
54
- [![Python](https://img.shields.io/badge/python-3.9–3.13-D4F77A?style=flat-square&labelColor=121113)](pyproject.toml)
55
+ [![Python](https://img.shields.io/badge/python-3.9–3.14-D4F77A?style=flat-square&labelColor=121113)](pyproject.toml)
55
56
  [![Stars](https://img.shields.io/github/stars/maximilianfeix/proxy-scraper?style=flat-square&color=D4F77A&labelColor=121113)](https://github.com/maximilianfeix/proxy-scraper/stargazers)
56
57
  [![License](https://img.shields.io/badge/license-MIT-D4F77A?style=flat-square&labelColor=121113)](LICENSE)
57
58
 
58
59
  <a href="https://maximilianfeix.github.io/proxy-scraper/"><img src="https://img.shields.io/badge/Browse_the_live_list-D4F77A?style=for-the-badge&labelColor=121113" alt="Browse the live list"></a>
60
+ <a href="https://github.com/maximilianfeix/free-proxy-list"><img src="https://img.shields.io/badge/Just_the_lists-121113?style=for-the-badge" alt="Just the lists: free-proxy-list"></a>
59
61
  <a href="#install"><img src="https://img.shields.io/badge/Install-121113?style=for-the-badge" alt="Install"></a>
60
62
  <a href="#from-python"><img src="https://img.shields.io/badge/Python_API-121113?style=for-the-badge" alt="Python API"></a>
61
63
  <a href="#mcp"><img src="https://img.shields.io/badge/MCP_server-121113?style=for-the-badge" alt="MCP server for AI agents"></a>
62
64
  <a href="bot/"><img src="https://img.shields.io/badge/Discord_bot-121113?style=for-the-badge" alt="Discord bot"></a>
63
65
 
66
+ **English** · [简体中文](README.zh-CN.md)
67
+
64
68
  [Install](#install) · [Live list](#live-list) · [For AI agents](#mcp) · [Proxy server](#proxy-server) · [How it works](#how-it-works) · [Recipes](#recipes) · [Options](#options) · [FAQ](#faq)
65
69
 
66
70
  </div>
@@ -69,6 +73,8 @@ Dynamic: license-file
69
73
 
70
74
  Most free proxy lists are 95 % dead, and a good part of the rest are honeypots or proxies that inject scripts into your pages. **proxy-scraper** collects public HTTP, SOCKS4 and SOCKS5 proxies from 700+ sources and keeps only the ones that pass every check. It learns with every run which sources are worth it, and it can turn the result into a single rotating proxy.
71
75
 
76
+ **In numbers:** in one day it checked 3.6 million free proxies – 1.1 % worked, and more than half of the ones that answered failed a second request. [What's actually out there →](docs/free-proxies-in-numbers.md)
77
+
72
78
  <picture>
73
79
  <source media="(prefers-color-scheme: dark)" srcset="docs/checks-dark.svg">
74
80
  <source media="(prefers-color-scheme: light)" srcset="docs/checks-light.svg">
@@ -112,6 +118,14 @@ proxy-scraper
112
118
 
113
119
  The package is called `proxy-scraper-cli` on PyPI (the plain name is taken), the command is `proxy-scraper`.
114
120
 
121
+ **With [Homebrew](https://brew.sh)** on macOS and Linux:
122
+
123
+ ```bash
124
+ brew install maximilianfeix/tap/proxy-scraper
125
+ ```
126
+
127
+ The formula follows each release within about a day.
128
+
115
129
  <details>
116
130
  <summary><b>Other ways: Docker, pip, a faster event loop, or straight from the repo</b></summary>
117
131
  <br>
@@ -148,7 +162,7 @@ proxy-scraper --completion fish > ~/.config/fish/completions/proxy-scraper.fish
148
162
  proxy-scraper --completion powershell | Out-String | Invoke-Expression # in $PROFILE
149
163
  ```
150
164
 
151
- Installed, the learned state lives in your user data folder (`~/Library/Application Support/proxy-scraper`, `%LOCALAPPDATA%\proxy-scraper` or `~/.local/share/proxy-scraper`; override with `PROXY_SCRAPER_HOME`) and results go to `./results`. Run from a clone, both stay inside the project.
165
+ Installed, the learned state lives in your user data folder (`~/Library/Application Support/proxy-scraper`, `%LOCALAPPDATA%\proxy-scraper` or `~/.local/share/proxy-scraper`; override with `PROXY_SCRAPER_HOME`) and results go to `./results`. Run from a clone, both stay inside the project. After the second run that finds proxies it asks once for a GitHub star; `PROXY_SCRAPER_NO_STAR_HINT=1` turns that off (it never shows in CI).
152
166
 
153
167
  </details>
154
168
 
@@ -176,7 +190,9 @@ Keys: <kbd>↑</kbd><kbd>↓</kbd> select · <kbd>Space</kbd> toggle · <kbd>1</
176
190
 
177
191
  ## Live proxy list
178
192
 
179
- Don't want to scan yourself? Every hour **GitHub Actions** runs the tool and publishes the hits to the [`proxy-list`](../../tree/proxy-list) branch – every entry worked in the last run, fastest first.
193
+ Don't want to scan yourself? Every hour **GitHub Actions** runs the tool and publishes the hits to the [`proxy-list`](../../tree/proxy-list) branch – every entry worked in the last run, best first: fast ones that are likely to still be up come on top.
194
+
195
+ > **Just want the lists?** They also live in a repository of their own, **[maximilianfeix/free-proxy-list](https://github.com/maximilianfeix/free-proxy-list)** – one list per protocol, per country and per site, updated every hour, with the numbers of the last run on the front page. Watch or star it to keep it at hand.
180
196
 
181
197
  <a href="https://maximilianfeix.github.io/proxy-scraper/"><picture>
182
198
  <source media="(prefers-color-scheme: dark)" srcset="https://maximilianfeix.github.io/proxy-scraper/chart-dark.svg">
@@ -317,7 +333,7 @@ Started without arguments, the tool asks what you need using the arrow keys –
317
333
  <td valign="top">
318
334
 
319
335
  **Real verification**<br>
320
- Every hit has to fetch two independent pages – that weeds out **honeypots** that only answer check requests (in some runs 5 out of 6 “hits”). A third request catches proxies that **tamper with content**: in our measurements one in five working proxies injected a script into a plain HTML page. Plus: HTTPS through a tunnel with **verified TLS**, anonymity level *elite / anonymous / transparent* and the country of the exit IP.
336
+ Every hit has to fetch two independent pages – that weeds out **honeypots** that only answer check requests: over 3.6 million checks, 54 % of the proxies that answered the first request failed the second. A third request catches proxies that **tamper with content**: about one in 40 working proxies changed a known page, usually by injecting a script ([the numbers](docs/free-proxies-in-numbers.md)). Plus: HTTPS through a tunnel with **verified TLS**, anonymity level *elite / anonymous / transparent* and the country of the exit IP.
321
337
 
322
338
  </td>
323
339
  <td valign="top">
@@ -359,13 +375,13 @@ Speed chart, latency histogram, protocols, countries and the latest hits in real
359
375
  <td valign="top">
360
376
 
361
377
  **Runs everywhere**<br>
362
- macOS, Linux and Windows, Python 3.9 to 3.13. Only two dependencies: `rich` and `certifi`. It even notices when a firewall blocks proxies.
378
+ macOS, Linux and Windows, Python 3.9 to 3.14. Only two dependencies: `rich` and `certifi`. It even notices when a firewall blocks proxies.
363
379
 
364
380
  </td>
365
381
  <td valign="top">
366
382
 
367
383
  **Thoroughly tested**<br>
368
- 450+ tests run offline against real mini proxies and honeypots on `localhost` – on Linux, macOS and Windows with Python 3.9, 3.11 and 3.13.
384
+ 760+ tests run offline against real mini proxies and honeypots on `localhost` – on Linux, macOS and Windows with Python 3.9, 3.11, 3.13 and 3.14.
369
385
 
370
386
  </td>
371
387
  </tr>
@@ -513,7 +529,7 @@ Without a password, `--serve-host` means **anyone who reaches the port can use i
513
529
 
514
530
  - every connection goes through a different proxy (unless sticky); fast and proven ones are preferred
515
531
  - `CONNECT` for HTTPS and plain HTTP requests; HTTP, SOCKS4 and SOCKS5 proxies can sit behind it (SOCKS5 with DNS through the proxy)
516
- - HTTPS only uses proxies that passed the test with **verified TLS** – no broken encryption
532
+ - HTTPS prefers proxies that passed the test with **verified TLS**; when no such proxy fits right now – none matches a wish like `country-de`, or they have all dropped out – it uses the others – your client's own certificate check still catches a proxy that breaks the encryption, so leave it on
517
533
  - if a proxy stays silent inside the tunnel or returns an error page instead of TLS, the same first packet quietly goes to the next one
518
534
  - three failures in a row and a proxy leaves the rotation – every 5 minutes those get re-checked and come back if they work again
519
535
  - `--serve-refill 6` checks fresh proxies every 6 hours in the background (the live list with `--recheck live`, otherwise the last run + history) with the same checks and filters, and adds the hits – a server that runs for days doesn't run dry
@@ -521,6 +537,10 @@ Without a password, `--serve-host` means **anyone who reaches the port can use i
521
537
 
522
538
  In testing: 20 of 20 HTTPS requests succeeded, over 15 different exit IPs. In the wizard this is **Proxy server right away**.
523
539
 
540
+ **Live dashboard:** open `http://127.0.0.1:8899/__proxy-scraper/` in a browser – the pool, success rate, traffic, a live chart of requests, countries, the best proxies and the latest connections, refreshed every two seconds. It needs nothing from the internet, and `--serve-password` protects it like the rest.
541
+
542
+ <div align="center"><img src="docs/dashboard-live.png" alt="The live dashboard of the rotating proxy server: usable proxies, success rate, requests per second, countries and the latest connections" width="860"></div>
543
+
524
544
  <a id="pool-api"></a>
525
545
 
526
546
  ### Proxy pool API
@@ -739,6 +759,18 @@ proxychains4 -f results/latest/proxychains.conf curl https://api.ipify.org
739
759
 
740
760
  `clash.yaml` has all HTTP and SOCKS5 proxies plus a `url-test` group that always picks the fastest. `singbox.json` does the same for sing-box, SOCKS4 included, and opens a local proxy: `sing-box run -c results/latest/singbox.json`, then use `127.0.0.1:2080` as HTTP or SOCKS5 proxy. All three leave out HTTP proxies that can't tunnel (`CONNECT`), because these tools tunnel everything.
741
761
 
762
+ **Browsers and the OS** – `--export pac` writes `proxy.pac`: point Firefox, Chrome (via the system settings), FoxyProxy or macOS/Windows proxy settings at it and every request goes through the best 30 HTTP and SOCKS5 proxies in order, the browser moving on by itself when one fails. Local names and private IP addresses stay direct (a host name like `10.example.com` doesn't count as private). The file itself has no `DIRECT` fallback and resolves no host names, and SOCKS4 is left out because it would make the browser resolve names with your own DNS. Two Firefox settings matter: turn on *Proxy DNS when using SOCKS v5*, and set `network.proxy.failover_direct` to `false` in `about:config` – otherwise Firefox goes direct once every proxy has failed. No install at all: the live list publishes one every hour at `https://maximilianfeix.github.io/proxy-scraper/proxy.pac`.
763
+
764
+ **Burp Suite, OWASP ZAP, mitmproxy** – put the rotating server behind your intercepting proxy, so a scan or a brute-force test comes from many IPs while you still see every request. Start it with `proxy-scraper --recheck live --serve`, then:
765
+
766
+ | Tool | Where | Set |
767
+ |---|---|---|
768
+ | Burp Suite | *Settings → Network → Connections → Upstream proxy servers* | a rule for destination host `*`, proxy host `127.0.0.1`, port `8899`; with `--serve-password` add Basic auth (user `any` or a wish like `country-de`, the password) |
769
+ | OWASP ZAP | *Options → Network → Connection → HTTP Proxy* | host `127.0.0.1`, port `8899`, and under its authentication the user (`any` or a wish) and the password – use the HTTP setting, not SOCKS: ZAP never sends loopback addresses through its SOCKS proxy |
770
+ | mitmproxy | command line | `mitmproxy --mode upstream:http://127.0.0.1:8899 --upstream-auth country-us:x` |
771
+
772
+ Username wishes – `country-us` sends everything out through US proxies, `session-NAME` keeps one exit IP for a login flow – reach the server as the proxy login. mitmproxy sends it right away; Burp and ZAP may wait to be asked, so start the server with `--serve-password` when you rely on a wish there. **Keep your tool's upstream certificate checks on** (no `--ssl-insecure` in mitmproxy, no "ignore certificate errors" upstream in Burp or ZAP): free proxies are strangers, and that check is what stops one from reading or changing your HTTPS traffic. Tested end to end with mitmproxy 12, certificate checks on: HTTP and HTTPS through mitmproxy and the rotating server, every request out through a US proxy, and a site with an expired certificate refused. Only test what you're allowed to.
773
+
742
774
  **In a pipe** – `-o -` prints the hits to stdout, the interface moves to stderr
743
775
 
744
776
  ```bash
@@ -832,7 +864,7 @@ curl.exe -x (Get-Content "$run\all.txt" -TotalCount 1) http://api.ipify.org
832
864
  | `--serve-refill HOURS` | while serving, check fresh proxies every HOURS and add the hits to the pool |
833
865
  | `--serve [PORT]` | afterwards serve as a rotating proxy on `127.0.0.1:PORT` (default: 8899) |
834
866
  | `-o FILE` | also write all hits to this file; `-o -` prints them to stdout |
835
- | `--export FORMATS` | extra files for other tools: `proxychains`, `clash`, `singbox`, `curl` or `all` |
867
+ | `--export FORMATS` | extra files for other tools: `proxychains`, `clash`, `singbox`, `curl`, `pac` or `all` |
836
868
  | `-V`, `--version` | print the version |
837
869
  | `--completion SHELL` | print the tab completion script for bash, zsh, fish or PowerShell |
838
870
 
@@ -918,8 +950,9 @@ Only for things that don't matter. Public proxies are run by strangers who can r
918
950
 
919
951
  What's next is in the [open issues](../../issues) – ideas and wishes are welcome as an [issue](../../issues/new/choose). During Hacktoberfest there are [beginner-friendly issues](../../issues?q=is%3Aopen+label%3Ahacktoberfest) with pointers on where to start.
920
952
 
921
- - [ ] [Measure throughput, not just latency](../../issues/140)
922
- - [ ] [Daily snapshots as a dataset](../../issues/143)
953
+ Shipped in v1.22 and v1.23: a live dashboard for the rotating server, `--export pac` and an hourly `proxy.pac`, "best first" that counts how likely a proxy is still up, the lists in a repository of their own ([free-proxy-list](https://github.com/maximilianfeix/free-proxy-list)), daily snapshots on Hugging Face, `brew install`, a Chinese README, Python 3.14, and a recipe for Burp Suite, ZAP and mitmproxy.
954
+
955
+ Shipped in v1.10 to v1.21: download speed per proxy and "best first" everywhere, daily snapshots, a rotating proxy URL for requests, httpx and Playwright, `--pick` for working proxies without a scan, a proxy pool API compatible with jhao104/proxy_pool, your own lists with `--source`, a GitHub Action, a Telegram bot and an Atom feed for the weekly report.
923
956
 
924
957
  Shipped in v1.8 and v1.9: uptime per proxy and `stable.txt`, which proxies get through to Google, Reddit and Amazon, `live_proxies()` in Python, a page per proxy with its week of checks, a weekly report, live charts in this README, shareable filters on the website, sources mined from other scrapers' lists, untyped lists tried as HTTP and SOCKS5, `--export singbox`, PowerShell completion and recipes for httpx, aiohttp and Scrapy.
925
958
 
@@ -966,12 +999,13 @@ proxyscraper/
966
999
  ├── geodb.py DB-IP country database (monthly, binary search)
967
1000
  ├── targets.py target sites for --target
968
1001
  ├── output.py result files
969
- ├── exporters.py proxychains, Clash, sing-box and curl formats (--export)
1002
+ ├── exporters.py proxychains, Clash, sing-box, curl and PAC formats (--export)
970
1003
  ├── server/ rotating proxy server (--serve): pool · http · upstream · socks · status · api · core
971
1004
  ├── api.py find_proxies() / check_proxies() for Python
972
1005
  ├── agent.py MCP tools without the SDK: live list, filters, fetch through proxies
973
1006
  ├── mcp_server.py MCP server (proxy-scraper-mcp) for AI agents
974
1007
  ├── publish.py live list for GitHub Actions
1008
+ ├── mirror.py the same lists in their own repo (free-proxy-list)
975
1009
  ├── paths.py where state and results are stored
976
1010
  ├── compat.py differences between Unix and Windows
977
1011
  ├── netio.py small HTTP client on asyncio
@@ -29,6 +29,7 @@ proxyscraper/history.py
29
29
  proxyscraper/judges.py
30
30
  proxyscraper/mcp_entry.py
31
31
  proxyscraper/mcp_server.py
32
+ proxyscraper/mirror.py
32
33
  proxyscraper/netio.py
33
34
  proxyscraper/options.py
34
35
  proxyscraper/output.py
@@ -50,6 +51,7 @@ proxyscraper/targets.py
50
51
  proxyscraper/server/__init__.py
51
52
  proxyscraper/server/api.py
52
53
  proxyscraper/server/core.py
54
+ proxyscraper/server/dashboard.html
53
55
  proxyscraper/server/http.py
54
56
  proxyscraper/server/pool.py
55
57
  proxyscraper/server/socks.py
@@ -87,9 +89,11 @@ tests/test_learning.py
87
89
  tests/test_live_api.py
88
90
  tests/test_mcp_server.py
89
91
  tests/test_mine_sources.py
92
+ tests/test_mirror.py
90
93
  tests/test_options.py
91
94
  tests/test_output_stdout.py
92
95
  tests/test_own_sources.py
96
+ tests/test_pac.py
93
97
  tests/test_packaging.py
94
98
  tests/test_pages.py
95
99
  tests/test_parsing.py
@@ -97,6 +101,7 @@ tests/test_parsing_fuzz.py
97
101
  tests/test_paths.py
98
102
  tests/test_pick.py
99
103
  tests/test_pipeline.py
104
+ tests/test_preferences.py
100
105
  tests/test_proxy_pages.py
101
106
  tests/test_proxy_sources.py
102
107
  tests/test_publish.py
@@ -104,6 +109,7 @@ tests/test_report.py
104
109
  tests/test_robustness.py
105
110
  tests/test_rotator.py
106
111
  tests/test_serve_api.py
112
+ tests/test_serve_dashboard.py
107
113
  tests/test_serve_password.py
108
114
  tests/test_serve_refill.py
109
115
  tests/test_serve_v2.py
@@ -114,6 +120,7 @@ tests/test_sites.py
114
120
  tests/test_sources_json.py
115
121
  tests/test_speed.py
116
122
  tests/test_speed_ranking.py
123
+ tests/test_survival_ranking.py
117
124
  tests/test_tamper.py
118
125
  tests/test_targets.py
119
126
  tests/test_ui.py
@@ -4,7 +4,7 @@ certifi
4
4
  [dev]
5
5
  pytest
6
6
  hypothesis
7
- ruff==0.16.8
7
+ ruff==0.16.9
8
8
 
9
9
  [fast]
10
10