proxy-scraper-cli 1.28.0__tar.gz → 1.30.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 (149) hide show
  1. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/PKG-INFO +107 -80
  2. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/README.md +104 -77
  3. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxy_scraper_cli.egg-info/PKG-INFO +107 -80
  4. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxy_scraper_cli.egg-info/SOURCES.txt +5 -0
  5. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxy_scraper_cli.egg-info/requires.txt +1 -1
  6. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/__init__.py +1 -1
  7. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/agent.py +43 -6
  8. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/api.py +27 -6
  9. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/app.py +67 -9
  10. proxy_scraper_cli-1.30.0/proxyscraper/checker.py +799 -0
  11. proxy_scraper_cli-1.30.0/proxyscraper/checkstate.py +153 -0
  12. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/cli.py +177 -18
  13. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/mcp_server.py +17 -6
  14. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/mirror.py +16 -13
  15. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/options.py +3 -0
  16. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/output.py +19 -1
  17. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/pages.py +8 -8
  18. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/pipeline.py +34 -4
  19. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/publish.py +57 -8
  20. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/report.py +30 -25
  21. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/site/index.html +53 -54
  22. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/sourcepages.py +7 -7
  23. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/ui/dashboard.py +7 -5
  24. proxy_scraper_cli-1.30.0/proxyscraper/verify.py +353 -0
  25. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/pyproject.toml +2 -2
  26. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_agent.py +1 -1
  27. proxy_scraper_cli-1.30.0/tests/test_check_states.py +519 -0
  28. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_checker.py +4 -2
  29. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_discovery_growth.py +1 -1
  30. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_publish.py +58 -0
  31. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_report.py +2 -2
  32. proxy_scraper_cli-1.30.0/tests/test_serve_open.py +72 -0
  33. proxy_scraper_cli-1.30.0/tests/test_verify.py +415 -0
  34. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_workflow_pip.py +5 -2
  35. proxy_scraper_cli-1.28.0/proxyscraper/checker.py +0 -520
  36. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/LICENSE +0 -0
  37. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxy_scraper_cli.egg-info/dependency_links.txt +0 -0
  38. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxy_scraper_cli.egg-info/entry_points.txt +0 -0
  39. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxy_scraper_cli.egg-info/top_level.txt +0 -0
  40. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/__main__.py +0 -0
  41. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/action.py +0 -0
  42. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/asndb.py +0 -0
  43. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/blocklist.py +0 -0
  44. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/charts.py +0 -0
  45. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/compat.py +0 -0
  46. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/completion.py +0 -0
  47. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/exporters.py +0 -0
  48. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/fetchcache.py +0 -0
  49. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/geo.py +0 -0
  50. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/geodb.py +0 -0
  51. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/handshake.py +0 -0
  52. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/history.py +0 -0
  53. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/judges.py +0 -0
  54. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/mcp_entry.py +0 -0
  55. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/netio.py +0 -0
  56. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/parsing.py +0 -0
  57. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/paths.py +0 -0
  58. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/preferences.py +0 -0
  59. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/proxypages.py +0 -0
  60. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/ranking.py +0 -0
  61. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/runsteps.py +0 -0
  62. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/server/__init__.py +0 -0
  63. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/server/api.py +0 -0
  64. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/server/core.py +0 -0
  65. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/server/dashboard.html +0 -0
  66. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/server/http.py +0 -0
  67. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/server/pool.py +0 -0
  68. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/server/socks.py +0 -0
  69. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/server/status.py +0 -0
  70. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/server/upstream.py +0 -0
  71. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/site/apple-touch-icon.png +0 -0
  72. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/site/googleaac1161b7853c5b5.html +0 -0
  73. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/site/logo.png +0 -0
  74. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/site/og.png +0 -0
  75. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/sites.py +0 -0
  76. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/sources.json +0 -0
  77. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/sources.py +0 -0
  78. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/speed.py +0 -0
  79. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/targets.py +0 -0
  80. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/ui/__init__.py +0 -0
  81. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/ui/keys.py +0 -0
  82. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/ui/report.py +0 -0
  83. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/ui/serve.py +0 -0
  84. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/ui/widgets.py +0 -0
  85. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/proxyscraper/ui/wizard.py +0 -0
  86. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/setup.cfg +0 -0
  87. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_action.py +0 -0
  88. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_api.py +0 -0
  89. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_app.py +0 -0
  90. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_asndb.py +0 -0
  91. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_auth.py +0 -0
  92. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_bad_hosts_and_host_header.py +0 -0
  93. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_blocklist.py +0 -0
  94. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_charts.py +0 -0
  95. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_citation.py +0 -0
  96. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_colon_logins.py +0 -0
  97. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_compat.py +0 -0
  98. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_completion.py +0 -0
  99. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_exporters.py +0 -0
  100. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_fetchcache.py +0 -0
  101. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_geodb.py +0 -0
  102. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_hf_card.py +0 -0
  103. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_hf_parquet.py +0 -0
  104. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_judges.py +0 -0
  105. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_learning.py +0 -0
  106. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_live_api.py +0 -0
  107. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_mcp_server.py +0 -0
  108. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_mine_sources.py +0 -0
  109. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_mirror.py +0 -0
  110. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_options.py +0 -0
  111. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_output_stdout.py +0 -0
  112. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_own_sources.py +0 -0
  113. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_pac.py +0 -0
  114. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_packaging.py +0 -0
  115. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_pages.py +0 -0
  116. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_parsing.py +0 -0
  117. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_parsing_fuzz.py +0 -0
  118. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_paths.py +0 -0
  119. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_pick.py +0 -0
  120. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_pipeline.py +0 -0
  121. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_preferences.py +0 -0
  122. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_proxy_pages.py +0 -0
  123. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_proxy_sources.py +0 -0
  124. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_pypi_readme.py +0 -0
  125. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_readme_translations.py +0 -0
  126. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_recheck_stdin.py +0 -0
  127. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_robustness.py +0 -0
  128. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_rotator.py +0 -0
  129. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_serve_api.py +0 -0
  130. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_serve_dashboard.py +0 -0
  131. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_serve_password.py +0 -0
  132. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_serve_refill.py +0 -0
  133. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_serve_v2.py +0 -0
  134. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_server.py +0 -0
  135. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_server_closed_writer.py +0 -0
  136. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_server_fixes.py +0 -0
  137. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_sites.py +0 -0
  138. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_source_pages.py +0 -0
  139. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_sources_json.py +0 -0
  140. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_speed.py +0 -0
  141. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_speed_ranking.py +0 -0
  142. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_survival_ranking.py +0 -0
  143. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_tamper.py +0 -0
  144. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_targets.py +0 -0
  145. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_ui.py +0 -0
  146. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_uptime.py +0 -0
  147. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_wizard.py +0 -0
  148. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_workflow_permissions.py +0 -0
  149. {proxy_scraper_cli-1.28.0 → proxy_scraper_cli-1.30.0}/tests/test_workflow_pins.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: proxy-scraper-cli
