proxy_fetcher 0.11.0 → 0.15.1

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -1
  3. data/Gemfile +4 -2
  4. data/Rakefile +3 -1
  5. data/gemfiles/nokogiri.gemfile +1 -1
  6. data/gemfiles/oga.gemfile +2 -2
  7. data/lib/proxy_fetcher.rb +42 -31
  8. data/lib/proxy_fetcher/client/request.rb +3 -3
  9. data/lib/proxy_fetcher/configuration.rb +13 -9
  10. data/lib/proxy_fetcher/document/node.rb +1 -1
  11. data/lib/proxy_fetcher/manager.rb +40 -7
  12. data/lib/proxy_fetcher/providers/base.rb +2 -1
  13. data/lib/proxy_fetcher/providers/free_proxy_list.rb +0 -21
  14. data/lib/proxy_fetcher/providers/free_proxy_list_socks.rb +58 -0
  15. data/lib/proxy_fetcher/providers/free_proxy_list_ssl.rb +1 -0
  16. data/lib/proxy_fetcher/providers/free_proxy_list_us.rb +54 -0
  17. data/lib/proxy_fetcher/providers/mtpro.rb +43 -0
  18. data/lib/proxy_fetcher/providers/proxypedia.rb +48 -0
  19. data/lib/proxy_fetcher/providers/proxyscrape_http.rb +65 -0
  20. data/lib/proxy_fetcher/providers/proxyscrape_socks4.rb +65 -0
  21. data/lib/proxy_fetcher/providers/proxyscrape_socks5.rb +65 -0
  22. data/lib/proxy_fetcher/providers/xroxy.rb +2 -2
  23. data/lib/proxy_fetcher/proxy.rb +12 -0
  24. data/lib/proxy_fetcher/utils/http_client.rb +25 -21
  25. data/lib/proxy_fetcher/utils/proxy_validator.rb +20 -8
  26. data/lib/proxy_fetcher/version.rb +2 -2
  27. data/proxy_fetcher.gemspec +6 -4
  28. data/spec/fixtures/proxies.txt +14 -0
  29. data/spec/proxy_fetcher/client/client_spec.rb +10 -5
  30. data/spec/proxy_fetcher/manager_spec.rb +18 -0
  31. data/spec/proxy_fetcher/providers/proxy_classes_spec.rb +28 -0
  32. metadata +15 -12
  33. data/lib/proxy_fetcher/providers/gather_proxy.rb +0 -50
  34. data/spec/proxy_fetcher/providers/free_proxy_list_spec.rb +0 -13
  35. data/spec/proxy_fetcher/providers/free_proxy_list_ssl_spec.rb +0 -11
  36. data/spec/proxy_fetcher/providers/gather_proxy_spec.rb +0 -11
  37. data/spec/proxy_fetcher/providers/http_tunnel_spec.rb +0 -11
  38. data/spec/proxy_fetcher/providers/proxy_list_spec.rb +0 -11
  39. data/spec/proxy_fetcher/providers/xroxy_spec.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a0d7b377ed3c25e50552e89ba76c0e73fad3923bf171e1cee2f592d777787c3
4
- data.tar.gz: 83b594e04e03c74a63146a6907c99025d50607c88f8cf94f6d5ce044795243ad
3
+ metadata.gz: 071dd5bfeaf01174bf803981de6147f999e75b99a2d03c32e034b72dd5dc7c82
4
+ data.tar.gz: 1675ce07491e0cbce401c2a113ee7eccdcba0c4cf42ba7e380ad63be988ec91a
5
5
  SHA512:
6
- metadata.gz: 1f096c2473035255eb9492297b5641ab5caee62566eb20eb40d3b2f02eea5d06fa1279a2cadeb3266c0f52ce98040185a69678faf116b6398c2c75f79d5c4ebd
7
- data.tar.gz: a9372ef8bdbb3c51c5060308cbc46c905df3819e682bceb858ba494f5f94722095f2a2bee94575606f628d091b87325425c218f8c31a2b807bcb159c59ba6e65
6
+ metadata.gz: 42037b0b55109b535e25284815a096154c79bca2f58b107311f5c53da5b9ec0242ab39a6dd9bae48ef3e863c7f43251167180266578ac177887bd3a63215ef1e
7
+ data.tar.gz: 188dd298f8ea03e5985d89e97f99a12ef5d5384eae03a78f9b77e5172c28ae5990dec64795817d52ea6895395679a6c2f2deafafa3f8617154afb32fc06bc972
data/CHANGELOG.md CHANGED
@@ -4,7 +4,38 @@ Reverse Chronological Order:
4
4
 
5
5
  ## `master`
6
6
 
7
- * Add your description here
7
+ ...
8
+
9
+ ## `0.15.1` (2021-02-17)
10
+
11
+ * Support for Ruby 3.0
12
+
13
+ ## `0.15.0` (2021-01-26)
14
+
15
+ * Removed failing providers
16
+ * Added new
17
+ * Specs refactoring
18
+
19
+ ## `0.14.0` (2020-05-11)
20
+
21
+ * Add MTPro provider
22
+ * Add Proxypedia provider
23
+
24
+ ## `0.13.0` (2020-03-09)
25
+
26
+ * Fix GatherProxy provider
27
+ * Fix XRoxy provider
28
+ * Allow ability to load proxies from files
29
+ * Fix Proxy object comparators
30
+
31
+ ## `0.12.0` (2020-01-28)
32
+
33
+ * Fix XRoxy provider
34
+ * Fix multi-threading issues with config and adapter
35
+
36
+ ## `0.11.0` (2019-10-24)
37
+
38
+ * Big gem refactoring
8
39
 
9
40
  ## `0.10.2` (2019-03-15)
10
41
 
data/Gemfile CHANGED
@@ -5,10 +5,12 @@ source "https://rubygems.org"
5
5
  gemspec
6
6
 
7
7
  gem "nokogiri", "~> 1.8"
8
- gem "oga", "~> 2.0"
9
- gem "rubocop", "~> 0.74"
8
+ gem "oga", "~> 3.2"
9
+ gem "rubocop", "~> 1.0"
10
10
 
11
11
  group :test do
12
12
  gem "coveralls", require: false
13
+ # Until I find a way to introduce other MITM proxy
14
+ gem "webrick", "1.4.2"
13
15
  gem "evil-proxy", "~> 0.2"
14
16
  end
data/Rakefile CHANGED
@@ -3,6 +3,8 @@
3
3
  require "bundler/gem_tasks"
4
4
 
5
5
  require "rspec/core/rake_task"
6
- RSpec::Core::RakeTask.new(:spec)
6
+ RSpec::Core::RakeTask.new(:spec) do |t|
7
+ t.rspec_opts = '--tag "~unreliable"'
8
+ end
7
9
 
8
10
  task default: :spec
@@ -8,6 +8,6 @@ gem "nokogiri", "~> 1.8"
8
8
 
9
9
  group :test do
10
10
  gem "coveralls", require: false
11
+ gem "webrick"
11
12
  gem "evil-proxy", "~> 0.2"
12
- gem "rspec", "~> 3.6"
13
13
  end
data/gemfiles/oga.gemfile CHANGED
@@ -4,10 +4,10 @@ source "https://rubygems.org"
4
4
 
5
5
  gemspec path: "../"
6
6
 
7
- gem "oga", "~> 2.0"
7
+ gem "oga", "~> 3.0"
8
8
 
9
9
  group :test do
10
10
  gem "coveralls", require: false
11
+ gem "webrick"
11
12
  gem "evil-proxy", "~> 0.2"
12
- gem "rspec", "~> 3.6"
13
13
  end
data/lib/proxy_fetcher.rb CHANGED
@@ -4,43 +4,52 @@ require "uri"
4
4
  require "http"
5
5
  require "logger"
6
6
 
7
- require File.dirname(__FILE__) + "/proxy_fetcher/version"
7
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/version"
8
8
 
