Class: HttpCrawler::Client

Inherits:
Object show all
Defined in:
lib/http_crawler/client.rb

Direct Known Subclasses

Proxy::Client, Web::Client

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parameter = {}) ⇒ Client

init_uri 如果未初始化@uri,则会报错

继承类需要重定义 init_uri


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/http_crawler/client.rb', line 34

def initialize(parameter = {})
  parameter = parameter.symbolize_keys

  parameter[:uri_or_path] = parameter[:url] || parameter[:uri]

  if parameter[:uri_or_path]
    # 如果自定义uri
    raise "Client uri为重复初始化" if uri
    update_uri(parameter[:uri_or_path])
  else
    # 初始化 uri
    init_uri
  end

  # 初始化超时时间
  init_timeout

  # 初始化 ssl 协议
  init_ssl unless uri.blank?

  # 初始化一些 client 自定义参数
  init_client

  self.redirect = true
  # 初始化 代理参数
  @proxy_params = {key: "#{self.class.to_s.gsub(":", "_")}"}
end

Instance Attribute Details

#all_timeoutObject

Returns the value of attribute all_timeout.



95
96
97
# File 'lib/http_crawler/client.rb', line 95

def all_timeout
  @all_timeout
end

#connect_timeObject

Returns the value of attribute connect_time.



95
96
97
# File 'lib/http_crawler/client.rb', line 95

def connect_time
  @connect_time
end

#cookiesObject

创建时间: 2019/9/16 17:12 更新时间: 2019/9/16 作者: Jagger 方法名称: cookies 方法说明: 返回头文件 调用方式: #cookies

Returns:



191
192
193
# File 'lib/http_crawler/client.rb', line 191

def cookies
  @cookies
end

#error_urlsObject

Returns the value of attribute error_urls.



388
389
390
# File 'lib/http_crawler/client.rb', line 388

def error_urls
  @error_urls
end

#headerObject

创建时间: 2019/9/16 17:11 更新时间: 2019/9/16 作者: Jagger 方法名称: header 方法说明: 返回头文件 调用方式: #header

Returns:



124
125
126
# File 'lib/http_crawler/client.rb', line 124

def header
  @header
end

#max_error_numObject

最大错误重试次数



64
65
66
# File 'lib/http_crawler/client.rb', line 64

def max_error_num
  @max_error_num
end

#read_timeObject

Returns the value of attribute read_time.



95
96
97
# File 'lib/http_crawler/client.rb', line 95

def read_time
  @read_time
end

#redirectObject

Returns the value of attribute redirect.



113
114
115
# File 'lib/http_crawler/client.rb', line 113

def redirect
  @redirect
end

#responseObject

请求的响应



499
500
501
# File 'lib/http_crawler/client.rb', line 499

def response
  @response
end

#uriObject (readonly)

Returns the value of attribute uri.



68
69
70
# File 'lib/http_crawler/client.rb', line 68

def uri
  @uri
end

#write_timeObject

Returns the value of attribute write_time.



95
96
97
# File 'lib/http_crawler/client.rb', line 95

def write_time
  @write_time
end

Class Method Details

.for(web_name, args = {}) ⇒ Object

接收格式 web_name = “biquge_duquanben” 返回 HttpCrawler::Web::BiqugeDuquanben::Client 实例



12
13
14
# File 'lib/http_crawler/client.rb', line 12

def for(web_name, args = {})
  "HttpCrawler::Web::#{web_name.camelize}::Client".constantize.new(args)
end

.for_module(module_name, args = {}) ⇒ Object

接收格式 module_name = “HttpCrawler::Web::BiqugeDuquanben” 返回 HttpCrawler::Web::BiqugeDuquanben::Client 实例



21
22
23
# File 'lib/http_crawler/client.rb', line 21

def for_module(module_name, args = {})
  "#{module_name}::Client".constantize.new(args)
end

.for_uri(path) ⇒ Object



25
26
27
# File 'lib/http_crawler/client.rb', line 25

def for_uri(path)
  self.new(uri: path)
end

Instance Method Details

#add_error_url(url_string) ⇒ Object

添加错误的url地址,表示这里面的url都是异常地址,存的是正则



395
396
397
# File 'lib/http_crawler/client.rb', line 395

def add_error_url(url_string)
  self.error_urls << url_string
end

#auto_proxy=(value) ⇒ Object

