使用Python自动签到V2EX

V2EX是我经常登录的一个社区,里面有很多做开发的小伙伴.这个网站每天有个签到功能,作为一个潜水党,每天和网站的交互,第一件事情就是签到,但是每天手动签到好麻烦,github上面搜到一个脚本,简单解析一下.

脚本地址

V2EX自动签到,不是我写的,感谢脚本作者,感谢开源社区,让大家有更多学习交流的机会

登陆签到流程

首先熟悉一下V站的登陆流程:

  1. 首先获取网站的cookie;
  2. 然后通过cookie获取每日任务页面的once;
  3. 如果once不为空,则是没有签到,执行签到操作;
  4. 反之退出程序

一顿操作

根据以上流程,首先获取cookie,在脚本的readme文件里面,有说明,V站之前是采用auth方式登录,现在是采用A2.
在浏览器中打开网址主页,我使用的Safari,右键->检查元素->存储空间->Cookie-www.v2ex.com,找到A2列,复制出来所在列的字符串.
解析A2,以示例中的A2为例:

2|1:0|10:1415406915|2:A2|56:xxxxxx|uuuuuu

我们需要的值,就是56:后面的字符串,它是cookie的base64编码之后的值,进行base64解码,简单的,可以使用终端:

1
echo 'xxxxxx|uuuuuu' |base64 -D;echo

得到cookie

源码解读

源码还是比较简单的,思路很清晰,也没有使用第三方的模块,使用的都是系统自带的模块,适合新手学习.
源码引入了sys,re,cookitlib,urllib2这几个模块,下面都会使用到这几个Python中经常使用的模块.
前面几行,定义了一些全局变量,分别用于存储cookie和URL,没什么好说的.需要说明,在Python中,为防止正则表达式和\(比如网址中)冲突,会在字符穿前面加上r,告诉编译器这个string是raw string,无需转义:

1
V2EX_DOMAIN = r'v2ex.com'

接下来是两个自定义方法和一个程序入口方法:
根据上面的签到流程,获取cookie之后,获取once,然后验证once是否为空;
第一个get_onec_url(data)就是用来获取once,第二个make_cookit(name, value)是生成cookie,是每次请求都需要携带的信息;
暂时跳过这两个函数的内部实现,先看入口函数,if __name__ == '__main__':用于判断运行的是不是当前文件,这里有个介绍,单文件程序就这么写好了.
入口函数代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if __name__ == '__main__':
cj = cookielib.CookieJar()
cj.set_cookie(make_cookie('auth', V2EX_COOKIE))
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
opener.addheaders = [
('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; rv:20.0) Gecko/20100101 Firefox/20.0'),
('Referer', V2EX_MISSION)
]
opener.open(V2EX_URL_START).read()
data = opener.open(V2EX_MISSION).read()
once = get_once_url(data)
if None == once:
print '"once" not found, maybe you already got coins'
sys.exit(-1)
v2ex_coin_url = V2EX_URL_START + once
print v2ex_coin_url
opener.open(v2ex_coin_url).read()

使用cookielib.CookieJar()生成一个jar,然后调用set_cookie(),里面接受参数,我们填写字段名auth,值填写为全局变量V2EX_COOKIE即我们从浏览器中获取的cookie,设置好jar之后,使用urllib2手动生成一个opener,这个对象可以进行网页数据的读取.访问V2EX需要User-Agent,这个写死就好了.通过opener读取数据,然后调用get_once_url(),获取once,Python中判读是否为空需要和None进行比较,如果为空,可能已经签到成功过了,调用sys.exit(-1)退出程序,否则,使用获取到的once值访问签到页面,成功签到.
回头看两个自定义函数,make_cookie,比较简单,有两个参数,一个name,一个value,用于设置cookie的name和value,返回值第通过cookielie.Cookie生成的一个字典,这个比较简单.
在看get_once_url,参数是网页获取的数据,然后通过正则表达式,匹配出来/mission/daily/redeem\?once=\d+,具体方法是re.search(p,data),作为对比,re.match()是从开头匹配结果,re.search()则是全字符串进行匹配,返回match object对象,我们取第一个结果,调用返回对象的group()方法即可.
至此,既可以完成自动签到功能.

用到模块方法总结

自动签到功能主要用到的函数有

  1. cookielib里面生成cookie的方法
  2. urllib2生成opener的方法及相关方法
  3. openeropen()以及read()方法
  4. re模块的search()相关对象方法
  5. sys模块的exit()方法