9
- require File.dirname(__FILE__) + "/proxy_fetcher/exceptions"
10
- require File.dirname(__FILE__) + "/proxy_fetcher/configuration"
11
- require File.dirname(__FILE__) + "/proxy_fetcher/configuration/providers_registry"
12
- require File.dirname(__FILE__) + "/proxy_fetcher/proxy"
13
- require File.dirname(__FILE__) + "/proxy_fetcher/manager"
14
- require File.dirname(__FILE__) + "/proxy_fetcher/null_logger"
9
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/exceptions"
10
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/configuration"
11
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/configuration/providers_registry"
12
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/proxy"
13
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/manager"
14
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/null_logger"
15
15
 
16
- require File.dirname(__FILE__) + "/proxy_fetcher/utils/http_client"
17
- require File.dirname(__FILE__) + "/proxy_fetcher/utils/proxy_validator"
18
- require File.dirname(__FILE__) + "/proxy_fetcher/utils/proxy_list_validator"
19
- require File.dirname(__FILE__) + "/proxy_fetcher/client/client"
20
- require File.dirname(__FILE__) + "/proxy_fetcher/client/request"
21
- require File.dirname(__FILE__) + "/proxy_fetcher/client/proxies_registry"
16
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/utils/http_client"
17
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/utils/proxy_validator"
18
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/utils/proxy_list_validator"
19
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/client/client"
20
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/client/request"
21
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/client/proxies_registry"
22
22
 
23
- require File.dirname(__FILE__) + "/proxy_fetcher/document"
24
- require File.dirname(__FILE__) + "/proxy_fetcher/document/adapters"
25
- require File.dirname(__FILE__) + "/proxy_fetcher/document/node"
26
- require File.dirname(__FILE__) + "/proxy_fetcher/document/adapters/abstract_adapter"
27
- require File.dirname(__FILE__) + "/proxy_fetcher/document/adapters/nokogiri_adapter"
28
- require File.dirname(__FILE__) + "/proxy_fetcher/document/adapters/oga_adapter"
23
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/document"
24
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/document/adapters"
25
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/document/node"
26
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/document/adapters/abstract_adapter"
27
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/document/adapters/nokogiri_adapter"
28
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/document/adapters/oga_adapter"
29
29
 
30
30
  ##
31
31
  # Ruby / JRuby lib for managing proxies
32
32
  module ProxyFetcher
33
33
  # ProxyFetcher providers namespace
34
34
  module Providers
35
- require File.dirname(__FILE__) + "/proxy_fetcher/providers/base"
36
- require File.dirname(__FILE__) + "/proxy_fetcher/providers/free_proxy_list"
37
- require File.dirname(__FILE__) + "/proxy_fetcher/providers/free_proxy_list_ssl"
38
- require File.dirname(__FILE__) + "/proxy_fetcher/providers/gather_proxy"
39
- require File.dirname(__FILE__) + "/proxy_fetcher/providers/http_tunnel"
40
- require File.dirname(__FILE__) + "/proxy_fetcher/providers/proxy_list"
41
- require File.dirname(__FILE__) + "/proxy_fetcher/providers/xroxy"
35
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/providers/base"
36
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/providers/free_proxy_list"
37
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/providers/free_proxy_list_socks"
38
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/providers/free_proxy_list_ssl"
39
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/providers/free_proxy_list_us"
40
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/providers/http_tunnel"
41
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/providers/mtpro"
42
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/providers/proxy_list"
43
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/providers/proxypedia"
44
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/providers/proxyscrape_http"
45
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/providers/proxyscrape_socks4"
46
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/providers/proxyscrape_socks5"
47
+ require "#{File.dirname(__FILE__)}/proxy_fetcher/providers/xroxy"
42
48
  end
43
49
 
50
+ @__config_access_lock__ = Mutex.new
51
+ @__config_definition_lock__ = Mutex.new
52
+
44
53
  # Main ProxyFetcher module.
45
54
  class << self
46
55
  ##
@@ -53,12 +62,14 @@ module ProxyFetcher
53
62
  # ProxyFetcher.config
54
63
  #
55
64
  # #=> #<ProxyFetcher::Configuration:0x0000000241eec8 @user_agent="Mozilla/5.0, ...", @pool_size=10,