创建时间: 2019/9/16 17:19 更新时间: 2019/9/16 作者: Jagger 方法名称: auto_proxy= 方法说明: 自动更新代理设置 调用方式: #auto_proxy=

Returns:



278
279
280
281
282
# File 'lib/http_crawler/client.rb', line 278

def auto_proxy=(value)
  Rails.logger.debug "自动更新代理"
  @auto_proxy = value
  update_proxy if (value == true && @proxy.blank?)
end

#get(path, params = {}, limit = 3) ⇒ Object

创建时间: 2019/9/16 17:27 更新时间: 2019/9/16 作者: Jagger 方法名称: get 方法说明: 发送get请求 调用方式: #get

Parameters:

  • path (String)

    uri路由地址

  • params (Hash) (defaults to: {})

    get参数

  • limit (Integer) (defaults to: 3)

    错误递归次数

Returns:



455
456
457
458
459
460
461
462
463
464
465
# File 'lib/http_crawler/client.rb', line 455

def get(path, params = {}, limit = 3)
  raise "Client uri为空" unless self.uri
  request do
    r = http.get((self.uri + path).to_s, :params => params, :ssl_context => @ctx)
    return r if limit < 0
    r.html.at_xpath("//meta[@http-equiv='Refresh']").jagger_blank do |objc|
      r = self.get(objc.to_html[/(?:URL|url)="?(.*)[^";>]/, 1], params, limit - 1)
    end
    r
  end
end

#get_proxyObject

获取proxy 通过调用 api 获取代理或者通过自定义设置代理 创建时间: 2019/9/16 17:26 更新时间: 2019/9/16 作者: Jagger 方法名称: get_proxy 方法说明: 获取proxy、通过调用 api 获取代理或者通过自定义设置代理 调用方式: #get_proxy

Returns:



360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
# File 'lib/http_crawler/client.rb', line 360

def get_proxy
  proxy_ip = nil
  begin
    Rails.logger.debug("开始获取代理IP")
    proxy_client = HttpCrawler::Proxy.for(proxy_api)
    proxy_r = proxy_client.get_proxy(proxy_params.symbolize_keys)
    proxy_ip = proxy_r.results unless proxy_r.results.blank?
    # 测试本地代理
    # proxy_ip = {p_addr: "127.0.0.1", p_port: 8888} if "production" =! Rails.env
    if proxy_ip.blank?
      Rails.logger.warn "无最新代理等待5秒后重新获取:proxy 为空"
    else
      break
    end
    sleep(5)
  end while true
  proxy_ip = proxy_ip.symbolize_keys

  unless proxy_ip[:p_addr] && proxy_ip[:p_port]
    Rails.logger.warn "无最新代理等待5秒后重新获取:p_addr 或 p_port 为空"
    sleep(5)
    proxy_ip = get_proxy
  end

  Rails.logger.info("当前IP => #{@proxy},切换至代理 => #{proxy_ip}")
  proxy_ip
end

#get_uriObject

创建时间: 2019/9/16 17:29 更新时间: 2019/9/16 作者: Jagger 方法名称: get_uri 方法说明: 直接发送uri的get请求 调用方式: #get_uri

Returns:



475
476
477
478
# File 'lib/http_crawler/client.rb', line 475

def get_uri
  raise "Client uri为空" unless self.uri
  request {http.get(self.uri.to_s, :ssl_context => @ctx)}
end

#httpObject

初始化http请求前置条件 创建时间: 2019/9/16 17:27 更新时间: 2019/9/16 作者: Jagger 方法名称: http 方法说明: 创建Http的对象,用于发送请求 调用方式: #http

Returns:

  • HTTP



414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
# File 'lib/http_crawler/client.rb', line 414

def http

  h = HTTP
  # 自动重定向。最大重定向次数 max_hops: 5
  h = h.follow(max_hops: 5) if self.redirect == true

  # 添加代理
  h = h.via(@proxy[:p_addr], @proxy[:p_port].to_i, @proxy[:p_user], @proxy[:p_pass]) unless (@proxy.blank?)

  # 添加头文件
  h = h.headers(header) if header

  # 添加cookies
  h = h.cookies(cookies) if cookies

  # 添加超时时间
  if (@all_timeout)
    # 整体总计超时时间
    h = h.timeout(@all_timeout)
  else
    # 指定每个处理超时时间
    h = h.timeout(connect: @connect_time, write: @write_time, read: @read_time)
  end

  h
