{"id":15580947,"url":"https://github.com/nbulaj/proxy_fetcher","last_synced_at":"2025-04-05T17:07:29.423Z","repository":{"id":44616462,"uuid":"91800768","full_name":"nbulaj/proxy_fetcher","owner":"nbulaj","description":"💪 Ruby / JRuby / TrufflleRuby gem \u0026 CLI for dealing with proxy lists from various sources","archived":false,"fork":false,"pushed_at":"2023-06-02T07:31:40.000Z","size":498,"stargazers_count":121,"open_issues_count":5,"forks_count":18,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-29T16:07:21.211Z","etag":null,"topics":["jruby","manager-proxies","proxies","proxy","proxy-checker","proxy-fetcher","proxy-list","proxy-validator","proxylist","proxymanager","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nbulaj.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-19T11:50:19.000Z","updated_at":"2024-05-02T05:36:35.000Z","dependencies_parsed_at":"2024-06-19T06:28:58.708Z","dependency_job_id":null,"html_url":"https://github.com/nbulaj/proxy_fetcher","commit_stats":{"total_commits":157,"total_committers":10,"mean_commits":15.7,"dds":"0.23566878980891715","last_synced_commit":"2ec54f145897e91ab7fd5d34efdaa47815988ca3"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nbulaj%2Fproxy_fetcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nbulaj%2Fproxy_fetcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nbulaj%2Fproxy_fetcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nbulaj%2Fproxy_fetcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nbulaj","download_url":"https://codeload.github.com/nbulaj/proxy_fetcher/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247369952,"owners_count":20927928,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jruby","manager-proxies","proxies","proxy","proxy-checker","proxy-fetcher","proxy-list","proxy-validator","proxylist","proxymanager","ruby"],"created_at":"2024-10-02T19:40:46.631Z","updated_at":"2025-04-05T17:07:29.393Z","avatar_url":"https://github.com/nbulaj.png","language":"Ruby","readme":"# Ruby / JRuby lib for managing proxies\n[![Gem Version](https://badge.fury.io/rb/proxy_fetcher.svg)](http://badge.fury.io/rb/proxy_fetcher)\n[![CI](https://github.com/nbulaj/proxy_fetcher/actions/workflows/ci.yml/badge.svg)](https://github.com/nbulaj/proxy_fetcher/actions/workflows/ci.yml)\n[![Coverage Status](https://coveralls.io/repos/github/nbulaj/proxy_fetcher/badge.svg)](https://coveralls.io/github/nbulaj/proxy_fetcher)\n[![Code Climate](https://codeclimate.com/github/nbulaj/proxy_fetcher/badges/gpa.svg)](https://codeclimate.com/github/nbulaj/proxy_fetcher)\n[![Inline docs](http://inch-ci.org/github/nbulaj/proxy_fetcher.png?branch=master)](http://inch-ci.org/github/nbulaj/proxy_fetcher)\n[![License](http://img.shields.io/badge/license-MIT-brightgreen.svg)](#license)\n\nThis gem can help your Ruby / JRuby application to make HTTP(S) requests using\nproxy by fetching and validating actual proxy lists from multiple providers.\n\nIt gives you a special `Manager` class that can load proxy lists, validate them and return random or specific proxies.\nIt also has a `Client` class that encapsulates all the logic for sending HTTP requests using proxies, automatically\nfetched and validated by the gem. Take a look at the documentation below to find all the gem features.\n\nAlso this gem can be used with any other programming language (Go / Python / etc) as standalone solution for downloading and\nvalidating proxy lists from the different providers. [Checkout examples](#standalone) of usage below.\n\n## Documentation valid for `master` branch\n\nPlease check the documentation for the version of doorkeeper you are using in:\nhttps://github.com/nbulaj/proxy_fetcher/releases\n\n## Table of Contents\n\n- [Dependencies](#dependencies)\n- [Installation](#installation)\n- [Example of usage](#example-of-usage)\n  - [In Ruby application](#in-ruby-application)\n  - [Standalone](#standalone)\n- [Client](#client)\n- [Configuration](#configuration)\n  - [Proxy validation speed](#proxy-validation-speed)\n- [Proxy object](#proxy-object)\n- [Providers](#providers)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Dependencies\n\nProxyFetcher gem itself requires Ruby `\u003e= 2.0.0` (or [JRuby](http://jruby.org/) `\u003e 9.0`, but maybe earlier too,\n[see GitHub Actions matrix](.github/workflows/ci.yml)) and great [HTTP.rb gem](https://github.com/httprb/http).\n\nHowever, it requires an adapter to parse HTML. If you do not specify any specific adapter, then it will use\ndefault one - [Nokogiri](https://github.com/sparklemotion/nokogiri). It's OK for any Ruby on Rails project\n(because they use it by default).\n\nBut if you want to use some specific adapter (for example your application uses [Oga](https://gitlab.com/yorickpeterse/oga),\nthen you need to manually add your dependencies to your project and configure ProxyFetcher to use another adapter. Moreover,\nyou can implement your own adapter if it your use-case. Take a look at the [Configuration](#configuration) section for more details.\n\n## Installation\n\nIf using bundler, first add 'proxy_fetcher' to your Gemfile:\n\n```ruby\ngem 'proxy_fetcher', '~\u003e 0.14'\n```\n\nor if you want to use the latest version (from `master` branch), then:\n\n```ruby\ngem 'proxy_fetcher', git: 'https://github.com/nbulaj/proxy_fetcher.git'\n```\n\nAnd run:\n\n```sh\nbundle install\n```\n\nOtherwise simply install the gem:\n\n```sh\ngem install proxy_fetcher -v '0.14'\n```\n\n## Example of usage\n\n### In Ruby application\n\nBy default ProxyFetcher uses all the available proxy providers. To get current proxy list without validation you\nneed to initialize an instance of `ProxyFetcher::Manager` class. By default ProxyFetcher will automatically load\nand parse all the proxies from all available sources:\n\n```ruby\nmanager = ProxyFetcher::Manager.new # will immediately load proxy list from the servers\nmanager.proxies\n\n #=\u003e [#\u003cProxyFetcher::Proxy:0x00000002879680 @addr=\"97.77.104.22\", @port=3128, @country=\"USA\",\n #     @response_time=5217, @type=\"HTTP\", @anonymity=\"High\"\u003e, ... ]\n```\n\nYou can initialize proxy manager without immediate load of the proxy list from the remote server by passing\n`refresh: false` on initialization:\n\n```ruby\nmanager = ProxyFetcher::Manager.new(refresh: false) # just initialize class instance\nmanager.proxies\n\n #=\u003e []\n```\n\nAlso you could use ProxyFetcher to load proxy lists from local files if you have such:\n\n```ruby\nmanager = ProxyFetcher::Manager.new(file: \"/home/dev/proxies.txt\", refresh: false)\n\n# or\n\nmanager = ProxyFetcher::Manager.from_file(file: \"/home/dev/proxies.txt\", refresh: false)\n\n# or\n\nmanager = ProxyFetcher::Manager.new(\n  files: Dir.glob(\"/home/dev/proxies/**/*.txt\"),\n  refresh: false\n)\nmanager.proxies\n\n #=\u003e [#\u003cProxyFetcher::Proxy:0x00000002879680 @addr=\"97.77.104.22\", @port=3128, @country=\"USA\",\n #     @response_time=5217, @type=\"HTTP\", @anonymity=\"High\"\u003e, ... ]\n```\n\n`ProxyFetcher::Manager` class is very helpful when you need to manipulate and manager proxies. To get the proxy\nfrom the list you can call `.get` or `.pop` method that will return first proxy and move it to the end of the list.\nThis methods has some equivalents like `get!` or aliased `pop!` that will return first **connectable** proxy and\nmove it to the end of the list. They both marked as danger methods because all dead proxies will be removed from the list.\n\nIf you need just some random proxy then call `manager.random_proxy` or it's alias `manager.random`.\n\nTo clean current proxy list from the dead entries that does not respond to the requests you need to use `cleanup!`\nor `validate!` method:\n\n```ruby\nmanager.cleanup! # or manager.validate!\n```\n\nThis action will enumerate proxy list and remove all the entries that doesn't respond by timeout or returns errors.\n\nIn order to increase the performance proxy list validation is performed using Ruby threads. By default gem creates a\npool with 10 threads, but you can increase this number by changing `pool_size` configuration option: `ProxyFetcher.config.pool_size = 50`.\nRead more in [Proxy validation speed](#proxy-validation-speed) section.\n\nIf you need raw proxy URLs (like `host:port`) then you can use `raw_proxies` methods that will return array of strings:\n\n```ruby\nmanager = ProxyFetcher::Manager.new\nmanager.raw_proxies\n\n # =\u003e [\"97.77.104.22:3128\", \"94.23.205.32:3128\", \"209.79.65.140:8080\",\n #     \"91.217.42.2:8080\", \"97.77.104.22:80\", \"165.234.102.177:8080\", ...]\n```\n\nYou don't need to initialize a new manager every time you want to load actual proxy list from the providers. All you\nneed is to refresh the proxy list by calling `#refresh_list!` (or `#fetch!`) method for your `ProxyFetcher::Manager` instance:\n\n```ruby\nmanager.refresh_list! # or manager.fetch!\n\n #=\u003e [#\u003cProxyFetcher::Proxy:0x00000002879680 @addr=\"97.77.104.22\", @port=3128, @country=\"USA\",\n #     @response_time=5217, @type=\"HTTP\", @anonymity=\"High\"\u003e, ... ]\n```\n\nIf you need to filter proxy list, for example, by country or response time and **selected provider supports filtering**\nwith GET params, then you can just pass your filters like a simple Ruby hash to the Manager instance:\n\n```ruby\nProxyFetcher.config.providers = :xroxy\n\nmanager = ProxyFetcher::Manager.new(filters: { country: 'PL', maxtime: '500' })\nmanager.proxies\n\n # =\u003e [...]\n```\n\n**[IMPORTANT]**: All the providers have their own filtering params! So you can't just use something like `country` to\nfilter all the proxies by country. If you are using multiple providers, then you can split your filters by proxy\nprovider names:\n\n```ruby\nProxyFetcher.config.providers = [:proxy_docker, :xroxy]\n\nmanager = ProxyFetcher::Manager.new(filters: {\n  hide_my_name: {\n    country: 'PL',\n    maxtime: '500'\n  },\n  xroxy: {\n    type: 'All_http'\n  }\n})\n\nmanager.proxies\n\n # =\u003e [...]\n```\n\nYou can apply different filters every time you calling `#refresh_list!` (or `#fetch!`) method:\n\n```ruby\nmanager.refresh_list!(country: 'PL', maxtime: '500')\n\n # =\u003e [...]\n```\n\n*NOTE*: not all the providers support filtering. Take a look at the provider classes to see if it supports custom filters.\n\n### Standalone\n\nAll you need to use this gem is Ruby \u003e= 2.0 (2.4 is recommended). You can install it in a different ways. If you are using Ubuntu Xenial (16.04LTS)\nthen you already have Ruby 2.3 installed. In other cases you can install it with [RVM](https://rvm.io/) or [rbenv](https://github.com/rbenv/rbenv).\n\nAfter installing Ruby just bundle the gem by running `gem install proxy_fetcher` in your terminal and now you can run it:\n\n```bash\nproxy_fetcher \u003e\u003e proxies.txt # Will download proxies from the default provider, validate them and write to file\n```\n\nIf you need a list of proxies from some specific provider, then you need to pass it's name with `-p` option:\n\n```bash\nproxy_fetcher -p xroxy \u003e\u003e proxies.txt # Will download proxies from the default provider, validate them and write to file\n```\n\nIf you need a list of proxies in JSON format just pass a `--json` option to the command:\n\n```bash\nproxy_fetcher --json\n\n# Will print:\n# {\"proxies\":[\"120.26.206.178:80\",\"119.61.13.242:1080\",\"117.40.213.26:80\",\"92.62.72.242:1080\",\"77.53.105.155:3124\"\n# \"58.20.41.172:35923\",\"204.116.192.151:35923\",\"190.5.96.58:1080\",\"170.250.109.97:35923\",\"121.41.82.99:1080\"]}\n```\n\nTo get all the possible options run:\n\n```bash\nproxy_fetcher --help\n```\n\n## Client\n\nProxyFetcher gem provides you a ready-to-use HTTP client that made requesting with proxies easy. It does all the work \nwith the proxy lists for you (load, validate, refresh, find proxy by type, follow redirects, etc). All you need it to\nmake HTTP(S) requests:\n\n```ruby\nrequire 'proxy_fetcher'\n\nProxyFetcher::Client.get 'https://example.com/resource'\n\nProxyFetcher::Client.post 'https://example.com/resource', { param: 'value' }\n\nProxyFetcher::Client.post 'https://example.com/resource', 'Any data'\n\nProxyFetcher::Client.post 'https://example.com/resource', { param: 'value'}.to_json , headers: { 'Content-Type': 'application/json' }\n\nProxyFetcher::Client.put 'https://example.com/resource', { param: 'value' }\n\nProxyFetcher::Client.patch 'https://example.com/resource', { param: 'value' }\n\nProxyFetcher::Client.delete 'https://example.com/resource'\n```\n\nBy default, `ProxyFetcher::Client` makes 1000 attempts to send a HTTP request in case if proxy is out of order or the\nremote server returns an error. You can increase or decrease this number for your case or set it to `nil` if you want to\nmake infinite number of requests (or before your Ruby process will die :skull:):\n\n```ruby\nrequire 'proxy_fetcher'\n\nProxyFetcher::Client.get 'https://example.com/resource', options: { max_retries: 10_000 }\n```\n\nYou can also use your own proxy object when using ProxyFetcher client:\n\n```ruby\nrequire 'proxy_fetcher'\n\nmanager = ProxyFetcher::Manager.new # will immediately load proxy list from the server\n\n#random will return random proxy object from the list\nProxyFetcher::Client.get 'https://example.com/resource', options: { proxy: manager.random }\n```\n\nBtw, if you need support of JavaScript or some other features, you need to implement your own client using, for example,\n`selenium-webdriver`.\n\n## Configuration\n\nProxyFetcher is very flexible gem. You can configure the most important parts of the library and use your own solutions.\n\nDefault configuration looks as follows:\n\n```ruby\nProxyFetcher.configure do |config|\n  config.logger = Logger.new($stdout)\n  config.user_agent = ProxyFetcher::Configuration::DEFAULT_USER_AGENT\n  config.pool_size = 10\n  config.client_timeout = 3\n  config.provider_proxies_load_timeout = 30\n  config.proxy_validation_timeout = 3\n  config.http_client = ProxyFetcher::HTTPClient\n  config.proxy_validator = ProxyFetcher::ProxyValidator\n  config.providers = ProxyFetcher::Configuration.registered_providers\n  config.adapter = ProxyFetcher::Configuration::DEFAULT_ADAPTER # :nokogiri by default\nend\n```\n\nYou can change any of the options above.\n\nFor example, you can set your custom User-Agent string:\n\n```ruby\nProxyFetcher.configure do |config|\n  config.user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'\nend\n```\n\nProxyFetcher uses HTTP.rb gem for dealing with HTTP(S) requests. It is fast enough and has a great chainable API.\nIf you wanna add, for example, your custom provider that was developed as a Single Page Application (SPA) with some JavaScript,\nthen you will need something like [selenium-webdriver](https://github.com/SeleniumHQ/selenium/tree/master/rb) to properly\nload the content of the website. For those and other cases you can write your own class for fetching HTML content by\nthe URL and setup it in the ProxyFetcher config:\n\n```ruby\nclass MyHTTPClient\n  # [IMPORTANT]: below methods are required!\n  def self.fetch(url)\n    # ... some magic to return proper HTML ...\n  end\nend\n\nProxyFetcher.config.http_client = MyHTTPClient\n\nmanager = ProxyFetcher::Manager.new\nmanager.proxies\n\n#=\u003e [#\u003cProxyFetcher::Proxy:0x00000002879680 @addr=\"97.77.104.22\", @port=3128, @country=\"USA\",\n #     @response_time=5217, @type=\"HTTP\", @anonymity=\"High\"\u003e, ... ]\n```\n\nYou can take a look at the [lib/proxy_fetcher/utils/http_client.rb](lib/proxy_fetcher/utils/http_client.rb) for an example.\n\nMoreover, you can write your own proxy validator to check if proxy is valid or not:\n\n```ruby\nclass MyProxyValidator\n  # [IMPORTANT]: below methods are required!\n  def self.connectable?(proxy_addr, proxy_port)\n    # ... some magic to check if proxy is valid ...\n  end\nend\n\nProxyFetcher.config.proxy_validator = MyProxyValidator\n\nmanager = ProxyFetcher::Manager.new\nmanager.proxies\n\n #=\u003e [#\u003cProxyFetcher::Proxy:0x00000002879680 @addr=\"97.77.104.22\", @port=3128, @country=\"USA\",\n #     @response_time=5217, @type=\"HTTP\", @anonymity=\"High\"\u003e, ... ]\n\nmanager.validate!\n\n #=\u003e [ ... ]\n```\n\nBe default, ProxyFetcher gem uses [Nokogiri](https://github.com/sparklemotion/nokogiri) for parsing HTML. If you want\nto use [Oga](https://gitlab.com/yorickpeterse/oga) instead, then you need to add `gem 'oga'` to your Gemfile and configure\nProxyFetcher as follows:\n\n```ruby\nProxyFetcher.config.adapter = :oga\n```\n\nAlso you can write your own HTML parser implementation and use it, take a look at the [abstract class and implementations](lib/proxy_fetcher/document).\nConfigure it as:\n\n```ruby\nProxyFetcher.config.adapter = MyHTMLParserClass\n```\n\n### Proxy validation speed\n\nThere are some tricks to increase proxy list validation performance.\n\nIn a few words, ProxyFetcher gem uses threads to validate proxies for availability. Every proxy is checked in a\nseparate thread. By default, ProxyFetcher uses a pool with a maximum of 10 threads. You can increase this number by\nsetting max number of threads in the config:\n\n```ruby\nProxyFetcher.config.pool_size = 50\n```\n\nYou can experiment with the threads pool size to find an optimal number of maximum threads count for you PC and OS.\nThis will definitely give you some performance improvements.\n\nMoreover, the common proxy validation speed depends on `ProxyFetcher.config.proxy_validation_timeout` option that is equal\nto `3` by default. It means that gem will wait 3 seconds for the server answer to check if particular proxy is connectable.\nYou can decrease this option to `1`, for example, and it will heavily increase proxy validation speed (**but remember**\nthat some proxies could be connectable, but slow, so with this option you will clear proxy list from the proxies that\nworks, but very slow).\n\n## Proxy object\n\nEvery proxy is a `ProxyFetcher::Proxy` object that has next readers (instance variables):\n\n* `addr` (IP address)\n* `port`\n* `type` (proxy type, can be HTTP, HTTPS, SOCKS4 or/and SOCKS5)\n* `country` (USA or Brazil for example)\n* `response_time` (5217 for example)\n* `anonymity` (`Low`, `Elite proxy` or `High +KA` for example)\n\nAlso you can call next instance methods for every Proxy object:\n\n* `connectable?` (whether proxy server is available)\n* `http?` (whether proxy server has a HTTP protocol)\n* `https?` (whether proxy server has a HTTPS protocol)\n* `socks4?`\n* `socks5?`\n* `uri` (returns `URI::Generic` object)\n* `url` (returns a formatted URL like \"_IP:PORT_\" or \"_http://IP:PORT_\" if `scheme: true` provided)\n\n## Providers\n\nCurrently ProxyFetcher can deal with next proxy providers (services):\n\n* Free Proxy List\n* Free SSL Proxies\n* Free Socks Proxies\n* Free US Proxies\n* HTTP Tunnel Genius\n* Proxy List\n* XRoxy\n* Proxypedia\n* Proxyscrape\n* MTPro.xyz\n\nIf you wanna use one of them just setup it in the config:\n\n```ruby\nProxyFetcher.config.provider = :free_proxy_list\n\nmanager = ProxyFetcher::Manager.new\nmanager.proxies\n #=\u003e ...\n```\n\nYou can use multiple providers at the same time:\n\n```ruby\nProxyFetcher.config.providers = :free_proxy_list, :xroxy, :proxy_docker\n\nmanager = ProxyFetcher::Manager.new\nmanager.proxies\n #=\u003e ...\n```\n\nIf you want to use all the possible proxy providers then you can configure ProxyFetcher as follows:\n\n```ruby\nProxyFetcher.config.providers = ProxyFetcher::Configuration.registered_providers\n\nmanager = ProxyFetcher::Manager.new\nmanager.proxies\n\n #=\u003e [#\u003cProxyFetcher::Proxy:0x00000002879680 @addr=\"97.77.104.22\", @port=3128, @country=\"USA\", \n #     @response_time=5217, @type=\"HTTP\", @anonymity=\"High\"\u003e, ... ]\n```\n\nMoreover, you can write your own provider! All you need is to create a class, that would be inherited from the\n`ProxyFetcher::Providers::Base` class, and register your provider like this:\n\n```ruby\nProxyFetcher::Configuration.register_provider(:your_provider, YourProviderClass)\n```\n\nProvider class must implement `self.load_proxy_list` and `#to_proxy(html_element)` methods that will load and parse\nprovider HTML page with proxy list. Take a look at the existing providers in the [lib/proxy_fetcher/providers](lib/proxy_fetcher/providers) directory.\n\n## Contributing\n\nYou are very welcome to help improve ProxyFetcher if you have suggestions for features that other people can use.\n\nTo contribute:\n\n1. Fork the project.\n2. Create your feature branch (`git checkout -b my-new-feature`).\n3. Implement your feature or bug fix.\n4. Add documentation for your feature or bug fix.\n5. Run \u003ctt\u003erake doc:yard\u003c/tt\u003e. If your changes are not 100% documented, go back to step 4.\n6. Add tests for your feature or bug fix.\n7. Run `rake spec` to make sure all tests pass.\n8. Commit your changes (`git commit -am 'Add new feature'`).\n9. Push to the branch (`git push origin my-new-feature`).\n10. Create new pull request.\n\nThanks.\n\n## License\n\n`proxy_fetcher` gem is released under the [MIT License](http://www.opensource.org/licenses/MIT).\n\nCopyright (c) 2017 Nikita Bulai (bulajnikita@gmail.com).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnbulaj%2Fproxy_fetcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnbulaj%2Fproxy_fetcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnbulaj%2Fproxy_fetcher/lists"}