56
- # @client_timeout=3, @proxy_validation_timeout=3, @provider_proxies_load_timeout=30,
57
- # @http_client=ProxyFetcher::HTTPClient, @proxy_validator=ProxyFetcher::ProxyValidator,
58
- # @providers=[:free_proxy_list, ...], @adapter=ProxyFetcher::Document::NokogiriAdapter>
65
+ # @client_timeout=3, @proxy_validation_timeout=3, @provider_proxies_load_timeout=30,
66
+ # @http_client=ProxyFetcher::HTTPClient, @proxy_validator=ProxyFetcher::ProxyValidator,
67
+ # @providers=[:free_proxy_list, ...], @adapter=ProxyFetcher::Document::NokogiriAdapter>
59
68
  #
60
69
  def config
61
- @config ||= ProxyFetcher::Configuration.new
70
+ @__config_definition_lock__.synchronize do
71
+ @config ||= ProxyFetcher::Configuration.new
72
+ end
62
73
  end
63
74
 
64
75
  ##
@@ -70,7 +81,7 @@ module ProxyFetcher
70
81
  # Configuration object.
71
82
  #
72
83
  def configure
73
- yield config
84
+ @__config_access_lock__.synchronize { yield config }
74
85
  end
75
86
 
76
87
  # Returns ProxyFetcher logger instance.
@@ -41,15 +41,15 @@ module ProxyFetcher
41
41
  # @return [String]
42
42
  # response body (requested resource content)
43
43
  #
44
- def self.execute(args)
45
- new(args).execute
44
+ def self.execute(**args)
45
+ new(**args).execute
46
46
  end
47
47
 
48
48
  # Initialize new HTTP request
49
49
  #
50
50
  # @return [Request]
51
51
  #
52
- def initialize(args)
52
+ def initialize(**args)
53
53
  raise ArgumentError, "args must be a Hash!" unless args.is_a?(Hash)
54
54
 
55
55
  @url = args.fetch(:url)
@@ -39,7 +39,7 @@ module ProxyFetcher
39
39
  attr_accessor :logger
40
40
 
41
41
  # @!attribute [r] adapter
42
- # @return [Object] HTML parser adapter
42
+ # @return [#to_s] HTML parser adapter
43
43
  attr_reader :adapter
44
44
 
45
45
  # @!attribute [r] http_client
@@ -51,7 +51,7 @@ module ProxyFetcher
51
51
  attr_reader :proxy_validator
52
52
 
53
53
  # @!attribute [r] providers
54
- # @return [Array<String>, Array<Symbol>] proxy providers list to be used
54
+ # @return [Array<String, Symbol>] proxy providers list to be used
55
55
  attr_reader :providers
56
56
 
57
57
  # User-Agent string that will be used by the ProxyFetcher HTTP client (to
@@ -68,6 +68,8 @@ module ProxyFetcher
68
68
  #
69
69
  DEFAULT_ADAPTER = :nokogiri
70
70
 
71
+ @__adapter_lock__ = Mutex.new
72
+
71
73
  class << self
72
74
  # Registry for handling proxy providers.
73
75
  #
@@ -93,7 +95,7 @@ module ProxyFetcher
93
95
 
94
96
  # Returns registered providers names.
95
97
  #
96
- # @return [Array<String>, Array<Symbol>]
98
+ # @return [Array<String, Symbol>]
97
99
  # registered providers names
98
100
  #
99
101
  def registered_providers
@@ -112,7 +114,7 @@ module ProxyFetcher
112
114
 
113
115
  # Sets default configuration options
114
116
  def reset!
115
- @logger = Logger.new(STDOUT)
117
+ @logger = Logger.new($stdout)
116
118
  @user_agent = DEFAULT_USER_AGENT
117
119
  @pool_size = 10
118
120
  @client_timeout = 3
@@ -131,16 +133,18 @@ module ProxyFetcher
131
133
  end
132
134
 
133
135
  def adapter_class
134
- return @adapter_class if defined?(@adapter_class)
136
+ self.class.instance_variable_get(:@__adapter_lock__).synchronize do
137
+ return @adapter_class if defined?(@adapter_class)
135
138
 