end

#inheritance_cookiesObject

创建时间: 2019/9/16 17:20 更新时间: 2019/9/16 作者: Jagger 方法名称: inheritance_cookies 方法说明: 继承上一个请求的set-cookies 调用方式: #inheritance_cookies

Returns:



262
263
264
265
266
267
# File 'lib/http_crawler/client.rb', line 262

def inheritance_cookies
  @response.cookies.each do |cookie|
    @cookies[:"#{cookie.name}"] = cookie.value
  end unless @response.blank?
  @cookies
end

#init_clientObject

初始化init_client参数



401
402
403
# File 'lib/http_crawler/client.rb', line 401

def init_client
  nil
end

#init_cookiesObject

创建时间: 2019/9/16 17:13 更新时间: 2019/9/16 作者: Jagger 方法名称: init_cookies 方法说明: 初始化头文件 调用方式: #init_cookies

Returns:



204
205
206
# File 'lib/http_crawler/client.rb', line 204

def init_cookies
  @cookies = {}
end

#init_headerObject

创建时间: 2019/9/16 17:08 更新时间: 2019/9/16 作者: Jagger 方法名称: init_header 方法说明: 初始化头文件 调用方式: #init_header

Returns:



137
138
139
140
141
142
143
144
145
146
# File 'lib/http_crawler/client.rb', line 137

def init_header
  @header = {
      "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
      "Accept-Encoding": "gzip, br",
      "Accept-Language": "zh-CN,zh;q=0.9",
      "Connection": "keep-alive",
      "Upgrade-Insecure-Requests": "1",
      "User-Agent": " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36",
  }
end

#init_sslObject

初始化 ssl 协议



105
106
107
108
109
110
111
# File 'lib/http_crawler/client.rb', line 105

def init_ssl
  if (@uri.scheme == "https")
    # ssl 协议
    @ctx = OpenSSL::SSL::SSLContext.new
    @ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
  end
end

#init_timeoutObject

初始化超时时间



97
98
99
100
101
102
# File 'lib/http_crawler/client.rb', line 97

def init_timeout
  @connect_time = 5
  @write_time = 5
  @read_time = 5
  @all_timeout = nil
end

#init_uriObject

init_uri 如果未初始化@uri,则会报错

继承类需要实现 @uri = URI("http://host")


72
73
74
# File 'lib/http_crawler/client.rb', line 72

def init_uri
  @uri = nil
end

#post(path, params = {}, format = :form) ⇒ Object

发送 post 请求 创建时间: 2019/9/16 17:29 更新时间: 2019/9/16 作者: Jagger 方法名称: post 方法说明: 发送 post 请求 调用方式: #post

Parameters:

  • path (String)

    uri路由地址

  • params (Hash) (defaults to: {})

    get参数

  • format (defaults to: :form)

    请求参数的模式::params、:form、:body、:json、:form。

Returns:



493
494
495
496
# File 'lib/http_crawler/client.rb', line 493

def post(path, params = {}, format = :form)
  raise "Client uri为空" unless self.uri
  request {http.post((self.uri + path).to_s, format => params, :ssl_context => @ctx)}
end

#proxy_apiObject

创建时间: 2019/9/16 17:23 更新时间: 2019/9/16 作者: Jagger 方法名称: proxy_api 方法说明: 代理使用的api方法名 调用方式: #proxy_api

Returns:



293
294
295
# File 'lib/http_crawler/client.rb', line 293

def proxy_api
  @proxy_api ||= "my"
end

#proxy_paramsObject

创建时间: 2019/9/16 17:24 更新时间: 2019/9/16 作者: Jagger 方法名称: proxy_params 方法说明: 调用代理 api使用的参数 调用方式: #proxy_params

Returns:



305
306
307
# File 'lib/http_crawler/client.rb', line 305

def proxy_params
  @proxy_params ||= {key: "default"}
end

#remove_tracesObject

创建时间: 2020/4/7 16:54 更新时间: 2020/4/7 作者: Jagger 方法名称: remove_traces 方法说明: 清除痕迹 调用方式: #remove_traces

Returns:



217
218
219
220
# File 'lib/http_crawler/client.rb', line 217

def remove_traces
  @response = nil
  self.init_cookies
end

#replace_header(parameter = {}) ⇒ Object