3
- Version: 1.28.0
4
- Summary: Finds free HTTP, SOCKS4 and SOCKS5 proxies that actually work: 700+ sources, real checks, honeypot filtering and a rotating local proxy server.
3
+ Version: 1.30.0
4
+ Summary: Finds and checks free HTTP, SOCKS4 and SOCKS5 proxies and shows what each check found: passed, failed or not run, and when. With a rotating local proxy server.
5
5
  Author: Maximilian Feix
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/maximilianfeix/proxy-scraper
@@ -39,15 +39,15 @@ Requires-Dist: pytest; extra == "dev"
39
39
  Requires-Dist: hypothesis; extra == "dev"
40
40
  Requires-Dist: pyyaml; extra == "dev"
41
41
  Requires-Dist: markdown-it-py; extra == "dev"
42
- Requires-Dist: ruff==0.16.10; extra == "dev"
42
+ Requires-Dist: ruff==0.17.0; extra == "dev"
43
43
  Dynamic: license-file
44
44
 
45
45
  <div align="center">
46
46
 
47
47
  <picture>
48
- <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.28.0/docs/banner-dark.svg">
49
- <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.28.0/docs/banner-light.svg">
50
- <img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.28.0/docs/banner-dark.svg" alt="proxy-scraper – free proxies that actually work" width="100%">
48
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.30.0/docs/banner-dark.svg">
49
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.30.0/docs/banner-light.svg">
50
+ <img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.30.0/docs/banner-dark.svg" alt="proxy-scraper – free proxies that actually work" width="100%">
51
51
  </picture>
52
52
 