136
- @adapter_class = ProxyFetcher::Document::Adapters.lookup(adapter)
137
- @adapter_class.setup!
138
- @adapter_class
139
+ @adapter_class = ProxyFetcher::Document::Adapters.lookup(adapter)
140
+ @adapter_class.setup!
141
+ @adapter_class
142
+ end
139
143
  end
140
144
 
141
145
  # Setups collection of providers that will be used to fetch proxies.
142
146
  #
143
- # @param value [String, Symbol, Array<String>, Array<Symbol>]
147
+ # @param value [String, Symbol, Array<String, Symbol>]
144
148
  # provider names
145
149
  #
146
150
  def providers=(value)
@@ -83,7 +83,7 @@ module ProxyFetcher
83
83
  def clear(text)
84
84
  return "" if text.nil? || text.empty?
85
85
 
86
- text.strip.gsub(/[\t]/i, "")
86
+ text.strip.gsub(/\t/i, "")
87
87
  end
88
88
  end
89
89
  end
@@ -3,6 +3,16 @@
3
3
  module ProxyFetcher
4
4
  # ProxyFetcher Manager class for interacting with proxy lists from various providers.
5
5
  class Manager
6
+ REFRESHER_LOCK = Mutex.new
7
+
8
+ class << self
9
+ def from_files(files, **options)
10
+ new(**options.merge(files: Array(files)))
11
+ end
12
+
13
+ alias from_file from_files
14
+ end
15
+
6
16
  # @!attribute [r] proxies
7
17
  # @return [Array<ProxyFetcher::Proxy>] An array of proxies
8
18
  attr_reader :proxies
@@ -14,14 +24,17 @@ module ProxyFetcher
14
24
  #
15
25
  # @return [Manager]
16
26
  #
17
- def initialize(refresh: true, validate: false, filters: {})
18
- if refresh
19
- refresh_list!(filters)
27
+ def initialize(**options)
28
+ if options.fetch(:refresh, true)
29
+ refresh_list!(options.fetch(:filters, {}))
20
30
  else
21
31
  @proxies = []
22
32
  end
23
33
 
24
- cleanup! if validate
34
+ files = Array(options.fetch(:file, options.fetch(:files, [])))
35
+ load_proxies_from_files!(files) if files&.any?
36
+
37
+ cleanup! if options.fetch(:validate, false)
25
38
  end
26
39
 
27
40
  # Update current proxy list using configured providers.
@@ -30,17 +43,17 @@ module ProxyFetcher
30
43
  #
31
44
  def refresh_list!(filters = nil)
32
45
  @proxies = []
33
-
34
46
  threads = []
35
- lock = Mutex.new
36
47
 
37
48
  ProxyFetcher.config.providers.each do |provider_name|
38
49
  threads << Thread.new do
50
+ Thread.current.report_on_exception = false
51
+
39
52
  provider = ProxyFetcher::Configuration.providers_registry.class_for(provider_name)
40
53
  provider_filters = filters && filters.fetch(provider_name.to_sym, filters)
41
54
  provider_proxies = provider.fetch_proxies!(provider_filters)
42
55
 
43
- lock.synchronize do
56
+ REFRESHER_LOCK.synchronize do
44
57
  @proxies.concat(provider_proxies)
45
58
  end
46
59
  end
@@ -89,6 +102,26 @@ module ProxyFetcher
89
102
 
90
103
  alias pop! get!
91
104
 
105
+ # Loads proxies from files.
106
+ #
107
+ # @param proxy_files [String, Array<String,Pathname>]
108
+ # file path of list of files to load
109
+ #
110
+ def load_proxies_from_files!(proxy_files)
111
+ proxy_files = Array(proxy_files)
112
+ return if proxy_files.empty?
113
+
114
+ proxy_files.each do |proxy_file|
115
+ File.foreach(proxy_file, chomp: true) do |proxy_string|
116
+ addr, port = proxy_string.split(":", 2)
117
+ port = Integer(port) if port
118
+ @proxies << Proxy.new(addr: addr, port: port)
119
+ end
120
+ end
121
+
122
+ @proxies.uniq!
123
+ end
124
+
92
125
  # Clean current proxy list from dead proxies (that doesn't respond by timeout)
93
126
  #
94
127
  # @return [Array<ProxyFetcher::Proxy>]
@@ -108,7 +108,8 @@ module ProxyFetcher
108
108
  to_proxy(*args)
109
109
  rescue StandardError => e
110
110
  ProxyFetcher.logger.warn(
111
- "Failed to build Proxy object for #{self.class.name} due to error: #{e.message}"
111
+ "Failed to build Proxy for #{self.class.name.split("::").last} " \
112
+ "due to error: #{e.message}"
112
113
  )
113
114
 
114
115
  nil
@@ -45,27 +45,6 @@ module ProxyFetcher
45
45
  #
46
46
  def parse_type(html_node)
47
47
  https = html_node.content_at("td[6]")
48
- # frozen_string_literal: true
49
- # FreeProxyList provider class.
50
- # Provider URL to fetch proxy list
51
- # [NOTE] Doesn't support filtering
52
- # Converts HTML node (entry of N tags) to <code>ProxyFetcher::Proxy</code>
53
- # object.
54
- #
55
- # @param html_node [Object]
56
- # HTML node from the <code>ProxyFetcher::Document</code> DOM model.
57
- #
58
- # @return [ProxyFetcher::Proxy]
59
- # Proxy object
60
- #
61
- # Parses HTML node to extract proxy type.
62
- #
63
- # @param html_node [Object]
64
- # HTML node from the <code>ProxyFetcher::Document</code> DOM model.
65
- #
66
- # @return [String]
67
- # Proxy type
68
- #
69
48
  https&.casecmp("yes")&.zero? ? ProxyFetcher::Proxy::HTTPS : ProxyFetcher::Proxy::HTTP
70
49
  end
71
50
  end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ProxyFetcher
4
+ module Providers
5
+ # FreeProxyListSocks provider class.
6
+ class FreeProxyListSocks < Base
7
+ # Provider URL to fetch proxy list
8
+ def provider_url
9
+ "https://www.socks-proxy.net/"
10
+ end
11
+
12
+ # [NOTE] Doesn't support filtering
13
+ def xpath
14
+ '//table[@id="proxylisttable"]/tbody/tr'
15
+ end
16
+
17
+ # Converts HTML node (entry of N tags) to <code>ProxyFetcher::Proxy</code>
18
+ # object.
19
+ #
20
+ # @param html_node [Object]
21
+ # HTML node from the <code>ProxyFetcher::Document</code> DOM model.
22
+ #
23
+ # @return [ProxyFetcher::Proxy]
24
+ # Proxy object
25
+ #
26
+ def to_proxy(html_node)
27
+ ProxyFetcher::Proxy.new.tap do |proxy|
28
+ proxy.addr = html_node.content_at("td[1]")
29
+ proxy.port = Integer(html_node.content_at("td[2]").gsub(/^0+/, ""))
30
+ proxy.country = html_node.content_at("td[4]")
31
+ proxy.type = parse_type(html_node)
32
+ proxy.anonymity = html_node.content_at("td[6]")
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ # Parses HTML node to extract proxy type.
39
+ #
40
+ # @param html_node [Object]
41
+ # HTML node from the <code>ProxyFetcher::Document</code> DOM model.
42
+ #
43
+ # @return [String]
44
+ # Proxy type
45
+ #
46
+ def parse_type(html_node)
47
+ https = html_node.content_at("td[5]")
48
+
49
+ return ProxyFetcher::Proxy::SOCKS4 if https&.casecmp("socks4")&.zero?
50
+ return ProxyFetcher::Proxy::SOCKS5 if https&.casecmp("socks5")&.zero?
51
+
52
+ "Unknown"
53
+ end
54
+ end
55
+
56
+ ProxyFetcher::Configuration.register_provider(:free_proxy_list_socks, FreeProxyListSocks)
57
+ end
58
+ end