创建时间: 2019/9/16 17:10 更新时间: 2019/9/16 作者: Jagger 方法名称: replace_header 方法说明: 替换头文件 调用方式: #replace_header

Parameters:

  • parameter (Hash) (defaults to: {})

    "": ,  # 参数说明
    

Options Hash (parameter):

  • Hash模式传参 (Hash)

Returns:



176
177
178
# File 'lib/http_crawler/client.rb', line 176

def replace_header(parameter = {})
  @header = parameter.symbolize_keys
end

#update_cookies(parameter = {}) ⇒ Object

创建时间: 2019/9/16 17:13 更新时间: 2019/9/16 作者: Jagger 方法名称: update_cookies 方法说明: 更新cookies,局部替换 调用方式: #update_cookies

Parameters:

  • parameter (Hash) (defaults to: {})

    "": ,  # 参数说明
    

Options Hash (parameter):

  • Hash模式传参 (Hash)

Returns:



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/http_crawler/client.rb', line 237

def update_cookies(parameter = {})
  case parameter
  when String
    hash = {}
    parameter.scan(/([^=]*)=([^;]*);? ?/) do |m|
      hash[:"#{m[0]}"] = m[1]
    end
    self.cookies = cookies.merge(hash.symbolize_keys)
  when Hash
    self.cookies  = cookies.merge(parameter.symbolize_keys)
  else
    raise "cookies传入格式错误"
  end
  self.cookies
end

#update_header(parameter = {}) ⇒ Object

创建时间: 2019/9/16 17:08 更新时间: 2019/9/16 作者: Jagger 方法名称: update_header 方法说明: 更新头文件,局部更新 调用方式: #update_header

Returns:



157
158
159
# File 'lib/http_crawler/client.rb', line 157

def update_header(parameter = {})
  @header = @header.merge(parameter.symbolize_keys)
end

#update_proxy(proxy = {}) ⇒ Object

创建时间: 2019/9/16 17:24 更新时间: 2019/9/16 作者: Jagger 方法名称: update_proxy 方法说明: 更新代理,如果未传入代理则自动获取代理 调用方式: #update_proxy

Parameters:

  • proxy (Hash) (defaults to: {})

Options Hash (proxy):

  • Hash模式传参 (Hash)

Returns:



320
321
322
323
324
325
326
327
328
# File 'lib/http_crawler/client.rb', line 320

def update_proxy(proxy = {})
  proxy = proxy.symbolize_keys
  if (proxy.blank?)
    @proxy = get_proxy
  else
    @proxy = proxy
  end
  # @http.update_proxy(proxy)
end

#update_proxy?Boolean

创建时间: 2019/9/16 17:25 更新时间: 2019/9/16 作者: Jagger 方法名称: update_proxy? 方法说明: 是否自动更新代理,如果自动更新代理 则更新代理返回 true,否则返回false 调用方式: #update_proxy?

Returns:

  • (Boolean)


339
340
341
342
343
344
345
346
# File 'lib/http_crawler/client.rb', line 339

def update_proxy?
  if @auto_proxy
    self.update_proxy
    return true
  else
    return false
  end
end

#update_uri(uri_or_path) ⇒ Object

更新uri



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/http_crawler/client.rb', line 77

def update_uri(uri_or_path)
  case uri_or_path
  when URI
    @uri = uri_or_path
  when String
    if uri_or_path =~ /^http/
      @uri = URI(uri_or_path)
    else
      @uri = @uri + uri_or_path
    end
  else
    raise ArgumentError, uri_or_path
  end
  # 初始化 ssl 协议
  self.init_ssl
  self.uri
end

#validation_to_proxy?(r = response) ⇒ Boolean

出现如果验证码,切换代理 创建时间: 2019/9/16 17:31 更新时间: 2019/9/16 作者: Jagger 方法名称: validation_to_proxy? 方法说明: 验证是否出现验证码,出现如果验证码,切换代理 调用方式: #validation_to_proxy?

Parameters:

  • r (defaults to: response)

    默认为本身的 @response

Returns:

  • (Boolean)


513
514
515
516
517
518
519
520
521
522
523
# File 'lib/http_crawler/client.rb', line 513

def validation_to_proxy?(r = response)
  # 判断是否出现验证码
  if r.validation_page?
    # 触发验证码切换代理
    self.update_proxy?
    # 成功处理
    return true
  else
    return false
  end
end