Skip to content

Instantly share code, notes, and snippets.

@francistm
Last active October 19, 2015 08:01
Show Gist options
  • Save francistm/87e89b4c7e645cedada5 to your computer and use it in GitHub Desktop.
Save francistm/87e89b4c7e645cedada5 to your computer and use it in GitHub Desktop.
yiichina.com 自动签到脚本

YiiChina 自动签到脚本

依赖

  • Ruby 2.1+
  • Bundler
  • Nokogiri
  • HTTParty

用法

  1. # bundle install
  2. # bundle exec ruby ./registration.rb <username> <password>
  3. 调用时,用户名和密码也可以通过系统变量传递,例如:
    # USERNAME=<username> PASSWORD=<password> bundle exec ruby ./registration.rb
source 'https://rubygems.org/'
gem 'httparty', '~> 0.13.7'
gem 'nokogiri', '~> 1.6.6.2'
require 'logger'
require 'nokogiri'
require 'httparty'
class Object
def blank?
respond_to?(:empty?) ? !!empty? : !self
end
def present?
!blank?
end
def presence
self if present?
end
end
class YiiChina
include HTTParty
base_uri 'www.yiichina.com'
def initialize(username:, password:)
@csrf_token = nil
@identity_cookie = nil
@username, @password = username, password
@user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0'.freeze
raise ArgumentError.new('User identity isn\'t correct') if @username.blank? || @password.blank?
end
def login
raise 'Already logged in' unless @identity_cookie.nil?
login_get_resp = self.class.get('/login', headers: { 'User-Agent' => @user_agent })
login_form_html = Nokogiri::HTML(login_get_resp.body)
csrf_meta_param_tag = login_form_html.at_css('meta[name="csrf-param"]').freeze
csrf_meta_token_tag = login_form_html.at_css('meta[name="csrf-token"]').freeze
login_get_req_cookie = parse_set_cookies(login_get_resp.headers['Set-Cookie'])
login_post_resp = self.class.post('/login', {
follow_redirects: false,
headers: {
'User-Agent' => @user_agent,
'Cookie' => login_get_req_cookie.to_cookie_string
},
body: {
'LoginForm' => {
'rememberMe' => '0',
'username' => @username,
'password' => @password,
},
csrf_meta_param_tag['content'] => csrf_meta_token_tag['content'],
},
})
case login_post_resp.code
when 302
@csrf_token = csrf_meta_token_tag['content']
@identity_cookie = parse_set_cookies(login_post_resp.headers['Set-Cookie'])
return true
when 200
raise 'Username or Password might not match'
else
raise 'Unknown login exception'
end
end
def registration
raise 'Not loggin yet' if @identity_cookie.nil?
reg_resp = self.class.get('/registration', {
follow_redirects: false,
headers: {
'User-Agent' => @user_agent,
'X-CSRF-Token' => @csrf_token,
'X-Requested-With' => 'XMLHttpRequest',
'Cookie' => @identity_cookie.to_cookie_string,
'Accept' => 'application/json, text/javascript, */*; q=0.01',
},
})
case reg_resp.code
when 200
logger.info 'Registration succeed today'
when 500
logger.info 'Registration failed, might already done'
end
end
private
def logger
@logger ||= ::Logger.new(STDOUT)
end
def parse_set_cookies(set_cookie)
cookie_hash = CookieHash.new
set_cookie.split(', ').each { |c| cookie_hash.add_cookies(c) }
cookie_hash
end
end
if __FILE__ == $0
user_identity = {}.tap do |identity|
identity[:username] = ENV['USERNAME'].presence || ARGV[0]
identity[:password] = ENV['PASSWORD'].presence || ARGV[1]
end
site = YiiChina.new user_identity
site.registration if site.login
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment