Ruby 求助: Mechanize 的 form 里面怎么样用 variable 去表示一个 field name ... 表达得不是很清楚,具体见帖子内容

blacktulip · 2012年10月17日 · 最后由 blacktulip 回复于 2012年10月18日 · 2542 次阅读

就是说呢,用 Mechanize 爬网页的时候遇到这样的问题,要提交登录表单,正常代码是这样:比方 bitbucket 吧

a = Mechanize.new
a.get('https://bitbucket.org/') do |page|
  login_page = a.click(page.link_with(text: 'Log In'))

  my_page = login_page.form_with(action: '/account/signin/') do |f|
    f.username = '我的帐号' # 这个 f.username 里面的 'username' 是表单里面对应的 field 名
    f.password = '我的密码' # 这个 f.password 里面的 'password' 是表单里面对应的 field 名
  end.click_button
end

然后把它做成一个 method 的时候,我希望能传进两个参数 username_field_name 和 password_field_name,因为别的登录页面的表单里头的 field 可能不是叫 username 和 password。比如 WordPress 登录表单里面这两个 field 分别叫 log 和 pwd。

那么就是这样子:

# 这个 method 传进去的参数有几个,前面的无关紧要,最后一个 auth_info 是个 Hash ,里面包括表单的地址,两个 field name 和两个 field 里面要填的内容。
def website_login(..., auth_info) 
  a = Mechanize.new
  a.get(auth_info[:login_page_url]) do |page|
    land_page = page.form_with(action: auth_info[:login_form_action]) do |f|
      # 于是以下两句不会写了......
      ????????
      ????????
      # 我试过像以下两句这样,但是不行
      f.instance_variable_set('@'+auth_info[:username_field_name], auth_info[:username])
      f.instance_variable_set('@'+auth_info[:password_field_name], auth_info[:password])
    end.click_button
  end

请问这里应该怎么写才对呢?谢谢。

所有标准的 Form 表单 input 都是有 name 属性的,如果不是那种表单你用 Mechanize 是没法直接搞定的。

Wordpress 表单我清楚,log 和 pwd 是 name 属性么?如果是的话,你也可以直接用 f.log = 'xxx' f.pwd = '' 来赋值的。

#1 楼 @huacnlee 对啊,都有 name 属性,但是各种各样的网站的登录表单里面的 name 属性的值不同。如果代码里面写死了 f.log = 'xxx', f.pwd = 'yyy' 这样的话,遇到 name 属性值是 username 和 password 这样的表单不就不适用了嘛,所以我想不写死,写成类似 f.一个变量 这种形式。

Mechanize 写出来的东西我感觉一般都是一个站一用啊

#3 楼 @huacnlee 谢谢,成功了,写成这个样子。 f.send(auth_info[:username_field_name] + '=', auth_info[:username]) f.send(auth_info[:password_field_name] + '=', auth_info[:password])

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