lib/http_crawler/client.rb in http_crawler-0.2.3.3 vs lib/http_crawler/client.rb in http_crawler-0.3.0.0
- old
+ new
@@ -1,5 +1,7 @@
+load File.dirname(__FILE__) + '/http/response.rb'
+
module HttpCrawler
module Client
class << self
@@ -19,47 +21,36 @@
def for_module(module_name, *args)
"#{module_name}::Client".constantize.new(*args)
end
end
- attr_reader :http, :uri
+ attr_reader :uri
- #
# init_uri 如果未初始化@uri,则会报错
- # 继承类需要重定义 init_uri
+ # 继承类需要实现 @uri = URI("http://host")
#
- def initialize
- raise "Client uri为空" unless init_uri
- @http = HttpCrawler::HTTP.new(uri.host, uri.port)
-
- @http.use_ssl = (uri.scheme == "https")
-
- @http.open_timeout = 5
- @http.read_timeout = 5
- @http.proxy_key = "#{self.class}"
- init_http
-
- Rails.logger.debug "proxy_key => #{@http.proxy_key}"
+ def init_uri
+ @uri = nil
end
- # 初始化http参数
- def init_http
-
+ # 初始化超时时间
+ def init_timeout
+ @connect_time = 5
+ @write_time = 2
+ @read_time = 5
end
- # 添加错误的url地址,表示这里面的url都是异常地址,存的是正则
- def add_error_url(url_string)
- @http.error_urls << url_string
+ # 初始化 ssl 协议
+ def init_ssl
+ if (@uri.scheme == "https")
+ # ssl 协议
+ @ctx = OpenSSL::SSL::SSLContext.new
+ @ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ end
end
- # init_uri 如果未初始化@uri,则会报错
- # 继承类需要实现 @uri = URI("http://host")
- #
- def init_uri
- @uri = nil
- end
-
+ # 头文件相关方法
def header
@header ||= init_header
end
def init_header
@@ -68,22 +59,147 @@
def update_header(parameter = {})
nil
end
- def update_proxy(proxy = {})
- @http.update_proxy(proxy)
+ # cookies
+ def cookies
+ @cookies ||= {}
end
+
+ # 代理设置
def auto_proxy=(value)
Rails.logger.debug "自动更新代理"
- @http.auto_proxy = value
- @http.update_proxy if (value == true && @http.proxy? == false)
+ @auto_proxy = value
+ update_proxy if (value == true && @proxy.blank?)
end
- # 是否验证码界面
- def validation_page?(*arg)
- false
+ # 代理使用的api方法名
+ def proxy_api
+ @proxy_api ||= "my"
end
+ # 调用代理 api使用的参数
+ def proxy_params
+ @proxy_params ||= {"key": "default"}
+ end
+
+ def update_proxy(proxy = {})
+ if (proxy.blank?)
+ @proxy = get_proxy
+ else
+ @proxy = proxy
+ end
+ # @http.update_proxy(proxy)
+ end
+
+
+ # 如果自动更新代理 则更新代理返回 true,否则返回false
+ def update_proxy?(proxy_ip = {})
+ if @auto_proxy
+ update_proxy(proxy_ip)
+ return true
+ else
+ return false
+ end
+ end
+
+
+ # 获取proxy
+ # 通过调用 api 获取代理或者通过自定义设置代理
+ 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)
+ proxy_ip = proxy_r.results unless proxy_r.results.blank?
+ if proxy_ip.blank?
+ Rails.logger.warn "无最新代理等待5秒后重新获取"
+ else
+ break
+ end
+ sleep(5)
+ end while true
+
+ Rails.logger.debug("当前IP => #{@proxy},获取最新代理 => #{proxy_ip}")
+
+ unless proxy_ip && proxy_ip["p_addr"] && proxy_ip["p_port"]
+ Rails.logger.warn "无最新代理等待5秒后重新获取"
+ sleep(5)
+ proxy_ip = get_proxy
+ end
+
+ if (@proxy && proxy_ip && @proxy["p_addr"] == proxy_ip["p_addr"] && @proxy["p_port"] == proxy_ip["p_port"])
+ Rails.logger.warn "无最新代理等待5秒后重新获取"
+ sleep(5)
+ proxy_ip = get_proxy
+ end
+ proxy_ip
+ end
+
+ # 添加错误的url地址,表示这里面的url都是异常地址,存的是正则
+ def add_error_url(url_string)
+ @http.error_urls << url_string
+ end
+
+
+ # 初始化http参数
+ def init_client
+
+ end
+
+ # 初始化http请求前置条件
+ def http
+ # 自动重定向。最大重定向次数 max_hops: 5
+ h = HTTP.follow(max_hops: 5)
+
+ # 添加代理
+ 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
+
+ # 添加超时时间
+ h = h.timeout(connect: @connect_time, write: @write_time, read: @read_time)
+
+ h
+ end
+
+ # 发送 get 请求
+ def get(path, params = {})
+ http.get((@uri + path).to_s, :params => params, :ssl_context => @ctx)
+ end
+
+ # 发送 post 请求
+ def post(path, params = {})
+ http.post((@uri + path).to_s, :form => params, :ssl_context => @ctx)
+ end
+
+ #
+ # init_uri 如果未初始化@uri,则会报错
+ # 继承类需要重定义 init_uri
+ #
+ def initialize
+ # 初始化 uri
+ raise "Client uri为空" unless init_uri
+
+ # 初始化超时时间
+ init_timeout
+
+ # 初始化 ssl 协议
+ init_ssl
+
+ # 初始化一些 client 自定义参数
+ init_client
+
+ # 初始化 代理参数
+ @proxy_params = {key: "#{self.class}"}
+ end
+
end
-end
\ No newline at end of file
+end
+