新手问题 Ruby 脚本 如何解决网页需要登录的问题?

stardiviner · 2014年08月11日 · 最后由 rubychinaspa 回复于 2014年08月12日 · 4217 次阅读

我想做一个下载网页上链接的小脚本。 我尝试了 Nokogiri。

这是我写的脚本。里面 nokogiri 传入的似乎到 一步就没有内容了,输出是 nil。 小小测试后发现竟然页面需要登录,我一直用 lastpass 没注意。。。

ADD

我做了点搜索,需要 COOKIE,以及 session。有一些方法,比如 CGI 和 Watir 之类的。 但是我不知道如何将浏览器里已经登录的 cookie 和 session 导出。然后被 ruby 脚本使用?

#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

# template: http://v.163.com/special/Khan/khstatistics.html
# always find a way to detect and goto upper page.

require 'nokogiri'
require 'open-uri'

page = Nokogiri::HTML(open("http://v.163.com/special/Khan/khstatistics.html"), nil, 'GB2312')

# puts "page"
# p page

# FIXME: the website need login.

ListsTitle = []
ListsDownloadLink = []

page.xpath('//table/tbody').each do |table| # <tbody>
  # puts "table"
  # p table
  table.xpath('//tr[@class="u-even"] | //tr[@class="u-odd"]').each do |list| # <tr class="u-even">
    # <td class="u-ctitle">
    # p list
    list.xpath('//td[@class="u-ctitle"]').each do |title| # <td class="u-ctitle">[第一集]
      # p title
      title.each do |title_name|
        # p title_name
        TitleNamePrefix = title_name.content
        TitleName = title_name.xpath('//a').content
        Title = TitleNamePrefix + TitleName
        ListsTitle << Title
      end
    end
    # <td class="u-cdown">
    list.xpath('//td[@class="u-cdown"]').each do |down|  # <td class="u-cdown"><a href="">
      ListsDownloadLink << down.xpath('//a')['href']
    end
  end
end

puts ListsTitle
puts ListsDownloadLink

这里是我用 firebug 看到的页面的一部分 HTML 源码。

#+BEGIN_SRC html
<table>
  <tbody>
    <th>名称</th>
    <th>下载</th>
    <tr class="u-even">
      <td class="u-ctitle">
        [第一集]
        <a href="http://v.163.com/movie/2011/6/6/0/M82IC6GQU_M83J9IK60.html">均值 中位数 众数</a>
        <img class="isyy" src="http://img1.cache.netease.com/v/2011/1414.png"></img>
      </td>
      <td class="u-cdown">
        <a id="M83J9IK60" class="downbtn" target="_blank" href="http://mov.bn.netease.com/open-movie/nos/mp4/2014/04/08/S9OD1DV40_sd.mp4"></a>
      </td>
    </tr>
    <tr class="u-odd">

    </tr>
    <tr class="u-even">

    </tr>
    <tr class="u-odd">

    </tr>
  </tbody>
</table>
#+END_SRC

既然需要登录,八成都要 cookie 机制。

http://ruby.bastardsbook.com/chapters/mechanize/

https://github.com/sparklemotion/mechanize

require 'rubygems'
require 'mechanize'

a = Mechanize.new
a.get('http://rubyforge.org/') do |page|
  # Click the login link
  login_page = a.click(page.link_with(:text => /Log In/))

  # Submit the login form
  my_page = login_page.form_with(:action => '/account/login.php') do |f|
    f.form_loginname  = ARGV[0]
    f.form_pw         = ARGV[1]
  end.click_button

  my_page.links.each do |link|
    text = link.text.strip
    next unless text.length > 0
    puts text
  end
end

@rubychinaspa Interesting, 我发现了另外一个东东:Watir。效果差不多,正在尝试中。

有没有可能直接从浏览器里导出已经登录后保留的 session cookie 到文件,然后 ruby 脚本引用这个 cookie 文件呢?

cookie 都是有安全机制的。如果导出的可以用,而且在非 browser 端都可以用,那盗号就太容易了。另外,@stardiviner, 现在回帖的这个帐号是个测试通用帐号,此评论来自rubychinaspa 端, 我是@suffering, 很高兴认识你。

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