proxy-scraper-cli 1.23.0__tar.gz → 1.24.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.
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/PKG-INFO +61 -10
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/README.md +60 -9
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxy_scraper_cli.egg-info/PKG-INFO +61 -10
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxy_scraper_cli.egg-info/SOURCES.txt +1 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/__init__.py +1 -1
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/api.py +1 -1
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/app.py +99 -6
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/cli.py +1 -1
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/pages.py +2 -2
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/parsing.py +5 -4
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/site/index.html +3 -3
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/sites.py +3 -0
- proxy_scraper_cli-1.24.0/tests/test_recheck_stdin.py +263 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_sites.py +22 -5
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/LICENSE +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxy_scraper_cli.egg-info/dependency_links.txt +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxy_scraper_cli.egg-info/entry_points.txt +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxy_scraper_cli.egg-info/requires.txt +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxy_scraper_cli.egg-info/top_level.txt +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/__main__.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/action.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/agent.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/asndb.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/blocklist.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/charts.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/checker.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/compat.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/completion.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/exporters.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/fetchcache.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/geo.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/geodb.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/handshake.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/history.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/judges.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/mcp_entry.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/mcp_server.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/mirror.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/netio.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/options.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/output.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/paths.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/pipeline.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/preferences.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/proxypages.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/publish.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/ranking.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/report.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/runsteps.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/server/__init__.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/server/api.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/server/core.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/server/dashboard.html +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/server/http.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/server/pool.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/server/socks.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/server/status.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/server/upstream.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/site/apple-touch-icon.png +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/site/googleaac1161b7853c5b5.html +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/site/logo.png +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/site/og.png +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/sources.json +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/sources.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/speed.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/targets.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/ui/__init__.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/ui/dashboard.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/ui/keys.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/ui/report.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/ui/serve.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/ui/widgets.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/proxyscraper/ui/wizard.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/pyproject.toml +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/setup.cfg +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_action.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_agent.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_api.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_app.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_asndb.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_auth.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_blocklist.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_charts.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_checker.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_compat.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_completion.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_discovery_growth.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_exporters.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_fetchcache.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_geodb.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_judges.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_learning.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_live_api.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_mcp_server.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_mine_sources.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_mirror.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_options.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_output_stdout.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_own_sources.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_pac.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_packaging.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_pages.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_parsing.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_parsing_fuzz.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_paths.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_pick.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_pipeline.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_preferences.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_proxy_pages.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_proxy_sources.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_publish.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_report.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_robustness.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_rotator.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_serve_api.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_serve_dashboard.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_serve_password.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_serve_refill.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_serve_v2.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_server.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_server_closed_writer.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_server_fixes.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_sources_json.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_speed.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_speed_ranking.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_survival_ranking.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_tamper.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_targets.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_ui.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.0}/tests/test_uptime.py +0 -0
- {proxy_scraper_cli-1.23.0 → proxy_scraper_cli-1.24.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.
|
|
3
|
+
Version: 1.24.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
|
|
@@ -75,16 +75,23 @@ Most free proxy lists are 95 % dead, and a good part of the rest are honeypots o
|
|
|
75
75
|
|
|
76
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
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
**Try it – no install, about five seconds:**
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
uvx proxy-scraper-cli --pick 5 --types socks5 # 5 checked proxies
|
|
82
|
+
|
|
83
|
+
# or just the plain list
|
|
84
|
+
curl -s https://maximilianfeix.github.io/proxy-scraper/socks5.txt | head
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`uvx` comes with [uv](https://docs.astral.sh/uv/); `pipx run proxy-scraper-cli --pick 5` does the same.
|
|
83
88
|
|
|
84
89
|
<div align="center">
|
|
85
|
-
<img src="docs/demo.svg" alt="Animated demo:
|
|
90
|
+
<img src="docs/demo.svg" alt="Animated demo: the live dashboard during a check, the report, the setup wizard and collecting" width="880">
|
|
86
91
|
</div>
|
|
87
92
|
|
|
93
|
+
> **Who runs free proxies – and is it safe to use them?** Mostly nobody on purpose: misconfigured servers with an open port, a few deliberately open ones, infected machines, and traps that log or rewrite your traffic. That's why every proxy here has to pass [five checks](#how-it-works), and why they're for public data and testing – never for logins, payments or anything personal. [More on where they come from →](#who-runs-free-proxies)
|
|
94
|
+
|
|
88
95
|
<details>
|
|
89
96
|
<summary><b>Table of contents</b></summary>
|
|
90
97
|
|
|
@@ -222,7 +229,7 @@ Every protocol and country also has its own page with a plain download, e.g. [SO
|
|
|
222
229
|
| HTTP · SOCKS4 · SOCKS5 | `1.2.3.4:8080` | [http.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/http.txt) · [socks4.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/socks4.txt) · [socks5.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/socks5.txt) |
|
|
223
230
|
| HTTPS-capable only | `type://ip:port` | [https.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/https.txt) |
|
|
224
231
|
| Elite only | `type://ip:port` | [elite.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/elite.txt) |
|
|
225
|
-
| Gets through to Google · Reddit · Amazon · Instagram · TikTok (no captcha, no block in the last run) | `type://ip:port` | [google.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/google.txt) · [reddit.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/reddit.txt) · [amazon.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/amazon.txt) · [instagram.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/instagram.txt) · [tiktok.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/tiktok.txt) |
|
|
232
|
+
| Gets through to Google · Reddit · Amazon · Instagram · TikTok · Discord (no captcha, no block in the last run) | `type://ip:port` | [google.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/google.txt) · [reddit.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/reddit.txt) · [amazon.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/amazon.txt) · [instagram.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/instagram.txt) · [tiktok.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/tiktok.txt) · [discord.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/discord.txt) |
|
|
226
233
|
| Stable, on the list in 90 %+ of this week's runs | `type://ip:port` | [stable.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/stable.txt) |
|
|
227
234
|
| With all details | latency, country, HTTPS, anonymity, exit IP, uptime, sites | [proxies.json](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/proxies.json) · [proxies.csv](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/proxies.csv) |
|
|
228
235
|
|
|
@@ -460,7 +467,7 @@ pool = itertools.cycle(p.url for p in proxies)
|
|
|
460
467
|
r = requests.get("https://api.ipify.org", proxies={"https": next(pool)}, timeout=15) # pip install "requests[socks]"
|
|
461
468
|
```
|
|
462
469
|
|
|
463
|
-
Same filters as `find_proxies`, plus `min_uptime`, `works_on` (`["google"]`, `"reddit"`, `"amazon"`, `"instagram"`, `"tiktok"`) and `limit`. Every result also has `uptime_24h`, `uptime_7d`, `first_seen`, `up_for_hours` and `sites`.
|
|
470
|
+
Same filters as `find_proxies`, plus `min_uptime`, `works_on` (`["google"]`, `"reddit"`, `"amazon"`, `"instagram"`, `"tiktok"`, `"discord"`) and `limit`. Every result also has `uptime_24h`, `uptime_7d`, `first_seen`, `up_for_hours` and `sites`.
|
|
464
471
|
|
|
465
472
|
Or let the library do the retrying: `ProxyRotator` loads a URL through the list and moves on to the next proxy when one fails – HTTPS only through proxies with verified TLS.
|
|
466
473
|
|
|
@@ -583,6 +590,13 @@ The live list can also come to you: [`bot/`](bot/) is a Discord bot that posts e
|
|
|
583
590
|
|
|
584
591
|
## How it works
|
|
585
592
|
|
|
593
|
+
<picture>
|
|
594
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/checks-dark.svg">
|
|
595
|
+
<source media="(prefers-color-scheme: light)" srcset="docs/checks-light.svg">
|
|
596
|
+
<img src="docs/checks-dark.svg" alt="The five checks: 700+ lists, a real handshake, two sites with one IP, nothing injected, the details" width="100%">
|
|
597
|
+
</picture>
|
|
598
|
+
|
|
599
|
+
|
|
586
600
|
```mermaid
|
|
587
601
|
flowchart LR
|
|
588
602
|
A[sources.json<br/>meta lists<br/>GitHub discovery] --> B[Fetch & parse<br/>in parallel on all cores]
|
|
@@ -777,6 +791,14 @@ Username wishes – `country-us` sends everything out through US proxies, `sessi
|
|
|
777
791
|
proxy-scraper --recheck live --want 20 -y -o - | grep '^socks5://' > socks.txt
|
|
778
792
|
```
|
|
779
793
|
|
|
794
|
+
**Check a list you already have** – `--recheck -` reads it from stdin: plain `ip:port` lines, `type://ip:port`, logins, JSON, a CSV export or a table pasted from a website (HTML or Markdown), in the order it came in. Only what works from your network comes out:
|
|
795
|
+
|
|
796
|
+
```bash
|
|
797
|
+
curl -s https://example.com/proxies.txt | proxy-scraper --recheck - -o - > working.txt
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
Proxies without a type are tried as HTTP and as SOCKS5 – or as SOCKS4 with `--types socks4` alone. A password with a comma, quote, `|` or bracket can't be told apart from the text around it in a paste; put such proxies in a file, one per line, and use `--recheck file.txt`.
|
|
801
|
+
|
|
780
802
|
**Any tool, through the rotating server**
|
|
781
803
|
|
|
782
804
|
```bash
|
|
@@ -849,7 +871,7 @@ curl.exe -x (Get-Content "$run\all.txt" -TotalCount 1) http://api.ipify.org
|
|
|
849
871
|
| `--no-blocklisted` | skip proxies whose exit IP is on the SpamCop blocklist – those often get captchas |
|
|
850
872
|
| `--no-dnsbl` | skip the blocklist lookup |
|
|
851
873
|
| `--target URL` | only proxies that reach this site (repeatable) |
|
|
852
|
-
| `--recheck [FILE
|
|
874
|
+
| `--recheck [FILE\|-\|live]` | only check proxies from a file, stdin (`-`), the last run, or the public live list |
|
|
853
875
|
| `--fast` | skip the HTTPS test (confirmation and anonymity still run) |
|
|
854
876
|
| `--no-geo` | skip the country lookup |
|
|
855
877
|
| `-c`, `--concurrency N` | simultaneous checks (default: 2000) |
|
|
@@ -896,6 +918,25 @@ The repo does part of the work itself:
|
|
|
896
918
|
|
|
897
919
|
## FAQ
|
|
898
920
|
|
|
921
|
+
<a id="who-runs-free-proxies"></a>
|
|
922
|
+
|
|
923
|
+
<details open>
|
|
924
|
+
<summary><b>Who runs free proxies – and should you use them?</b></summary>
|
|
925
|
+
<br>
|
|
926
|
+
|
|
927
|
+
Almost nobody runs a free proxy for you. What ends up on public lists is usually one of these:
|
|
928
|
+
|
|
929
|
+
- **Misconfigured servers** – a Squid, a router or an app with a proxy port that was meant to stay internal.
|
|
930
|
+
- **Deliberately open proxies** – a few volunteers and research projects, and services that give some away to sell the rest.
|
|
931
|
+
- **Infected machines** – computers and IoT devices whose owners don't know they relay traffic. Many residential exits are like this.
|
|
932
|
+
- **Traps** – honeypots that log what goes through them, and proxies that rewrite pages to inject ads or scripts.
|
|
933
|
+
|
|
934
|
+
proxy-scraper can't tell an infected home router from an open office proxy, but it filters what it can measure: a proxy has to answer two independent requests with the same exit IP (honeypots that only answer scanners drop out), deliver a known page byte for byte (injectors drop out), and HTTPS counts only with a certificate that verifies end to end. Each hit says whether its exit is in a datacenter.
|
|
935
|
+
|
|
936
|
+
Good uses: public data, checking how a site looks from another country, testing your own blocking and rate limits, research. Never send passwords, cookies, payment or personal data through a free proxy, and keep HTTPS certificate checks on. Use them only where you're allowed to.
|
|
937
|
+
|
|
938
|
+
</details>
|
|
939
|
+
|
|
899
940
|
<details>
|
|
900
941
|
<summary><b>Almost nothing gets through.</b></summary>
|
|
901
942
|
<br>
|
|
@@ -950,6 +991,8 @@ Only for things that don't matter. Public proxies are run by strangers who can r
|
|
|
950
991
|
|
|
951
992
|
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.
|
|
952
993
|
|
|
994
|
+
Shipped in v1.24: `--recheck -` for lists you pipe in, which proxies get through to Discord, and a README you can try in five seconds.
|
|
995
|
+
|
|
953
996
|
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
997
|
|
|
955
998
|
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.
|
|
@@ -1020,6 +1063,14 @@ proxyscraper/
|
|
|
1020
1063
|
|
|
1021
1064
|
Questions, ideas and things you built with it go to [Discussions](https://github.com/maximilianfeix/proxy-scraper/discussions) – bugs to the [issues](../../issues). If proxy-scraper saves you time, a ⭐ helps others find it.
|
|
1022
1065
|
|
|
1066
|
+
Thanks to everyone who helped build it – new sources, countries, Python 3.14, examples and more:
|
|
1067
|
+
|
|
1068
|
+
<a href="https://github.com/maximilianfeix/proxy-scraper/graphs/contributors">
|
|
1069
|
+
<img src="https://contrib.rocks/image?repo=maximilianfeix/proxy-scraper" alt="Contributors to proxy-scraper">
|
|
1070
|
+
</a>
|
|
1071
|
+
|
|
1072
|
+
Want to join? [Beginner-friendly issues](../../issues?q=is%3Aopen+label%3A%22good+first+issue%22) say where to start.
|
|
1073
|
+
|
|
1023
1074
|
<a href="https://star-history.com/#maximilianfeix/proxy-scraper&Date">
|
|
1024
1075
|
<picture>
|
|
1025
1076
|
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=maximilianfeix/proxy-scraper&type=Date&theme=dark">
|
|
@@ -33,16 +33,23 @@ Most free proxy lists are 95 % dead, and a good part of the rest are honeypots o
|
|
|
33
33
|
|
|
34
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
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
**Try it – no install, about five seconds:**
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
uvx proxy-scraper-cli --pick 5 --types socks5 # 5 checked proxies
|
|
40
|
+
|
|
41
|
+
# or just the plain list
|
|
42
|
+
curl -s https://maximilianfeix.github.io/proxy-scraper/socks5.txt | head
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`uvx` comes with [uv](https://docs.astral.sh/uv/); `pipx run proxy-scraper-cli --pick 5` does the same.
|
|
41
46
|
|
|
42
47
|
<div align="center">
|
|
43
|
-
<img src="docs/demo.svg" alt="Animated demo:
|
|
48
|
+
<img src="docs/demo.svg" alt="Animated demo: the live dashboard during a check, the report, the setup wizard and collecting" width="880">
|
|
44
49
|
</div>
|
|
45
50
|
|
|
51
|
+
> **Who runs free proxies – and is it safe to use them?** Mostly nobody on purpose: misconfigured servers with an open port, a few deliberately open ones, infected machines, and traps that log or rewrite your traffic. That's why every proxy here has to pass [five checks](#how-it-works), and why they're for public data and testing – never for logins, payments or anything personal. [More on where they come from →](#who-runs-free-proxies)
|
|
52
|
+
|
|
46
53
|
<details>
|
|
47
54
|
<summary><b>Table of contents</b></summary>
|
|
48
55
|
|
|
@@ -180,7 +187,7 @@ Every protocol and country also has its own page with a plain download, e.g. [SO
|
|
|
180
187
|
| HTTP · SOCKS4 · SOCKS5 | `1.2.3.4:8080` | [http.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/http.txt) · [socks4.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/socks4.txt) · [socks5.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/socks5.txt) |
|
|
181
188
|
| HTTPS-capable only | `type://ip:port` | [https.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/https.txt) |
|
|
182
189
|
| Elite only | `type://ip:port` | [elite.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/elite.txt) |
|
|
183
|
-
| Gets through to Google · Reddit · Amazon · Instagram · TikTok (no captcha, no block in the last run) | `type://ip:port` | [google.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/google.txt) · [reddit.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/reddit.txt) · [amazon.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/amazon.txt) · [instagram.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/instagram.txt) · [tiktok.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/tiktok.txt) |
|
|
190
|
+
| Gets through to Google · Reddit · Amazon · Instagram · TikTok · Discord (no captcha, no block in the last run) | `type://ip:port` | [google.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/google.txt) · [reddit.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/reddit.txt) · [amazon.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/amazon.txt) · [instagram.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/instagram.txt) · [tiktok.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/tiktok.txt) · [discord.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/discord.txt) |
|
|
184
191
|
| Stable, on the list in 90 %+ of this week's runs | `type://ip:port` | [stable.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/stable.txt) |
|
|
185
192
|
| With all details | latency, country, HTTPS, anonymity, exit IP, uptime, sites | [proxies.json](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/proxies.json) · [proxies.csv](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/proxies.csv) |
|
|
186
193
|
|
|
@@ -418,7 +425,7 @@ pool = itertools.cycle(p.url for p in proxies)
|
|
|
418
425
|
r = requests.get("https://api.ipify.org", proxies={"https": next(pool)}, timeout=15) # pip install "requests[socks]"
|
|
419
426
|
```
|
|
420
427
|
|
|
421
|
-
Same filters as `find_proxies`, plus `min_uptime`, `works_on` (`["google"]`, `"reddit"`, `"amazon"`, `"instagram"`, `"tiktok"`) and `limit`. Every result also has `uptime_24h`, `uptime_7d`, `first_seen`, `up_for_hours` and `sites`.
|
|
428
|
+
Same filters as `find_proxies`, plus `min_uptime`, `works_on` (`["google"]`, `"reddit"`, `"amazon"`, `"instagram"`, `"tiktok"`, `"discord"`) and `limit`. Every result also has `uptime_24h`, `uptime_7d`, `first_seen`, `up_for_hours` and `sites`.
|
|
422
429
|
|
|
423
430
|
Or let the library do the retrying: `ProxyRotator` loads a URL through the list and moves on to the next proxy when one fails – HTTPS only through proxies with verified TLS.
|
|
424
431
|
|
|
@@ -541,6 +548,13 @@ The live list can also come to you: [`bot/`](bot/) is a Discord bot that posts e
|
|
|
541
548
|
|
|
542
549
|
## How it works
|
|
543
550
|
|
|
551
|
+
<picture>
|
|
552
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/checks-dark.svg">
|
|
553
|
+
<source media="(prefers-color-scheme: light)" srcset="docs/checks-light.svg">
|
|
554
|
+
<img src="docs/checks-dark.svg" alt="The five checks: 700+ lists, a real handshake, two sites with one IP, nothing injected, the details" width="100%">
|
|
555
|
+
</picture>
|
|
556
|
+
|
|
557
|
+
|
|
544
558
|
```mermaid
|
|
545
559
|
flowchart LR
|
|
546
560
|
A[sources.json<br/>meta lists<br/>GitHub discovery] --> B[Fetch & parse<br/>in parallel on all cores]
|
|
@@ -735,6 +749,14 @@ Username wishes – `country-us` sends everything out through US proxies, `sessi
|
|
|
735
749
|
proxy-scraper --recheck live --want 20 -y -o - | grep '^socks5://' > socks.txt
|
|
736
750
|
```
|
|
737
751
|
|
|
752
|
+
**Check a list you already have** – `--recheck -` reads it from stdin: plain `ip:port` lines, `type://ip:port`, logins, JSON, a CSV export or a table pasted from a website (HTML or Markdown), in the order it came in. Only what works from your network comes out:
|
|
753
|
+
|
|
754
|
+
```bash
|
|
755
|
+
curl -s https://example.com/proxies.txt | proxy-scraper --recheck - -o - > working.txt
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
Proxies without a type are tried as HTTP and as SOCKS5 – or as SOCKS4 with `--types socks4` alone. A password with a comma, quote, `|` or bracket can't be told apart from the text around it in a paste; put such proxies in a file, one per line, and use `--recheck file.txt`.
|
|
759
|
+
|
|
738
760
|
**Any tool, through the rotating server**
|
|
739
761
|
|
|
740
762
|
```bash
|
|
@@ -807,7 +829,7 @@ curl.exe -x (Get-Content "$run\all.txt" -TotalCount 1) http://api.ipify.org
|
|
|
807
829
|
| `--no-blocklisted` | skip proxies whose exit IP is on the SpamCop blocklist – those often get captchas |
|
|
808
830
|
| `--no-dnsbl` | skip the blocklist lookup |
|
|
809
831
|
| `--target URL` | only proxies that reach this site (repeatable) |
|
|
810
|
-
| `--recheck [FILE
|
|
832
|
+
| `--recheck [FILE\|-\|live]` | only check proxies from a file, stdin (`-`), the last run, or the public live list |
|
|
811
833
|
| `--fast` | skip the HTTPS test (confirmation and anonymity still run) |
|
|
812
834
|
| `--no-geo` | skip the country lookup |
|
|
813
835
|
| `-c`, `--concurrency N` | simultaneous checks (default: 2000) |
|
|
@@ -854,6 +876,25 @@ The repo does part of the work itself:
|
|
|
854
876
|
|
|
855
877
|
## FAQ
|
|
856
878
|
|
|
879
|
+
<a id="who-runs-free-proxies"></a>
|
|
880
|
+
|
|
881
|
+
<details open>
|
|
882
|
+
<summary><b>Who runs free proxies – and should you use them?</b></summary>
|
|
883
|
+
<br>
|
|
884
|
+
|
|
885
|
+
Almost nobody runs a free proxy for you. What ends up on public lists is usually one of these:
|
|
886
|
+
|
|
887
|
+
- **Misconfigured servers** – a Squid, a router or an app with a proxy port that was meant to stay internal.
|
|
888
|
+
- **Deliberately open proxies** – a few volunteers and research projects, and services that give some away to sell the rest.
|
|
889
|
+
- **Infected machines** – computers and IoT devices whose owners don't know they relay traffic. Many residential exits are like this.
|
|
890
|
+
- **Traps** – honeypots that log what goes through them, and proxies that rewrite pages to inject ads or scripts.
|
|
891
|
+
|
|
892
|
+
proxy-scraper can't tell an infected home router from an open office proxy, but it filters what it can measure: a proxy has to answer two independent requests with the same exit IP (honeypots that only answer scanners drop out), deliver a known page byte for byte (injectors drop out), and HTTPS counts only with a certificate that verifies end to end. Each hit says whether its exit is in a datacenter.
|
|
893
|
+
|
|
894
|
+
Good uses: public data, checking how a site looks from another country, testing your own blocking and rate limits, research. Never send passwords, cookies, payment or personal data through a free proxy, and keep HTTPS certificate checks on. Use them only where you're allowed to.
|
|
895
|
+
|
|
896
|
+
</details>
|
|
897
|
+
|
|
857
898
|
<details>
|
|
858
899
|
<summary><b>Almost nothing gets through.</b></summary>
|
|
859
900
|
<br>
|
|
@@ -908,6 +949,8 @@ Only for things that don't matter. Public proxies are run by strangers who can r
|
|
|
908
949
|
|
|
909
950
|
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.
|
|
910
951
|
|
|
952
|
+
Shipped in v1.24: `--recheck -` for lists you pipe in, which proxies get through to Discord, and a README you can try in five seconds.
|
|
953
|
+
|
|
911
954
|
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
955
|
|
|
913
956
|
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.
|
|
@@ -978,6 +1021,14 @@ proxyscraper/
|
|
|
978
1021
|
|
|
979
1022
|
Questions, ideas and things you built with it go to [Discussions](https://github.com/maximilianfeix/proxy-scraper/discussions) – bugs to the [issues](../../issues). If proxy-scraper saves you time, a ⭐ helps others find it.
|
|
980
1023
|
|
|
1024
|
+
Thanks to everyone who helped build it – new sources, countries, Python 3.14, examples and more:
|
|
1025
|
+
|
|
1026
|
+
<a href="https://github.com/maximilianfeix/proxy-scraper/graphs/contributors">
|
|
1027
|
+
<img src="https://contrib.rocks/image?repo=maximilianfeix/proxy-scraper" alt="Contributors to proxy-scraper">
|
|
1028
|
+
</a>
|
|
1029
|
+
|
|
1030
|
+
Want to join? [Beginner-friendly issues](../../issues?q=is%3Aopen+label%3A%22good+first+issue%22) say where to start.
|
|
1031
|
+
|
|
981
1032
|
<a href="https://star-history.com/#maximilianfeix/proxy-scraper&Date">
|
|
982
1033
|
<picture>
|
|
983
1034
|
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=maximilianfeix/proxy-scraper&type=Date&theme=dark">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: proxy-scraper-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.24.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
|
|
@@ -75,16 +75,23 @@ Most free proxy lists are 95 % dead, and a good part of the rest are honeypots o
|
|
|
75
75
|
|
|
76
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
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
**Try it – no install, about five seconds:**
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
uvx proxy-scraper-cli --pick 5 --types socks5 # 5 checked proxies
|
|
82
|
+
|
|
83
|
+
# or just the plain list
|
|
84
|
+
curl -s https://maximilianfeix.github.io/proxy-scraper/socks5.txt | head
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`uvx` comes with [uv](https://docs.astral.sh/uv/); `pipx run proxy-scraper-cli --pick 5` does the same.
|
|
83
88
|
|
|
84
89
|
<div align="center">
|
|
85
|
-
<img src="docs/demo.svg" alt="Animated demo:
|
|
90
|
+
<img src="docs/demo.svg" alt="Animated demo: the live dashboard during a check, the report, the setup wizard and collecting" width="880">
|
|
86
91
|
</div>
|
|
87
92
|
|
|
93
|
+
> **Who runs free proxies – and is it safe to use them?** Mostly nobody on purpose: misconfigured servers with an open port, a few deliberately open ones, infected machines, and traps that log or rewrite your traffic. That's why every proxy here has to pass [five checks](#how-it-works), and why they're for public data and testing – never for logins, payments or anything personal. [More on where they come from →](#who-runs-free-proxies)
|
|
94
|
+
|
|
88
95
|
<details>
|
|
89
96
|
<summary><b>Table of contents</b></summary>
|
|
90
97
|
|
|
@@ -222,7 +229,7 @@ Every protocol and country also has its own page with a plain download, e.g. [SO
|
|
|
222
229
|
| HTTP · SOCKS4 · SOCKS5 | `1.2.3.4:8080` | [http.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/http.txt) · [socks4.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/socks4.txt) · [socks5.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/socks5.txt) |
|
|
223
230
|
| HTTPS-capable only | `type://ip:port` | [https.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/https.txt) |
|
|
224
231
|
| Elite only | `type://ip:port` | [elite.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/elite.txt) |
|
|
225
|
-
| Gets through to Google · Reddit · Amazon · Instagram · TikTok (no captcha, no block in the last run) | `type://ip:port` | [google.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/google.txt) · [reddit.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/reddit.txt) · [amazon.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/amazon.txt) · [instagram.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/instagram.txt) · [tiktok.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/tiktok.txt) |
|
|
232
|
+
| Gets through to Google · Reddit · Amazon · Instagram · TikTok · Discord (no captcha, no block in the last run) | `type://ip:port` | [google.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/google.txt) · [reddit.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/reddit.txt) · [amazon.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/amazon.txt) · [instagram.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/instagram.txt) · [tiktok.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/tiktok.txt) · [discord.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/works-with/discord.txt) |
|
|
226
233
|
| Stable, on the list in 90 %+ of this week's runs | `type://ip:port` | [stable.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/stable.txt) |
|
|
227
234
|
| With all details | latency, country, HTTPS, anonymity, exit IP, uptime, sites | [proxies.json](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/proxies.json) · [proxies.csv](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/proxies.csv) |
|
|
228
235
|
|
|
@@ -460,7 +467,7 @@ pool = itertools.cycle(p.url for p in proxies)
|
|
|
460
467
|
r = requests.get("https://api.ipify.org", proxies={"https": next(pool)}, timeout=15) # pip install "requests[socks]"
|
|
461
468
|
```
|
|
462
469
|
|
|
463
|
-
Same filters as `find_proxies`, plus `min_uptime`, `works_on` (`["google"]`, `"reddit"`, `"amazon"`, `"instagram"`, `"tiktok"`) and `limit`. Every result also has `uptime_24h`, `uptime_7d`, `first_seen`, `up_for_hours` and `sites`.
|
|
470
|
+
Same filters as `find_proxies`, plus `min_uptime`, `works_on` (`["google"]`, `"reddit"`, `"amazon"`, `"instagram"`, `"tiktok"`, `"discord"`) and `limit`. Every result also has `uptime_24h`, `uptime_7d`, `first_seen`, `up_for_hours` and `sites`.
|
|
464
471
|
|
|
465
472
|
Or let the library do the retrying: `ProxyRotator` loads a URL through the list and moves on to the next proxy when one fails – HTTPS only through proxies with verified TLS.
|
|
466
473
|
|
|
@@ -583,6 +590,13 @@ The live list can also come to you: [`bot/`](bot/) is a Discord bot that posts e
|
|
|
583
590
|
|
|
584
591
|
## How it works
|
|
585
592
|
|
|
593
|
+
<picture>
|
|
594
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/checks-dark.svg">
|
|
595
|
+
<source media="(prefers-color-scheme: light)" srcset="docs/checks-light.svg">
|
|
596
|
+
<img src="docs/checks-dark.svg" alt="The five checks: 700+ lists, a real handshake, two sites with one IP, nothing injected, the details" width="100%">
|
|
597
|
+
</picture>
|
|
598
|
+
|
|
599
|
+
|
|
586
600
|
```mermaid
|
|
587
601
|
flowchart LR
|
|
588
602
|
A[sources.json<br/>meta lists<br/>GitHub discovery] --> B[Fetch & parse<br/>in parallel on all cores]
|
|
@@ -777,6 +791,14 @@ Username wishes – `country-us` sends everything out through US proxies, `sessi
|
|
|
777
791
|
proxy-scraper --recheck live --want 20 -y -o - | grep '^socks5://' > socks.txt
|
|
778
792
|
```
|
|
779
793
|
|
|
794
|
+
**Check a list you already have** – `--recheck -` reads it from stdin: plain `ip:port` lines, `type://ip:port`, logins, JSON, a CSV export or a table pasted from a website (HTML or Markdown), in the order it came in. Only what works from your network comes out:
|
|
795
|
+
|
|
796
|
+
```bash
|
|
797
|
+
curl -s https://example.com/proxies.txt | proxy-scraper --recheck - -o - > working.txt
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
Proxies without a type are tried as HTTP and as SOCKS5 – or as SOCKS4 with `--types socks4` alone. A password with a comma, quote, `|` or bracket can't be told apart from the text around it in a paste; put such proxies in a file, one per line, and use `--recheck file.txt`.
|
|
801
|
+
|
|
780
802
|
**Any tool, through the rotating server**
|
|
781
803
|
|
|
782
804
|
```bash
|
|
@@ -849,7 +871,7 @@ curl.exe -x (Get-Content "$run\all.txt" -TotalCount 1) http://api.ipify.org
|
|
|
849
871
|
| `--no-blocklisted` | skip proxies whose exit IP is on the SpamCop blocklist – those often get captchas |
|
|
850
872
|
| `--no-dnsbl` | skip the blocklist lookup |
|
|
851
873
|
| `--target URL` | only proxies that reach this site (repeatable) |
|
|
852
|
-
| `--recheck [FILE
|
|
874
|
+
| `--recheck [FILE\|-\|live]` | only check proxies from a file, stdin (`-`), the last run, or the public live list |
|
|
853
875
|
| `--fast` | skip the HTTPS test (confirmation and anonymity still run) |
|
|
854
876
|
| `--no-geo` | skip the country lookup |
|
|
855
877
|
| `-c`, `--concurrency N` | simultaneous checks (default: 2000) |
|
|
@@ -896,6 +918,25 @@ The repo does part of the work itself:
|
|
|
896
918
|
|
|
897
919
|
## FAQ
|
|
898
920
|
|
|
921
|
+
<a id="who-runs-free-proxies"></a>
|
|
922
|
+
|
|
923
|
+
<details open>
|
|
924
|
+
<summary><b>Who runs free proxies – and should you use them?</b></summary>
|
|
925
|
+
<br>
|
|
926
|
+
|
|
927
|
+
Almost nobody runs a free proxy for you. What ends up on public lists is usually one of these:
|
|
928
|
+
|
|
929
|
+
- **Misconfigured servers** – a Squid, a router or an app with a proxy port that was meant to stay internal.
|
|
930
|
+
- **Deliberately open proxies** – a few volunteers and research projects, and services that give some away to sell the rest.
|
|
931
|
+
- **Infected machines** – computers and IoT devices whose owners don't know they relay traffic. Many residential exits are like this.
|
|
932
|
+
- **Traps** – honeypots that log what goes through them, and proxies that rewrite pages to inject ads or scripts.
|
|
933
|
+
|
|
934
|
+
proxy-scraper can't tell an infected home router from an open office proxy, but it filters what it can measure: a proxy has to answer two independent requests with the same exit IP (honeypots that only answer scanners drop out), deliver a known page byte for byte (injectors drop out), and HTTPS counts only with a certificate that verifies end to end. Each hit says whether its exit is in a datacenter.
|
|
935
|
+
|
|
936
|
+
Good uses: public data, checking how a site looks from another country, testing your own blocking and rate limits, research. Never send passwords, cookies, payment or personal data through a free proxy, and keep HTTPS certificate checks on. Use them only where you're allowed to.
|
|
937
|
+
|
|
938
|
+
</details>
|
|
939
|
+
|
|
899
940
|
<details>
|
|
900
941
|
<summary><b>Almost nothing gets through.</b></summary>
|
|
901
942
|
<br>
|
|
@@ -950,6 +991,8 @@ Only for things that don't matter. Public proxies are run by strangers who can r
|
|
|
950
991
|
|
|
951
992
|
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.
|
|
952
993
|
|
|
994
|
+
Shipped in v1.24: `--recheck -` for lists you pipe in, which proxies get through to Discord, and a README you can try in five seconds.
|
|
995
|
+
|
|
953
996
|
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
997
|
|
|
955
998
|
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.
|
|
@@ -1020,6 +1063,14 @@ proxyscraper/
|
|
|
1020
1063
|
|
|
1021
1064
|
Questions, ideas and things you built with it go to [Discussions](https://github.com/maximilianfeix/proxy-scraper/discussions) – bugs to the [issues](../../issues). If proxy-scraper saves you time, a ⭐ helps others find it.
|
|
1022
1065
|
|
|
1066
|
+
Thanks to everyone who helped build it – new sources, countries, Python 3.14, examples and more:
|
|
1067
|
+
|
|
1068
|
+
<a href="https://github.com/maximilianfeix/proxy-scraper/graphs/contributors">
|
|
1069
|
+
<img src="https://contrib.rocks/image?repo=maximilianfeix/proxy-scraper" alt="Contributors to proxy-scraper">
|
|
1070
|
+
</a>
|
|
1071
|
+
|
|
1072
|
+
Want to join? [Beginner-friendly issues](../../issues?q=is%3Aopen+label%3A%22good+first+issue%22) say where to start.
|
|
1073
|
+
|
|
1023
1074
|
<a href="https://star-history.com/#maximilianfeix/proxy-scraper&Date">
|
|
1024
1075
|
<picture>
|
|
1025
1076
|
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=maximilianfeix/proxy-scraper&type=Date&theme=dark">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""proxy-scraper: collects public HTTP/SOCKS4/SOCKS5 proxies from hundreds of sources, checks them
|
|
2
2
|
in parallel with its own protocol handshakes and learns which sources deliver good proxies."""
|
|
3
3
|
|
|
4
|
-
__version__ = "1.
|
|
4
|
+
__version__ = "1.24.0"
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def __getattr__(name):
|
|
@@ -215,7 +215,7 @@ async def live_proxies_async(*, types: Iterable[str] = PROXY_TYPES, countries: I
|
|
|
215
215
|
Same filters as find_proxies, plus
|
|
216
216
|
min_uptime only proxies listed in at least this share (percent) of the week's runs, e.g. 90
|
|
217
217
|
works_on only proxies that got through to these sites in the last run: google, reddit, amazon, instagram,
|
|
218
|
-
tiktok
|
|
218
|
+
tiktok, discord
|
|
219
219
|
min_speed only proxies that downloaded at least this many KiB/s in the last run
|
|
220
220
|
limit at most this many (0 = all)
|
|
221
221
|
"""
|
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import contextlib
|
|
7
7
|
import ipaddress
|
|
8
|
+
import re
|
|
8
9
|
import socket
|
|
9
10
|
import sys
|
|
10
11
|
import tempfile
|
|
@@ -12,7 +13,7 @@ import time
|
|
|
12
13
|
from collections import Counter
|
|
13
14
|
from dataclasses import replace
|
|
14
15
|
from pathlib import Path
|
|
15
|
-
from typing import List, Optional, Tuple
|
|
16
|
+
from typing import Dict, List, Optional, Tuple
|
|
16
17
|
|
|
17
18
|
from rich.live import Live
|
|
18
19
|
from rich.text import Text
|
|
@@ -42,7 +43,17 @@ from .netio import INSECURE_HOSTS, http_get
|
|
|
42
43
|
from .options import STDOUT, RunOptions
|
|
43
44
|
from .output import ResultWriter, latest_results
|
|
44
45
|
from .pages import REPO_URL
|
|
45
|
-
from .parsing import
|
|
46
|
+
from .parsing import (
|
|
47
|
+
JSON_IP_PORT_RE,
|
|
48
|
+
JSON_PORT_IP_RE,
|
|
49
|
+
PROXY_RE,
|
|
50
|
+
PROXY_TYPES,
|
|
51
|
+
TYPE_ALIASES,
|
|
52
|
+
parse_blob,
|
|
53
|
+
parse_keys,
|
|
54
|
+
parse_proxy_line,
|
|
55
|
+
split_key,
|
|
56
|
+
)
|
|
46
57
|
from .paths import is_checkout
|
|
47
58
|
from .pipeline import (
|
|
48
59
|
CheckRun,
|
|
@@ -114,9 +125,90 @@ async def confirm_target() -> Optional[str]:
|
|
|
114
125
|
return ip if await probe_confirm_target(ip, timeout=8) else None
|
|
115
126
|
|
|
116
127
|
|
|
128
|
+
STDIN = "-" # --recheck -: the candidates come from a pipe
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def read_stdin() -> bytes:
|
|
132
|
+
"""What was piped in, as bytes – a stray non-UTF-8 byte in a pasted table mustn't sink the whole list.
|
|
133
|
+
A terminal on stdin means nothing was piped: reading it would just wait."""
|
|
134
|
+
if sys.stdin is None or sys.stdin.isatty():
|
|
135
|
+
raise OSError(0, "nothing was piped in (try: cat proxies.txt | proxy-scraper --recheck -)")
|
|
136
|
+
buffer = getattr(sys.stdin, "buffer", None)
|
|
137
|
+
data = buffer.read() if buffer is not None else sys.stdin.read().encode("utf-8", "replace")
|
|
138
|
+
return data[3:] if data.startswith(b"\xef\xbb\xbf") else data # the BOM Notepad and PowerShell write
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
# a typed proxy anywhere in a word – at its start, or after "url":" in compact JSON; it ends at a quote, comma or
|
|
142
|
+
# bracket, which a password could in theory contain but practically never does
|
|
143
|
+
_TYPED_PROXY = re.compile(
|
|
144
|
+
rb"(?<![A-Za-z0-9])(?:" + b"|".join(s.encode() for s in TYPE_ALIASES if TYPE_ALIASES[s] != "auto")
|
|
145
|
+
+ rb")://[^\s\"'`,;()\[\]{}<>]+", re.IGNORECASE)
|
|
146
|
+
# what separates an untyped proxy from the text around it: spaces, but also the quotes, commas, pipes and
|
|
147
|
+
# brackets of compact JSON, a CSV row or a Markdown table – otherwise '"proxy":"user:pass@ip:port' would read
|
|
148
|
+
# as a login of '"proxy":"user'
|
|
149
|
+
_WORD_SPLIT = re.compile(rb"[\s\"'`,;|()\[\]{}<>]+")
|
|
150
|
+
# what a proxy user name is made of; anything else in front of "@" ("proxy=user", "US|user") is text glued on,
|
|
151
|
+
# and the address is then checked without a login rather than with a made-up one
|
|
152
|
+
_LOGIN_USER = re.compile(r"[A-Za-z0-9._~+%-]+")
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
# IP and port in neighbouring columns of a CSV export or a Markdown table: "8.8.4.4,8080" / "| 8.8.4.4 | 8080 |"
|
|
156
|
+
_COLUMN_PAIR = re.compile(rb"(?<![\d.])(\d{1,3}(?:\.\d{1,3}){3})\s*[,;|]\s*(\d{2,5})(?![\d.])")
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def _address_positions(data: bytes) -> Dict[str, int]:
|
|
160
|
+
"""Where each ip:port first appears, in any layout the extraction reads: ip:port, "ip port", a table cell
|
|
161
|
+
pair, JSON in either order – so a list keeps its order whatever it looks like."""
|
|
162
|
+
hits = [(m.start(), m.group(1), m.group(2))
|
|
163
|
+
for regex in (PROXY_RE, JSON_IP_PORT_RE, _COLUMN_PAIR) for m in regex.finditer(data)]
|
|
164
|
+
hits += [(m.start(), m.group(2), m.group(1)) for m in JSON_PORT_IP_RE.finditer(data)]
|
|
165
|
+
first: Dict[str, int] = {}
|
|
166
|
+
for at, ip, port in sorted(hits):
|
|
167
|
+
first.setdefault(f"{'.'.join(str(int(p)) for p in ip.split(b'.'))}:{int(port)}", at)
|
|
168
|
+
return first
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def stdin_keys(data: bytes, types) -> List[str]:
|
|
172
|
+
"""Every proxy in the piped text, in the order it came in (lists often come best first, and --limit takes
|
|
173
|
+
the first jobs).
|
|
174
|
+
|
|
175
|
+
Every type://… in the text is read as a proxy on its own – at the start of a line, after other text,
|
|
176
|
+
several on a line, inside JSON – which also keeps a login whose password has '@' or '/'. Untyped proxies –
|
|
177
|
+
a bare word like user:pass@ip:port (read whole, so the login stays), or ip/port inside JSON or a table –
|
|
178
|
+
are tried as HTTP and right after as SOCKS5, or as the types asked for when neither of those is (a list of
|
|
179
|
+
SOCKS4 proxies piped in with --types socks4). Not the "auto" mode of sources: its "plain lines only count
|
|
180
|
+
as the majority" rule is for scraped lists, and whoever pipes a list in means all of it."""
|
|
181
|
+
wanted = tuple(types)
|
|
182
|
+
bare_types = tuple(t for t in ("http", "socks5") if t in wanted) or wanted
|
|
183
|
+
|
|
184
|
+
def address(key: str) -> str:
|
|
185
|
+
return split_key(key)[1].rpartition("@")[2]
|
|
186
|
+
|
|
187
|
+
typed = {k for k in (parse_proxy_line(m.group(0).decode("utf-8", "replace"), None)
|
|
188
|
+
for m in _TYPED_PROXY.finditer(data)) if k}
|
|
189
|
+
words = [w.decode("utf-8", "replace") for w in _WORD_SPLIT.split(data) if w and b"://" not in w]
|
|
190
|
+
words = [w for w in words if "@" not in w or _LOGIN_USER.fullmatch(w.rpartition("@")[0].partition(":")[0])]
|
|
191
|
+
whole_words = {k for w in words for t in bare_types for k in [parse_proxy_line(w, t)] if k}
|
|
192
|
+
# full: sources pick the "ip port"/table regex from their first 8 KB, a paste may be a.txt then b.html
|
|
193
|
+
found = {k for t in bare_types for k in parse_blob(data, t, wanted, full=True).split("\n") if k}
|
|
194
|
+
columns = [f"{m.group(1).decode()}:{m.group(2).decode()}" for m in _COLUMN_PAIR.finditer(data)]
|
|
195
|
+
found |= {k for pair in columns for t in bare_types for k in [parse_proxy_line(pair, t)] if k}
|
|
196
|
+
# an address read with its login (or with a type of its own) owns it: the regex's login-less copy, or a
|
|
197
|
+
# bare copy of a typed proxy of an unwanted type, mustn't come back. Claimed before the type filter.
|
|
198
|
+
claimed = {address(k) for k in typed} | {address(k) for k in whole_words if "@" in split_key(k)[1]}
|
|
199
|
+
keys = ({k for k in typed | whole_words if split_key(k)[0] in wanted}
|
|
200
|
+
| {k for k in found if address(k) not in claimed})
|
|
201
|
+
|
|
202
|
+
first = _address_positions(data)
|
|
203
|
+
rank = {t: i for i, t in enumerate(PROXY_TYPES)} # http before socks4 before socks5 for the same address
|
|
204
|
+
return sorted(keys, key=lambda k: (first.get(address(k), len(data)), rank.get(split_key(k)[0], 9), k))
|
|
205
|
+
|
|
206
|
+
|
|
117
207
|
def load_recheck_jobs(target: str, types, history: ProxyHistory) -> List[str]:
|
|
118
|
-
"""--recheck: a file, otherwise the last run plus history."""
|
|
119
|
-
if target:
|
|
208
|
+
"""--recheck: a file, '-' for stdin, otherwise the last run plus history."""
|
|
209
|
+
if target == STDIN:
|
|
210
|
+
return stdin_keys(read_stdin(), types)
|
|
211
|
+
elif target:
|
|
120
212
|
lines = Path(target).expanduser().read_text(encoding="utf-8").splitlines()
|
|
121
213
|
# lines without type:// in files like http.txt take the type from the file name
|
|
122
214
|
default = next((t for t in PROXY_TYPES if t in Path(target).name.lower()), None)
|
|
@@ -311,9 +403,10 @@ class Run:
|
|
|
311
403
|
jobs = load_recheck_jobs(opts.recheck, opts.types, self.history)
|
|
312
404
|
except (OSError, UnicodeDecodeError) as e:
|
|
313
405
|
reason = e.strerror if isinstance(e, OSError) and e.strerror else "not a text file"
|
|
314
|
-
note(f"Can't read {opts.recheck}: {reason}.", BAD, "✘")
|
|
406
|
+
note(f"Can't read {'stdin' if opts.recheck == STDIN else opts.recheck}: {reason}.", BAD, "✘")
|
|
315
407
|
return []
|
|
316
|
-
|
|
408
|
+
where = "stdin" if opts.recheck == STDIN else opts.recheck or "the last run + history"
|
|
409
|
+
info("Recheck", f"{fmt(len(jobs))} proxies from {where}")
|
|
317
410
|
else:
|
|
318
411
|
jobs = await self._scrape_jobs()
|
|
319
412
|
|
|
@@ -183,7 +183,7 @@ def parse_args(argv: Optional[List[str]] = None) -> argparse.Namespace:
|
|
|
183
183
|
g.add_argument("--no-dnsbl", action="store_true",
|
|
184
184
|
help="don't look up whether exit IPs are on the SpamCop blocklist")
|
|
185
185
|
g.add_argument("--recheck", nargs="?", const="", metavar="FILE",
|
|
186
|
-
help="only check proxies from FILE – without FILE: last run + history; "
|
|
186
|
+
help="only check proxies from FILE ('-' reads them from stdin) – without FILE: last run + history; "
|
|
187
187
|
"'live': the live list from GitHub (seconds instead of minutes, e.g. with --serve)")
|
|
188
188
|
|
|
189
189
|
f = p.add_argument_group("Filters (for the result files)")
|