53
53
  [![tests](https://github.com/maximilianfeix/proxy-scraper/actions/workflows/tests.yml/badge.svg)](https://github.com/maximilianfeix/proxy-scraper/actions/workflows/tests.yml)
@@ -55,18 +55,18 @@ Dynamic: license-file
55
55
  [![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)
56
56
  [![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/)
57
57
  [![Downloads](https://img.shields.io/pepy/dt/proxy-scraper-cli?style=flat-square&color=D4F77A&labelColor=121113&label=downloads)](https://pepy.tech/projects/proxy-scraper-cli)
58
- [![Python](https://img.shields.io/badge/python-3.9–3.14-D4F77A?style=flat-square&labelColor=121113)](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/pyproject.toml)
58
+ [![Python](https://img.shields.io/badge/python-3.9–3.14-D4F77A?style=flat-square&labelColor=121113)](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/pyproject.toml)
59
59
  [![Stars](https://img.shields.io/github/stars/maximilianfeix/proxy-scraper?style=flat-square&color=D4F77A&labelColor=121113)](https://github.com/maximilianfeix/proxy-scraper/stargazers)
60
- [![License](https://img.shields.io/badge/license-MIT-D4F77A?style=flat-square&labelColor=121113)](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/LICENSE)
60
+ [![License](https://img.shields.io/badge/license-MIT-D4F77A?style=flat-square&labelColor=121113)](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/LICENSE)
61
61
 
62
62
  <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>
63
63
  <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>
64
64
  <a href="#install"><img src="https://img.shields.io/badge/Install-121113?style=for-the-badge" alt="Install"></a>
65
65
  <a href="#from-python"><img src="https://img.shields.io/badge/Python_API-121113?style=for-the-badge" alt="Python API"></a>
66
66
  <a href="#mcp"><img src="https://img.shields.io/badge/MCP_server-121113?style=for-the-badge" alt="MCP server for AI agents"></a>
67
- <a href="https://github.com/maximilianfeix/proxy-scraper/tree/v1.28.0/bot/"><img src="https://img.shields.io/badge/Discord_bot-121113?style=for-the-badge" alt="Discord bot"></a>
67
+ <a href="https://github.com/maximilianfeix/proxy-scraper/tree/v1.30.0/bot/"><img src="https://img.shields.io/badge/Discord_bot-121113?style=for-the-badge" alt="Discord bot"></a>
68
68
 
69
- **English** · [简体中文](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/README.zh-CN.md) · [Español](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/README.es.md) · [Deutsch](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/README.de.md) · [Русский](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/README.ru.md) · [Português (Brasil)](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/README.pt-BR.md) · [Français](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/README.fr.md)
69
+ **English** · [简体中文](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/README.zh-CN.md) · [Español](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/README.es.md) · [Deutsch](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/README.de.md) · [Русский](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/README.ru.md) · [Português (Brasil)](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/README.pt-BR.md) · [Français](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/README.fr.md)
70
70
 
71
71
  [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)
72
72
 
@@ -74,30 +74,46 @@ Dynamic: license-file
74
74
 
75
75
  ---
76
76
 
77
- 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.
77
+ **Proxy checks you can inspect: what passed, what failed, and when.** proxy-scraper collects public HTTP, SOCKS4 and SOCKS5 proxies from hundreds of lists, runs up to four checks on each one and keeps the outcome of each check for the proxies it lists (for the rest it counts how each check ended), so "working" is something you can look at instead of a label you have to trust.
78
78
 
79
- **In numbers:** in one day it ran 3.6 million checks on free proxies – 1.1 % passed, and more than half of the ones that answered failed a second request. [What's actually out there →](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/docs/free-proxies-in-numbers.md)
79
+ https://github.com/user-attachments/assets/b99c1d8f-5bce-4a52-a8a9-b9c2c726301b
80
80
 
81
- **Used by:** the hourly list is a built-in source of [monosans/proxy-scraper-checker](https://github.com/monosans/proxy-scraper-checker) and [gfpcom/free-proxy-list](https://github.com/gfpcom/free-proxy-list).
81
+ <sub>21 seconds · real interface, example numbers, documentation IPs · <a href="https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/video/proxy-scraper.mp4">mp4</a></sub>
82
82
 
83
- **Try it – no install, about five seconds:**
83
+ **Try it** – no install needed, `uvx` comes with [uv](https://docs.astral.sh/uv/) (`pipx run` does the same):
84
84
 
85
85
  ```bash
86
- uvx proxy-scraper-cli --pick 5 --types socks5 # 5 checked proxies
87
-
88
- # or just the plain list
89
- curl -s https://maximilianfeix.github.io/proxy-scraper/socks5.txt | head
86
+ uvx proxy-scraper-cli --pick 3 --verify # up to 3 proxies from the hourly list that pass right now, from your network
87
+ uvx proxy-scraper-cli --diagnose socks5://HOST:PORT # one proxy, check by check: what it did and what it didn't
90
88
  ```
91
89
 
92
- `uvx` comes with [uv](https://docs.astral.sh/uv/); `pipx run proxy-scraper-cli --pick 5` does the same.
93
-
94
- **Only want proxies?** The lists, rebuilt every hour, best first: [all.txt](https://maximilianfeix.github.io/proxy-scraper/all.txt) · [http.txt](https://maximilianfeix.github.io/proxy-scraper/http.txt) · [socks4.txt](https://maximilianfeix.github.io/proxy-scraper/socks4.txt) · [socks5.txt](https://maximilianfeix.github.io/proxy-scraper/socks5.txt) · [proxies.json](https://maximilianfeix.github.io/proxy-scraper/proxies.json) · [by country](https://maximilianfeix.github.io/proxy-scraper/) · [more formats](#live-list)
95
-
96
90
  <div align="center">
97
- <img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.28.0/docs/demo.svg" alt="Animated demo: the live dashboard during a check, the report, the setup wizard and collecting" width="880">
91
+ <img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.30.0/docs/demo/checks.gif" alt="Terminal recording: proxy-scraper --pick 2 --verify --https-only prints two proxies and says on stderr why the other four were left out; proxy-scraper --diagnose shows each check of one proxy with its result" width="880">
98
92
  </div>
99
93
 
100
- > **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
+ <sub>A real terminal recording, made against six simulated proxies on localhost ([reproduce it](https://github.com/maximilianfeix/proxy-scraper/tree/v1.30.0/docs/demo/)). It shows how results are reported. It measures nothing about public proxies.</sub>
95
+
96
+ The package is `proxy-scraper-cli` on PyPI (the plain name is taken). Once [installed](#install), the command is `proxy-scraper`. `--verify` and `--diagnose` need version 1.30 or newer.
97
+
98
+ **Three ways to get proxies, and what "checked" means for each:**
99
+
100
+ | Command | Where the proxies come from | Checked | Takes |
101
+ |---|---|---|---|
102
+ | `proxy-scraper --pick 5` | the [published list](#live-list) | from GitHub's servers when the list was built, about every hour | under a second |
103
+ | `proxy-scraper --pick 5 --verify` | the published list | **now, from your network** | seconds to a minute and a half at most |
104
+ | `proxy-scraper -y` | every list the tool knows | now, from your network | minutes (about three in the hourly runs) |
105
+
106
+ **What you get**
107
+
108
+ - **Every check has an outcome you can read.** `passed`, `failed`, `unavailable` or `skipped`, with a reason code, the target and the time, in the terminal, in JSON and from Python. A check that didn't run is never shown as passed, and a check target that is down doesn't turn the proxies checked against it into failures. → [Check states](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/check-states.md)
109
+ - **Fresh when it matters.** `--pick --verify` checks a few proxies from your own network, usually in seconds. `--recheck` does the same for [a list of your own](#examples), and `--diagnose` tells you why one proxy doesn't work.
110
+ - **More than a list.** A [rotating local proxy server](#proxy-server), a [Python API](#from-python), an [MCP server](#mcp) for AI agents, Docker, and exports for curl, proxychains, Clash and sing-box.
111
+
112
+ **What it can't do.** Free proxies are run by strangers, and of one hour's list only about a quarter is on the list again a day later. A pass is one measurement, from one network, against test targets: it is not a promise for the next hour or for the site you care about. The HTTPS check is a verified TLS connection to one test host, not a security rating. Use free proxies for public data and testing, never for logins, payments or anything personal. → [What the numbers show and what they don't](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/free-proxies-in-numbers.md) · [How it compares](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/comparison.md) · [Who runs free proxies](#who-runs-free-proxies)
113
+
114
+ **Only want the lists?** You don't need this tool: [free-proxy-list](https://github.com/maximilianfeix/free-proxy-list) has them as plain files per protocol and country, rebuilt about every hour. Or straight from here: [all.txt](https://maximilianfeix.github.io/proxy-scraper/all.txt) · [http.txt](https://maximilianfeix.github.io/proxy-scraper/http.txt) · [socks4.txt](https://maximilianfeix.github.io/proxy-scraper/socks4.txt) · [socks5.txt](https://maximilianfeix.github.io/proxy-scraper/socks5.txt) · [proxies.json](https://maximilianfeix.github.io/proxy-scraper/proxies.json) · [more formats](#live-list)
115
+
116
+ **Used by:** the hourly list is a built-in source of [monosans/proxy-scraper-checker](https://github.com/monosans/proxy-scraper-checker) and [gfpcom/free-proxy-list](https://github.com/gfpcom/free-proxy-list).
101
117
 
102
118
  <details>
103
119
  <summary><b>Table of contents</b></summary>
@@ -166,7 +182,7 @@ pip install -r requirements.txt
166
182
  python3 proxy_scraper.py
167
183
  ```
168
184
 
169
- Every [release](https://github.com/maximilianfeix/proxy-scraper/releases/latest) also ships a wheel you can install with `pip install <file>.whl`, and a multi-arch image (amd64/arm64) on `ghcr.io`. In the container the wizard never shows up, it runs straight away. For the proxy server use `--serve --serve-host 0.0.0.0` with `-p 127.0.0.1:8899:8899`, so the port is only open on your own machine.
185
+ Every [release](https://github.com/maximilianfeix/proxy-scraper/releases/latest) also ships a wheel you can install with `pip install <file>.whl`, and a multi-arch image (amd64/arm64) on `ghcr.io`. In the container the wizard never shows up, it runs straight away. For the proxy server use `--serve --serve-host 0.0.0.0 --serve-open` with `-p 127.0.0.1:8899:8899`, so the port is only open on your own machine – or set `-e PROXY_SCRAPER_SERVE_PASSWORD=…` instead of `--serve-open`.
170
186
 
171
187
  Tab completion for bash, zsh, fish and PowerShell:
172
188
 
@@ -183,7 +199,8 @@ Installed, the learned state lives in your user data folder (`~/Library/Applicat
183
199
  Started without arguments, a wizard asks what you are looking for:
184
200
 
185
201
  <div align="center">
186
- <img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.28.0/docs/wizard.svg" alt="Setup wizard" width="760">
202
+ <img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.30.0/docs/wizard.svg" alt="Setup wizard" width="760">
203
+ <sub>Illustration: the real interface, rendered with sample data by <a href="https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/make_demo.py">docs/make_demo.py</a>. The numbers in it are made up.</sub>
187
204
  </div>
188
205
 
189
206
  | Preset | What it does |
@@ -204,7 +221,7 @@ Keys: <kbd>↑</kbd><kbd>↓</kbd> select · <kbd>Space</kbd> toggle · <kbd>1</
204
221
 
205
222
  ## Live proxy list
206
223
 
207
- Don't want to scan yourself? Every hour **GitHub Actions** runs the tool and publishes the hits to the [`proxy-list`](https://github.com/maximilianfeix/proxy-scraper/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.
224
+ Don't want to scan yourself? About every hour **GitHub Actions** runs the tool and publishes the hits to the [`proxy-list`](https://github.com/maximilianfeix/proxy-scraper/tree/proxy-list) branch – every entry passed the first request, the second request and the content check in the last run (the HTTPS test is recorded per entry, not required), best first: fast ones that are likely to still be up come on top.
208
225
 
209
226
  > **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. Other tools pull it too: [monosans/proxy-scraper-checker](https://github.com/monosans/proxy-scraper-checker) and [gfpcom/free-proxy-list](https://github.com/gfpcom/free-proxy-list) use it as a built-in source.
210
227
 
@@ -214,11 +231,11 @@ Don't want to scan yourself? Every hour **GitHub Actions** runs the tool and pub
214
231
  <img src="https://maximilianfeix.github.io/proxy-scraper/chart-dark.svg" alt="Working proxies over the last days, stacked by protocol – redrawn with every run" width="100%">
215
232
  </picture></a>
216
233
 
217
- **→ [Browse it on the website](https://maximilianfeix.github.io/proxy-scraper/)** – search, filter by type, country, HTTPS, provider and latency, see how long each proxy has been up and how often it was on the list this week, copy or download exactly the proxies you need.
234
+ **→ [Browse it on the website](https://maximilianfeix.github.io/proxy-scraper/)** – search, filter by type, country, HTTPS, provider and latency, see how long each proxy has been on the list and in how many of the week's runs, copy or download exactly the proxies you need.
218
235
 
219
236
  Every protocol and country also has its own page with a plain download, e.g. [SOCKS5](https://maximilianfeix.github.io/proxy-scraper/socks5/) or [Germany](https://maximilianfeix.github.io/proxy-scraper/country/de/) (`country/de/proxies.txt`).
220
237
 
221
- <div align="center"><a href="https://maximilianfeix.github.io/proxy-scraper/"><img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.28.0/docs/website.png" alt="The live list website" width="860"></a></div>
238
+ <div align="center"><a href="https://maximilianfeix.github.io/proxy-scraper/"><img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.30.0/docs/website.png" alt="The live list website" width="860"></a></div>
222
239
 
223
240
  <div align="center">
224
241
 
@@ -236,7 +253,7 @@ Every protocol and country also has its own page with a plain download, e.g. [SO
236
253
  | 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) |
237
254
  | HTTPS-capable only | `type://ip:port` | [https.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/https.txt) |
238
255
  | Elite only | `type://ip:port` | [elite.txt](https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/elite.txt) |
239
- | 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) |
256
+ | Gets through to Google · Reddit · Amazon · Instagram · TikTok · Discord (one test request got a normal page 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) |
240
257
  | 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) |
241
258
  | 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) |
242
259
 
@@ -250,13 +267,13 @@ Every protocol and country also has its own page with a plain download, e.g. [SO
250
267
  curl -s https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/proxy-list/socks5.txt | head
251
268
  ```
252
269
 
253
- **Where they come from:** [which free proxy lists actually work](https://maximilianfeix.github.io/proxy-scraper/sources/) ranks all 700+ sources every hour – how many proxies each one lists, how many passed every check and the share. The same as data: [sources.json](https://maximilianfeix.github.io/proxy-scraper/sources.json).
270
+ **Where they come from:** [which free proxy lists actually work](https://maximilianfeix.github.io/proxy-scraper/sources/) ranks every source of the hourly runs – how many proxies each one lists, how many passed every check and the share. The same as data: [sources.json](https://maximilianfeix.github.io/proxy-scraper/sources.json).
254
271
 
255
272
  **Over time:** every day the first run's `proxies.json` is kept for good as a gzipped asset of the release of that year, like [snapshots-2026](https://github.com/maximilianfeix/proxy-scraper/releases/tag/snapshots-2026) – `proxies-2026-09-28.json.gz` and so on, for anyone who wants to look at free proxies over weeks and months.
256
273
 
257
274
  Every file is also on GitHub Pages, which sits behind a CDN, isn't rate limited like raw.githubusercontent and sends CORS headers, so it works straight from the browser: `https://maximilianfeix.github.io/proxy-scraper/socks5.txt`. [jsDelivr](https://cdn.jsdelivr.net/gh/maximilianfeix/proxy-scraper@proxy-list/) works too, but can lag behind by a few hours.
258
275
 
259
- Or let the tool start from it: `proxy-scraper --recheck live` downloads the list and checks it again from **your** network – about 30 seconds instead of a full scan (517 of 1,169 worked from here). With `--serve` you have a rotating proxy in under a minute.
276
+ Or let the tool start from it: `proxy-scraper --recheck live` downloads the list and checks it again from **your** network – well under a minute instead of a full scan. How many still work from your network differs a lot from the list's own count, which is the point of checking again. Add `--serve` and the result is a rotating proxy.
260
277
 
261
278
  <a id="mcp"></a>
262
279
 
@@ -270,9 +287,9 @@ Or let the tool start from it: `proxy-scraper --recheck live` downloads the list
270
287
 
271
288
  | Tool | What it does |
272
289
  |---|---|
273
- | `get_proxies` | working proxies right now, from the hourly list – filter by protocol, country, HTTPS, elite, no datacenter, not blocklisted, stable, uptime, latency, gets through to Google/Reddit/Amazon |
290
+ | `get_proxies` | proxies from the hourly list, as checked in its last run – filter by protocol, country, HTTPS, elite, no datacenter, not blocklisted, stable, uptime, latency, gets through to Google/Reddit/Amazon |
274
291
  | `check_proxies` | checks proxies from your own network, so they work from where your code runs (30–90 s, reports progress) |
275
- | `fetch_url` | loads a page through a verified proxy, switches proxies by itself when one fails, returns readable text – HTTPS only through proxies with verified TLS |
292
+ | `fetch_url` | loads a page through a proxy from the checked list, switches proxies by itself when one fails, returns readable text – HTTPS only through proxies that passed the TLS test |
276
293
 
277
294
  Things to ask your agent: *"Load bbc.com/news as seen from the UK"*, *"Give me 5 SOCKS5 proxies from Germany that aren't in a datacenter"*, *"Check which of these sites block free proxies"*.
278
295
 
@@ -356,7 +373,7 @@ Started without arguments, the tool asks what you need using the arrow keys –
356
373
  <td width="50%" valign="top">
357
374
 
358
375
  **Fast**<br>
359
- 700+ sources fetched in parallel, large lists parsed on all CPU cores, hand-written HTTP/SOCKS handshakes directly on `asyncio` with 2000+ checks at once.
376
+ 350+ curated lists, plus the ones found through meta lists and GitHub search (about 750 to 820 in the hourly runs), fetched in parallel. Large lists are parsed on all CPU cores, and hand-written HTTP/SOCKS handshakes run directly on `asyncio`, 2,000 checks at once.
360
377
 
361
378
  </td>
362
379
  </tr>
@@ -364,7 +381,7 @@ Started without arguments, the tool asks what you need using the arrow keys –
364
381
  <td valign="top">
365
382
 
366
383
  **Real verification**<br>
367
- 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](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/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.
384
+ Every hit has to answer **a second request** to an unrelated site with the same exit IP: over 3.6 million checks, 54 % of the proxies that answered the first request did not pass the second. A third request fetches **a static test page that has to arrive byte for byte**: for 5.2 % of the proxies that got that far it didn't. Why a proxy fails either one (unstable, a rotating exit, a changed or cut-off page) is not something those runs recorded; from 1.30 on every result carries a reason code ([the numbers](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/free-proxies-in-numbers.md), [check states](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/check-states.md)). Plus: HTTPS through a tunnel with **a TLS certificate that verifies** for the test host, anonymity level *elite / anonymous / transparent* and the country of the exit IP.
368
385
 
369
386
  </td>
370
387
  <td valign="top">
@@ -384,7 +401,7 @@ Searches GitHub for actively maintained proxy lists and reads source lists maint
384
401
  <td valign="top">
385
402
 
386
403
  **Filters & target sites**<br>
387
- With `--target google.com` a proxy only counts if it really reaches the site – many public proxies are blocked by Google, Discord & co. Filter by country, HTTPS, anonymity and latency, and stop with `--want 50` as soon as enough matching proxies are found. Filters even speed things up: with `--max-latency 1000` slow proxies are given up after 1 s instead of 8 s.
404
+ With `--target google.com` a proxy only counts if it really reaches the site – many public proxies are turned away by the big sites. Filter by country, HTTPS, anonymity and latency, and stop with `--want 50` as soon as enough matching proxies are found. Filters even speed things up: with `--max-latency 1000` slow proxies are given up after 1 s instead of 8 s.
388
405
 
389
406
  </td>
390
407
  </tr>
@@ -412,7 +429,7 @@ macOS, Linux and Windows, Python 3.9 to 3.14. Only two dependencies: `rich` and
412
429
  <td valign="top">
413
430
 
414
431
  **Thoroughly tested**<br>
415
- 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.
432
+ 1,100+ tests run offline against real mini proxies with known flaws on `localhost` – on Linux, macOS and Windows with Python 3.9, 3.11, 3.13 and 3.14.
416
433
 
417
434
  </td>
418
435
  </tr>
@@ -422,20 +439,23 @@ macOS, Linux and Windows, Python 3.9 to 3.14. Only two dependencies: `rich` and
422
439
 
423
440
  ### Why not just download a list?
424
441
 
425
- | | Typical proxy list repo | **proxy-scraper** |
426
- |---|:---:|:---:|
427
- | Proxies checked right before you use them | ❌ | ✅ |
428
- | Honeypots that fake a successful check filtered out | ❌ | ✅ |
429
- | Proxies that inject scripts or ads filtered out | ❌ | ✅ |
430
- | HTTPS tested with verified TLS | rarely | ✅ |
431
- | Anonymity level and country per proxy | sometimes | ✅ |
432
- | Only proxies that reach *your* target site | ❌ | ✅ `--target` |
433
- | Learns which sources are worth it | ❌ | ✅ |
434
- | Usable as a single rotating proxy | ❌ | ✅ `--serve` |
435
- | API to fetch a proxy (proxy_pool compatible) | ❌ | ✅ [`/get`](#pool-api) |
436
- | Ready-made list without running anything | ✅ | ✅ [live list](#live-list) |
437
-
438
- Named and dated: [how it compares to proxifly, TheSpeedX, monosans and clarketm](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/docs/comparison.md).
442
+ A list tells you what worked for its author when it was built. This is what the tool adds; what other projects document about their own checks is in the [comparison](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/comparison.md), no other list was measured for it.
443
+
444
+ | | **proxy-scraper** |
445
+ |---|---|
446
+ | Checked right before you use them, from your network | `--pick --verify`, `--recheck`, or a scan |
447
+ | The outcome of every check, with reason and time | `checks` in JSON, `--diagnose` |
448
+ | A second request that has to show the same exit IP | always attempted; if its target is down, your own run keeps the proxy as `unavailable`, the hourly list and `--verify` don't |
449
+ | A test page that has to arrive byte for byte | the same |
450
+ | HTTPS tested with a certificate that verifies (one test host) | unless `--fast` |
451
+ | Anonymity level and country per proxy | yes |
452
+ | Only proxies that reach *your* target site | `--target` |
453
+ | Learns which sources are worth it | yes |
454
+ | Usable as a single rotating proxy | `--serve` |
455
+ | API to fetch a proxy (same paths as proxy_pool) | [`/get`](#pool-api) |
456
+ | Ready-made list without running anything | [live list](#live-list) |
457
+
458
+ Named and dated: [how it compares to other tools and lists, task by task](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/comparison.md).
439
459
 
440
460
  <a id="examples"></a>
441
461
 
@@ -526,7 +546,7 @@ It runs on 127.0.0.1 with a random password, takes over each new hourly list by
526
546
 
527
547
  ## Rotating proxy server
528
548
 
529
- A list is nice – but usually you just want to enter **one** proxy that always works:
549
+ A list is nice – but usually you just want to enter **one** proxy address and have something behind it that keeps trying:
530
550
 
531
551
  ```bash
532
552
  proxy-scraper --recheck --serve # recheck the last hits, then go – takes seconds
@@ -551,7 +571,7 @@ proxy-scraper --recheck --serve --serve-host 0.0.0.0
551
571
  curl -x "http://country-de:$PROXY_SCRAPER_SERVE_PASSWORD@your-server:8899" https://api.ipify.org
552
572
  ```
553
573
 
554
- Without a password, `--serve-host` means **anyone who reaches the port can use it**. The ready-made [`compose.yaml`](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/compose.yaml) starts the server in Docker from the live list, with a password, a health check and learned state in a volume: put `PROXY_PASSWORD=…` into `.env`, then `docker compose up -d`.
574
+ Without a password the server refuses to start on any address but `127.0.0.1`: that would be an open proxy for **anyone who reaches the port** (Docker publishes ports past host firewalls like ufw). If a firewall or `-p 127.0.0.1:…` already keeps others out, say so with `--serve-open`. The ready-made [`compose.yaml`](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/compose.yaml) starts the server in Docker from the live list, with a password, a health check and learned state in a volume: put `PROXY_PASSWORD=…` into `.env`, then `docker compose up -d`.
555
575
 
556
576
  | Option | What it does |
557
577
  |---|---|
@@ -568,11 +588,11 @@ Without a password, `--serve-host` means **anyone who reaches the port can use i
568
588
  - `--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
569
589
  - listens on `127.0.0.1` only (unless `--serve-host` says otherwise), optionally with a password; live view with requests, success rate, pool and the latest connections
570
590
 
571
- In testing: 20 of 20 HTTPS requests succeeded, over 15 different exit IPs. In the wizard this is **Proxy server right away**.
591
+ In the wizard this is **Proxy server right away**.
572
592
 
573
593
  **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.
574
594
 
575
- <div align="center"><img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.28.0/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>
595
+ <div align="center"><img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.30.0/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>
576
596
 
577
597
  <a id="pool-api"></a>
578
598
 
@@ -598,7 +618,7 @@ curl "http://127.0.0.1:8899/report?proxy=203.0.113.7:8080&ok=0" # it failed you
598
618
 
599
619
  Filters work on `/get`, `/pop` and `/all`: `country=DE,AT`, `protocol=socks5`, `https=1`, `anonymity=elite`, `max_latency=1500`, and `format=txt` for plain URLs. With `--serve-password` the API wants it as Basic auth, like the status page.
600
620
 
601
- **Coming from [jhao104/proxy_pool](https://github.com/jhao104/proxy_pool)?** The endpoints, `type=https` and the JSON fields (`proxy`, `https`, `region`, `anonymous`, `check_count`, `fail_count`, …) are the same, so point your code at port 8899 and it keeps working – without Redis, and with proxies that passed the honeypot, tampering and TLS checks:
621
+ **Coming from [jhao104/proxy_pool](https://github.com/jhao104/proxy_pool)?** The endpoints, `type=https` and most JSON fields (`proxy`, `https`, `region`, `check_count`, `fail_count`, …) are the same, so point your code at port 8899 and most of it keeps working (three differences: there is no `last_time`, `anonymous` is true/false, not a string, and `source` is always `proxy-scraper`) – without Redis, and with proxies that passed the second-request, content and TLS checks:
602
622
 
603
623
  ```python
604
624
  import requests
@@ -610,16 +630,16 @@ requests.get("https://example.com", proxies={"http": proxy, "https": proxy})
610
630
 
611
631
  ## Discord and Telegram bot
612
632
 
613
- The live list can also come to you: [`bot/`](https://github.com/maximilianfeix/proxy-scraper/tree/v1.28.0/bot/) is a Discord bot that posts every run into a server – a summary with the fastest proxies, the full lists per protocol as files, and slash commands like `/proxies type:socks5 country:DE https:true`. It sets up its own read-only channels when you invite it, and a GitHub Action deploys it to a server as a systemd service. The same process answers on Telegram too: `/proxy de socks5` for one proxy with a curl line, `/proxies 10 us https` for a short list. Setup in [bot/README.md](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/bot/README.md).
633
+ The live list can also come to you: [`bot/`](https://github.com/maximilianfeix/proxy-scraper/tree/v1.30.0/bot/) is a Discord bot that posts every run into a server – a summary with the fastest proxies, the full lists per protocol as files, and slash commands like `/proxies type:socks5 country:DE https:true`. It sets up its own read-only channels when you invite it, and a GitHub Action deploys it to a server as a systemd service. The same process answers on Telegram too: `/proxy de socks5` for one proxy with a curl line, `/proxies 10 us https` for a short list. Setup in [bot/README.md](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/bot/README.md).
614
634
 
615
635
  <a id="how-it-works"></a>
616
636
 
617
637
  ## How it works
618
638
 
619
639
  <picture>
620
- <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.28.0/docs/checks-dark.svg">
621
- <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.28.0/docs/checks-light.svg">
622
- <img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.28.0/docs/checks-dark.svg" alt="The five checks: 700+ lists, a real handshake, two sites with one IP, nothing injected, the details" width="100%">
640
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.30.0/docs/checks-dark.svg">
641
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.30.0/docs/checks-light.svg">
642
+ <img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.30.0/docs/checks-dark.svg" alt="Illustration of the steps: the lists, a real handshake, two sites with one exit IP, an unchanged test page, the details" width="100%">
623
643
  </picture>
624
644
 
625
645
 
@@ -634,28 +654,29 @@ flowchart LR
634
654
  G -. next run .-> C
635
655
  ```
636
656
 
637
- 1. **Sources** – the curated list in [`sources.json`](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/proxyscraper/sources.json), meta sources (other projects that maintain lists of proxy sources) and, once a day, a GitHub search for actively maintained repos. Every search adds to what earlier ones found; a list the search hasn't seen for three weeks drops out.
638
- 2. **Collect** – plain text, HTML tables, JSON APIs and `type://ip:port` lines are recognized; private and reserved address ranges are dropped. Lists that haven't changed since the last run answer `304` and come from a local cache – a second run right after the first loads 0 MB instead of ~160 MB.
657
+ 1. **Sources** – the curated list in [`sources.json`](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/proxyscraper/sources.json), meta sources (other projects that maintain lists of proxy sources) and, once a day, a GitHub search for actively maintained repos. Every search adds to what earlier ones found; a list the search hasn't seen for three weeks drops out.
658
+ 2. **Collect** – plain text, HTML tables, JSON APIs and `type://ip:port` lines are recognized; private and reserved address ranges are dropped. Lists that haven't changed since the last run answer `304` and come from a local cache – a second run right after the first loads only what changed (in one logged hourly run 52 MB, with 431 of 746 lists unchanged).
639
659
  3. **Prioritize** – known working proxies first, then by the learned hit rate of their sources.
640
- 4. **Check** – every proxy has to fetch its exit IP from a check target (`checkip.amazonaws.com`, with `ifconfig.me`, `ipinfo.io`, `wtfismyip.com` and `ident.me` as reserves – none of them behind Cloudflare) and return a valid, *foreign* IP. If the target goes down mid-run, the tool switches and re-checks the proxies that were affected, so the statistics don't learn from an outage. Anyone passing your own IP through is out. Then comes the **confirmation** via `httpbin.org`: fake proxies that only answer the first check with “200 + IP” fail here. Finally a static HTML page has to arrive byte for byte as it does without a proxy – anyone injecting ads or scripts is out.
641
- 5. **Countries and providers** – looked up offline in the free DB-IP databases, including the provider (ASN) and whether it's probably a datacenter (about 45 % of working proxies are) (downloaded once a month, ~2 µs per lookup); ip-api.com is only asked for the few addresses it doesn't know.
642
- 6. **Blocklists** – one DNS lookup per exit IP against SpamCop, cached for the run: about 29 % of working proxies exit from a listed IP, and sites that use the list show those captchas or block them. `--no-blocklisted` drops them. If your DNS resolver is refused by SpamCop (large public resolvers are), the lookup is skipped instead of guessing.
660
+ 4. **Check** – every proxy has to fetch its exit IP from a check target (`checkip.amazonaws.com`, with `ifconfig.me`, `ipinfo.io`, `wtfismyip.com` and `ident.me` as reserves – none of them behind Cloudflare) and return a valid, *foreign* IP. If the target goes down mid-run, the tool switches and re-checks the proxies that were affected, so the statistics don't learn from an outage. The targets of the later checks are asked directly when a check against them fails; if they don't answer either, the proxy's check is `unavailable`, not `failed`. Anyone passing your own IP through is out. Then comes the **second request** via `httpbin.org`, which has to see the same exit IP: proxies that only answer the first check with “200 + IP” fail here, and so do unstable ones and exits that rotate. Finally a static HTML page has to arrive byte for byte as it does without a proxy. Each of these leaves [its outcome](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/check-states.md) on the result.
661
+ 5. **Countries and providers** – looked up offline in the free DB-IP databases, including the provider (ASN) and whether the provider's name looks like a hosting company (between 45 % and 65 % of the entries in the lists we looked at) (downloaded once a month, ~2 µs per lookup); ip-api.com is only asked for the few addresses it doesn't know.
662
+ 6. **Blocklists** – one DNS lookup per exit IP against SpamCop, cached for the run: between 28 % and 43 % of the entries exited from a listed IP in the lists we looked at, and sites that use the list show those captchas or block them. `--no-blocklisted` drops them. If your DNS resolver is refused by SpamCop (large public resolvers are), the lookup is skipped instead of guessing.
643
663
  7. **Learn** – hit rates and history are stored. Sources without hits, with content unchanged for a week or permanently unreachable are skipped.
644
664
 
645
665
  <details>
646
666
  <summary><b>📸 See the live dashboard and final report</b></summary>
647
667
  <br>
648
668
  <div align="center">
649
- <img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.28.0/docs/dashboard.svg" alt="Live dashboard while checking" width="860">
669
+ <img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.30.0/docs/dashboard.svg" alt="Live dashboard while checking" width="860">
650
670
  <br><br>
651
- <img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.28.0/docs/summary.svg" alt="Final report after a run" width="860">
671
+ <img src="https://raw.githubusercontent.com/maximilianfeix/proxy-scraper/v1.30.0/docs/summary.svg" alt="Final report after a run" width="860">
672
+ <sub>Illustration: the real interface, rendered with sample data by <a href="https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/make_demo.py">docs/make_demo.py</a>. The numbers in it are made up.</sub>
652
673
  </div>
653
674
  </details>
654
675
 
655
676
  ### Your own lists
656
677
 
657
678
  ```bash
658
- proxy-scraper --source https://example.com/my-list.txt --source socks5=./socks.txt # on top of the 700+ sources
679
+ proxy-scraper --source https://example.com/my-list.txt --source socks5=./socks.txt # on top of the built-in sources
659
680
  proxy-scraper --only-sources --source bought.txt --want 50 # only yours
660
681
  ```
661
682
 
@@ -856,7 +877,7 @@ pip download requests # git, pip, npm & co. now go through the pool
856
877
 
857
878
  **In a GitHub workflow** – the action picks working proxies for the next steps
858
879
 
859
- [Marketplace](https://github.com/marketplace/actions/proxy-scraper-free-working-proxies) · [Complete workflow, inputs and outputs](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/docs/github-action.md)
880
+ [Marketplace](https://github.com/marketplace/actions/proxy-scraper-free-working-proxies) · [Complete workflow, inputs and outputs](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/github-action.md)
860
881
 
861
882
  ```yaml
862
883
  - id: proxies
@@ -929,8 +950,12 @@ curl.exe -x (Get-Content "$run\all.txt" -TotalCount 1) http://api.ipify.org
929
950
  | `--no-cache` | download every list again (unchanged ones are normally skipped via ETag) |
930
951
  | `--list-sources [N]` | show the source ranking (add `--json` for scripts: url, status, hit rate, checks, last change) |
931
952
  | `--pick [N]` | print N proxies (default 1) from the hourly checked list and exit – no scan, same filters, plus `--min-uptime PERCENT`, `--min-speed KBPS` and `--works-on google,reddit,…` |
932
- | `--serve-host ADDR` | where the proxy server listens (default `127.0.0.1`; `0.0.0.0` for Docker, with a warning) |
953
+ | `--verify` | with `--pick`: check the candidates from your machine first and print only those that pass now – 5 candidates per proxy asked for (10 to 60), up to 8 at a time, 90 s at most; exit code 3 if fewer than N passed |
954
+ | `--diagnose PROXY` | check one proxy and show what each check found, [state by state](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/check-states.md); exit code 0 nothing failed, 1 a check failed, 3 a check could not run |
955
+ | `--json` | with `--pick` or `--diagnose` (and `--list-sources`): the result as JSON on stdout |
956
+ | `--serve-host ADDR` | where the proxy server listens (default `127.0.0.1`; any other address needs a password or `--serve-open`) |
933
957
  | `--serve-password SECRET` | clients must send this password in the proxy login; better set `PROXY_SCRAPER_SERVE_PASSWORD` |
958
+ | `--serve-open` | allow `--serve-host` without a password – only behind a firewall or with `docker -p 127.0.0.1:…` |
934
959
  | `--rotate STRATEGY` · `--sticky SEC` | how the proxy server picks proxies, see [above](#proxy-server) |
935
960
  | `--serve-refill HOURS` | while serving, check fresh proxies every HOURS and add the hits to the pool |
936
961
  | `--serve [PORT]` | afterwards serve as a rotating proxy on `127.0.0.1:PORT` (default: 8899) |
@@ -954,10 +979,10 @@ The repo does part of the work itself:
954
979
 
955
980
  | Workflow | What it does |
956
981
  |---|---|
957
- | [**tests**](https://github.com/maximilianfeix/proxy-scraper/actions/workflows/tests.yml) | 3 operating systems × 3 Python versions, plus a built and installed package – on every push and pull request |
982
+ | [**tests**](https://github.com/maximilianfeix/proxy-scraper/actions/workflows/tests.yml) | 3 operating systems × 4 Python versions, plus a built and installed package – on every push and pull request |
958
983
  | [**lint**](https://github.com/maximilianfeix/proxy-scraper/actions/workflows/lint.yml) | `ruff` with a pinned version – same rules locally and in CI |
959
984
  | [**codeql**](https://github.com/maximilianfeix/proxy-scraper/actions/workflows/codeql.yml) | security analysis on every push and once a week |
960
- | [**proxy list**](https://github.com/maximilianfeix/proxy-scraper/actions/workflows/proxy-list.yml) | every hour: collect, check, publish to `proxy-list`. The learned statistics live in the Actions cache, so the tool keeps getting better in the cloud too |
985
+ | [**proxy list**](https://github.com/maximilianfeix/proxy-scraper/actions/workflows/proxy-list.yml) | about every hour: collect, check, publish to `proxy-list`. The learned statistics live in the Actions cache, so the tool keeps getting better in the cloud too |
961
986
  | [**docker**](https://github.com/maximilianfeix/proxy-scraper/actions/workflows/docker.yml) | builds the image on every change and runs a real scan inside it; on a version tag it publishes `linux/amd64` + `linux/arm64` to `ghcr.io` |
962
987
  | [**release**](https://github.com/maximilianfeix/proxy-scraper/actions/workflows/release.yml) | on a version tag: test, build, smoke-test and publish a GitHub release with the wheel |
963
988
  | [**discord bot**](https://github.com/maximilianfeix/proxy-scraper/actions/workflows/bot.yml) | tests the bot and deploys it to the server on every change in `bot/` |
@@ -980,7 +1005,9 @@ Almost nobody runs a free proxy for you. What ends up on public lists is usually
980
1005
  - **Infected machines** – computers and IoT devices whose owners don't know they relay traffic. Many residential exits are like this.
981
1006
  - **Traps** – honeypots that log what goes through them, and proxies that rewrite pages to inject ads or scripts.
982
1007
 
983
- 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.
1008
+ That is general background, not something this project measured: a check can't see who runs a proxy or why.
1009
+
1010
+ 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, deliver a known page byte for byte, and HTTPS counts only with a certificate that verifies for the test host. Each hit says whether its exit is in a datacenter.
984
1011
 
985
1012
  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.
986
1013
 
@@ -1006,7 +1033,7 @@ Yes, in PowerShell and Windows Terminal. `uvloop` doesn't exist there and is ski
1006
1033
  <summary><b>Why does it find fewer proxies than other lists claim to have?</b></summary>
1007
1034
  <br>
1008
1035
 
1009
- Because only proxies that pass every check are kept. Many lists count anything that accepts a TCP connection; here a proxy must fetch two independent pages and show a foreign IP. That's usually a few hundred out of a million candidates – but they work.
1036
+ Because only proxies that pass every check are kept: two independent requests that show the same foreign exit IP, and a test page that arrives unchanged. In the hourly runs that is about 1 % of the 150,000 candidates checked. They passed from the network that checked them, at that moment.
1010
1037
 
1011
1038
  </details>
1012
1039
 
@@ -1022,7 +1049,7 @@ Lines like `socks5://user:pass@1.2.3.4:1080` keep their login: HTTP proxies get
1022
1049
  <summary><b>How fresh is the live list?</b></summary>
1023
1050
  <br>
1024
1051
 
1025
- It's rebuilt every hour; the “updated” badge shows the last run. Free proxies come and go quickly, so for anything important run `proxy-scraper --recheck` right before use.
1052
+ It's rebuilt about every hour; the “updated” badge shows the last run. Free proxies come and go quickly, so for anything important run `proxy-scraper --recheck` right before use.
1026
1053
 
1027
1054
  </details>
1028
1055
 
@@ -1058,7 +1085,7 @@ Shipped in [v1.5](https://github.com/maximilianfeix/proxy-scraper/milestone/5):
1058
1085
 
1059
1086
  ## Contributing
1060
1087
 
1061
- Bug reports, new sources and pull requests are very welcome – see [CONTRIBUTING.md](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/CONTRIBUTING.md), and [docs/ARCHITECTURE.md](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/docs/ARCHITECTURE.md) for how the pieces fit together. The short version:
1088
+ Bug reports, new sources and pull requests are very welcome – see [CONTRIBUTING.md](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/CONTRIBUTING.md), and [docs/ARCHITECTURE.md](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/docs/ARCHITECTURE.md) for how the pieces fit together. The short version:
1062
1089
 
1063
1090
  ```bash
1064
1091
  pip install -e ".[dev]"
@@ -1078,7 +1105,7 @@ proxyscraper/
1078
1105
  ├── app.py one run in phases: network → jobs → check → learn & report
1079
1106
  ├── options.py RunOptions + Filters – all settings in one place
1080
1107
  ├── pipeline.py collect sources, prioritize, check loop
1081
- ├── checker.py checks, honeypot confirmation, HTTPS test
1108
+ ├── checker.py the checks: basic, second request, content, HTTPS
1082
1109
  ├── handshake.py HTTP/SOCKS4/SOCKS5 handshakes incl. login
1083
1110
  ├── judges.py check targets, Cloudflare filter, failover
1084
1111
  ├── sources.py source lists, meta sources, GitHub discovery, statistics
@@ -1135,7 +1162,7 @@ From the same author: [dejabuilt](https://github.com/maximilianfeix/dejabuilt),
1135
1162
 
1136
1163
  ## Acknowledgements
1137
1164
 
1138
- proxy-scraper stands on the work of the people who publish free proxy lists. Thanks to everyone listed in [`sources.json`](https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/proxyscraper/sources.json), and especially to
1165
+ proxy-scraper stands on the work of the people who publish free proxy lists. Thanks to everyone listed in [`sources.json`](https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/proxyscraper/sources.json), and especially to
1139
1166
 
1140
1167
  - [monosans/proxy-scraper-checker](https://github.com/monosans/proxy-scraper-checker) and [gfpcom/free-proxy-list](https://github.com/gfpcom/free-proxy-list), whose curated source collections are read as meta sources
1141
1168
  - [Textualize/rich](https://github.com/Textualize/rich), which draws the whole terminal UI
@@ -1150,7 +1177,7 @@ This tool only collects publicly listed proxies and checks whether they work. Yo
1150
1177
 
1151
1178
  ---
1152
1179
 
1153
- <sub>Made in Germany by <a href="https://github.com/maximilianfeix">@maximilianfeix</a> · <a href="https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/LICENSE">MIT License</a> · <a href="https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/CHANGELOG.md">Changelog</a> · <a href="https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/SECURITY.md">Security</a> · <a href="https://github.com/maximilianfeix/proxy-scraper/blob/v1.28.0/CONTRIBUTING.md">Contributing</a></sub>
1180
+ <sub>Made in Germany by <a href="https://github.com/maximilianfeix">@maximilianfeix</a> · <a href="https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/LICENSE">MIT License</a> · <a href="https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/CHANGELOG.md">Changelog</a> · <a href="https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/SECURITY.md">Security</a> · <a href="https://github.com/maximilianfeix/proxy-scraper/blob/v1.30.0/CONTRIBUTING.md">Contributing</a></sub>
1154
1181
 
1155
1182
  <sub>If proxy-scraper saves you time, a ⭐ helps others find it.</sub>
1156
1183