分享 分享一段用 Ruby 模拟网页登录并拿到页面的代码

ruohanc · 2012年10月29日 · 最后由 ruohanc 回复于 2014年01月18日 · 7267 次阅读

要点在于 Net::HTTP.new("example.com").get(url, headers) 的时候 headers 中调用 cookie 方法, 在没有 @cookie 变量的时候就登录, 然后后期如果得到的返回是 302, (如果 302 代表需要登录). 那就清除 @cookie 变量再 retry

require "net/http"

module PubPage
  class HTTP

    class << self
      def get(path)
        @@instance ||= self.new
        @@instance.get(path)
      end
    end

    def get(path)
      uri = URI(path)
      url = "#{uri.path}?#{uri.query}"
      resp = http.get(url, headers)
      raise NeedLoginException if resp.code == "302"
      resp
      rescue NeedLoginException
      @cookie = nil
      retry
    end

    private
    def http
      @http ||= Net::HTTP.new("example.com")
    end

    def headers
      { "Cookie" => cookie }
    end

    def login_data
      config = YAML.load_file(Pow(Rails.root, "config/pub_page.yml"))
      account = config["account"]
      password = config["password"]
      "action=login&loginName=#{account}&pwd=#{password}"
    end

    def login
      @cookie = http
      .post("/login.json", login_data)
      .get_fields('set-cookie')
      .select {|e|
        e.match(/SESSION_ID/)
      }.map {|e|
        e.split(/; /)[0]
      }.first
    end

    def cookie
      login unless @cookie
      @cookie
    end
  end
end

尝试过用 mechanize 吗?

@ruohanc @yedingding watir 不行吗?好像这个还用的人挺多的

用过 mechanize 的表示此方法太土鳖啦,哈哈哈

#3 楼 @huacnleepatron 的飘过。

#1 楼 @yedingding #2 楼 @mobiwolf #3 楼 @huacnlee #4 楼 @lyfi2003 赞....起到了抛砖引玉的效果..我还真不知道那些东西..谢谢诸位

#5 楼 @ruohanc 既然如此再补充一下,测试 http based api 还可以用 faraday ,比较轻量级

用 mechanize 搞 xici.net 会莫名其妙的出错。。然后直接上了 net/http

准备在 redmine 上试试

#9 楼 @yixiaoyang - -。。。赶快看看楼上的建议,这个土鳖的方法就别用了。。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册