喵宅苑 MewoGarden × 技术宅社区II | Z站 Z Station 棒棒哒纯文字二次元技术社区

正文

姬宅百度贴吧的自动签到菜鸟脚本教程(二)签到篇

作者:foodszhu
[i=s] 本帖最后由 foodszhu 于 2012-11-21 00:23 编辑 继续前一篇的内容,姬宅百度贴吧的自动签到菜鸟脚本教程(一)登陆篇 (一)准备 其实经过上一篇所讲,签到也是一个类似的过程 这次我们用firefox的firebug插件为例来探究下签到的过程 1.姬宅签到: 因为自己自从写了这个脚本之后就真的自动签到了。。所以新建了一个号来截图。。不过用户组在loading下无法完成签到,不过仍可以登陆进签到中心,来查看提交的表单,跟在主页签到完全一样。进入页面打开firebug,进入网络分页,点击保持按钮保证处于保持状态,然后选好参数,这里我选择不想填写,签到心情是慵懒。单击开始签到 同登陆时一样,是一个post表单,url是https://www.gn00.com/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1&inajax=1,qdmode是签到模式,貌似1是自己填写,3是不想填写,2是什么不清楚,qdxq是签到心情,yl是慵懒。。好吧都是拼音。。 这些都是可以固定下来或者随机选取的。而唯一看似重要的formhash是什么呢?我们打开页面的源代码进行搜索。。 表单处理那发现这么一行[mw_shl_code=html,true]<form id="qiandao" method="post" action="plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1"> <input type="hidden" name="formhash" value="05bdef8b">[/mw_shl_code] 明显为我们所需。。在登陆的基础上,签到明显是个简单活动 2.贴吧签到 以bilibili吧为例 登陆bilibili吧,单击签到, 也是post表单,url为http://tieba.baidu.com/sign/add,三个参数也十分简单 ie估计是编码格式,kw为贴吧名称,tbs估计为贴吧的代码,打开源代码进行搜索 [mw_shl_code=html,true]<script> PageData.tbs = "483101895300e4521353410592";[/mw_shl_code] 可查到这么一行,说明tbs也可从本页面直接获取。 需要注意的是,中文贴吧名在转化为url时,必须是由gbk码转换成url。才能正常访问 把所需要的数据放在qiaodao.ini中方便读取 [mw_shl_code=text,true]#qiandao.ini [技术宅] url=https://www.gn00.com qiandao_url=https://www.gn00.com/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1&sign_as=1&inajax=1 fastreply=0 formhash= qdmode=3 qdxq=fd todaysay= [百度] url=http://www.baidu.com qiandao_url=http://tieba.baidu.com/sign/add ie=utf-8 kw= tbs=[/mw_shl_code] 不过单纯一个贴吧的签到当然无法满足我们,我们要尝试下签到所有喜欢的贴吧,第一步,就要找出自己的喜爱的贴吧。 这里我提供两种方案 1.通过http://www.baidu.com/p/用户名?from=tieba进入到百度个人主页的我在贴吧子页,从中获取我最喜爱的吧。 2.在登陆状态下,通过http://tieba.baidu.com/i/sys/enter?ie=utf-8&kw=用户名进入到个人的i贴吧,从中提取我爱逛的贴吧。 具体操作稍后再讲 相比登陆方面,签到简直是没有任何难度。。。所以我们就要在脚本上下点功夫了
(二)脚本 先上总脚本,这个签到本来是一件非常简单的事,但是不比登陆,我们往往需要获得一些签到返回的信息,所以对返回信息稍作处理 [mw_shl_code=python,true]#!/usr/bin/env python # -*- coding: utf-8 -*- # # qiandao.py import login,re,urllib,urllib2,json,threading import ConfigParser as cp class Qiandao(login.Login): def __init__(self,name): super(Qiandao,self).__init__(name) self.loadIni('qiandao.ini',name,self.data,'url','qiandao_url') def qiandao(self): data = urllib.urlencode(self.data) req = urllib2.Request(self.qiandao_url,data,self.headers) response = self.opener.open(req) self.qiandao_response=response self.qiandao_response_read=response.read().decode('utf-8') return self.qiandao_response_read class TiebaQiandao(Qiandao,login.BaiduLogin): def __init__(self,name='百度'): self.result_list={u'cont_sign_num':u'连续签到天数', u'cout_total_sing_num':u'本月累计签到天数',u'user_sign_rank':u'个人签到排名',u'tieba_name':u'贴吧'} super(TiebaQiandao,self).__init__(name) def getTiebaKw(self,name): return urllib2.quote(name.decode('utf-8').encode('gbk')) def getTiebaTbs(self,name): url='http://tieba.baidu.com/f?kw='+self.getTiebaKw(name) buf=self.opener.open(url).read() s=r'PageData.tbs = \"(\w+)\"' t=re.findall(s,buf)[0] return t def qiandao(self,tieba_name): self.setData(kw=tieba_name,tbs=self.getTiebaTbs(tieba_name)) response=super(TiebaQiandao,self).qiandao() return tieba_name,response def qiandaoAll(self,*except_list): self.qiandao_response_list=[self.qiandao(item) for item in self.getAllTiebaList() if item not in except_list] return self.qiandao_response_list def getAllTiebaList(self): #url='http://www.baidu.com/p/%s?from=tieba' % self.getTiebaKw(self.data['username']) #r=r'target=_blank title=\\x22(.*?)\\x22' #for i,v in enumerate(l): # l=v.rstrip('\xe5\x90\xa7') #return l url='http://tieba.baidu.com/i/sys/enter?ie=utf-8&kw=%s' % self.getTiebaKw(self.data['username']) r=r'\$_likeForum=(.*?);' buf=self.opener.open(url).read() l=re.findall(r,buf)[0] j=json.loads(l) l=[] for i in j: l.append(i['name'].encode('utf-8')) print i['name'].encode('utf-8') return l def analyseQiandaoResult(self,tieba_name,response): result=json.loads(response) no=result['no'] error=result['error'] if no == 0: result=result['data']['uinfo'] result[u'tieba_name']=tieba_name.decode('utf-8') else: result=tieba_name,error return no,result def printQiandaoResult(self,no,result): if no == 0: for key,value in self.result_list.items(): print "%s : %s" %(value,result[key]) else: print "贴吧 : %s" %result[0] print '签到失败 : %s'%result[1].encode('utf-8') print '' class JishuzhaiQiandao(Qiandao,login.JishuzhaiLogin): def __init__(self,name='技术宅'): super(JishuzhaiQiandao,self).__init__(name) def getFormHash(self): buf=self.opener.open(self.url).read().decode('utf-8') r=r'formhash=\w+' s=re.findall(r,buf)[0].split('=')[1] return s def qiandao(self): self.setData(formhash=self.getFormHash()) response = super(JishuzhaiQiandao,self).qiandao() return response def analyseQiandaoResult(self): r=r'<div class="c">\r\n(.*?) </div>' result=re.findall(r,self.qiandao_response_read)[0] if u'成功' in result: no=0 else: no=1 return no,result def printQiandaoResult(self): no,result=self.analyseQiandaoResult() print '技术宅社区:' if no == 0: print '签到成功:' else: print '签到失败:' print result print '' def main(name): if name=='技术宅': website=JishuzhaiQiandao() website.login() website.qiandao() website.printQiandaoResult() elif name=='百度': tieba_name=raw_input("输入您想签到的贴吧名称(如果想签到所有喜欢贴吧请打all):").lower() website=TiebaQiandao() website.login() if tieba_name != 'all': website.printQiandaoResult(*website.analyseQiandaoResult(*website.qiandao(tieba_name))) else: response_list=website.qiandaoAll() for item in response_list: website.printQiandaoResult(*website.analyseQiandaoResult(*item)) else: print '没有填写配置文件!' return 1 return 0 if __name__ == '__main__': name=raw_input('输入您想登陆的网站名称(确保您已填写配置文件):') main(name) [/mw_shl_code] [mw_shl_code=python,true]import login,re,urllib,urllib2,json import ConfigParser as cp[/mw_shl_code] 依旧是首先引入模块,这里需要引入上篇我们写的登陆模块。。 [mw_shl_code=python,true]class Qiandao(login.Login): def __init__(self,name): super(Qiandao,self).__init__(name) self.loadIni('qiandao.ini',name,self.data,'url','qiandao_url') def qiandao(self): data = urllib.urlencode(self.data) req = urllib2.Request(self.qiandao_url,data,self.headers) response = self.opener.open(req) self.qiandao_response=response self.qiandao_response_read=response.read().decode('utf-8') return self.qiandao_response_read[/mw_shl_code] 同样是先构造签到的基类,由于签到是基于登陆完成,且两者有很多共同之处,所以将Login类设为Qiandao类的基类,可以省下很多操作 初始化时多一步读取qiandao.ini的内容作为表单值。 定义新的方法qiandao作为签到的实际做法,不过跟登陆的做法极为类似,只是换掉了登陆的url而已,不过这个qiandao必须在已登陆的前提下再进行签到。 [mw_shl_code=python,true]class TiebaQiandao(Qiandao,login.BaiduLogin): def __init__(self,name='百度'): self.result_list={u'cont_sign_num':u'连续签到天数', u'cout_total_sing_num':u'本月累计签到天数',u'user_sign_rank':u'个人签到排名',u'tieba_name':u'贴吧'} super(TiebaQiandao,self).__init__(name) def getTiebaKw(self,name): return urllib2.quote(name.decode('utf-8').encode('gbk')) def getTiebaTbs(self,name): url='http://tieba.baidu.com/f?kw='+self.getTiebaKw(name) buf=self.opener.open(url).read() s=r'PageData.tbs = \"(\w+)\"' t=re.findall(s,buf)[0] return t def qiandao(self,tieba_name): self.setData(kw=tieba_name,tbs=self.getTiebaTbs(tieba_name)) response=super(TiebaQiandao,self).qiandao() return tieba_name,response def qiandaoAll(self,*except_list): self.qiandao_response_list=[self.qiandao(item) for item in self.getAllTiebaList() if item not in except_list] return self.qiandao_response_list def getAllTiebaList(self): #url='http://www.baidu.com/p/%s?from=tieba' % self.getTiebaKw(self.data['username']) #r=r'target=_blank title=\\x22(.*?)\\x22' #for i,v in enumerate(l): # l=v.rstrip('\xe5\x90\xa7') #return l url='http://tieba.baidu.com/i/sys/enter?ie=utf-8&kw=%s' % self.getTiebaKw(self.data['username']) r=r'\$_likeForum=(.*?);' buf=self.opener.open(url).read() l=re.findall(r,buf)[0] j=json.loads(l) l=[] for i in j: l.append(i['name'].encode('utf-8')) print i['name'].encode('utf-8') return l def analyseQiandaoResult(self,tieba_name,response): result=json.loads(response) no=result['no'] error=result['error'] if no == 0: result=result['data']['uinfo'] result[u'tieba_name']=tieba_name.decode('utf-8') else: result=tieba_name,error return no,result def printQiandaoResult(self,no,result): if no == 0: for key,value in self.result_list.items(): print "%s : %s" %(value,result[key]) else: print "贴吧 : %s" %result[0] print '签到失败 : %s'%result[1].encode('utf-8') print '' [/mw_shl_code] 当签到的基类构造好时我们就要构造下一步的子类了,但是在登陆基类我们已经派生出两个子类BaiduLogin和JishuzhaiLogin,来分别处理百度与姬宅的登陆,所以我们既需要从登陆的两个子类中继承需要的功能,又需要从签到基类中继承所需要的功能,所以我们采用多继承的方法。 在我们的TiebaQiandao类中,我们既继承了BaiduLogin类,又继承了Qiandao类,为了防止共同父类方法的多次调用,我们采用super来调用父类的方法。 super是采用mro方式处理多继承中共同方法的多次调用的问题的,所以为了运行良好,我们必须将所有的调用父类的形式都改为super 同时,由于新型类中,mro顺序是广度优先的,所以同层间的相同方法最好使用相同的参数个数,否则就可能报错,而且达不到我们想要的结果。关于这部分的讨论,搜索一下python的多继承 [mw_shl_code=python,true]def getTiebaKw(self,name): return urllib2.quote(name.decode('utf-8').encode('gbk')) def getTiebaTbs(self,name): url='http://tieba.baidu.com/f?kw='+self.getTiebaKw(name) buf=self.opener.open(url).read() s=r'PageData.tbs = \"(\w+)\"' t=re.findall(s,buf)[0] return t[/mw_shl_code] 这两个函数是为了得到签到的表单项之一的tbs,我们从该贴吧的页面中获取信息,所以得先进入这个贴吧, 而贴吧url形式为http://tieba.baidu.com/f?kw=贴吧名,当然贴吧名需要处理为url能识别的形式,而且得从gbk码转换而来,由于我编码的统一为utf-8,所以要做进一步转换 同样用正则表达式将tbs挑捡出来 [mw_shl_code=python,true]def getAllTiebaList(self): #url='http://www.baidu.com/p/%s?from=tieba' % self.getTiebaKw(self.data['username']) #r=r'target=_blank title=\\x22(.*?)\\x22' #for i,v in enumerate(l): # l=v.rstrip('\xe5\x90\xa7') #return l url='http://tieba.baidu.com/i/sys/enter?ie=utf-8&kw=%s' % self.getTiebaKw(self.data['username']) r=r'\$_likeForum=(.*?);' buf=self.opener.open(url).read() l=re.findall(r,buf)[0] j=json.loads(l) l=[i['name'].encode('utf-8') for i in j] return l[/mw_shl_code] getAllTiebaList是获取喜爱贴吧的方法,其中我注释的部分是我在准备篇中所说的第一种方法,即进入到个人主页中提取。。其中包含在target=_blank title=后面的即是贴吧名,不过后面多了一个吧字,在这里我们用rstrip将其消掉,字符串rstrip方法用于消去共同后缀,rstrip消去共同前缀,使用默认参数时消去空格 第二种方法,即在登陆前提下,进入个人的i贴吧,从中获取贴吧信息,而这个部分信息较为混杂,我们仔细查看,发现在响应的末尾有一组以脚本形式存储的信息,以$_likeForum开头的数据 我们先用re模块将字符串提取出来,注意$需要转义所以加\,然后用json模块将字串转化为我们能够直接用的对象,在这里面会生成一组列表,列表中每一项都是一个字典,包括了爱逛的贴吧的信息,这里我们暂且只用name这一对键值,同时用了列表推导的技巧生成了这个列表 [mw_shl_code=python,true]def qiandao(self,tieba_name): self.setData(kw=tieba_name,tbs=self.getTiebaTbs(tieba_name)) response=super(TiebaQiandao,self).qiandao() return tieba_name,response[/mw_shl_code] qiandao方法是对父类的签到方法的具体实现,对于贴吧签到而言,我们不仅需要登陆百度,而且还需要知道所要签到的贴吧名,在加上贴吧的tbs后,发送表单完成签到 同时返回贴吧名与响应的元组 [mw_shl_code=python,true]def analyseQiandaoResult(self,tieba_name,response): result=json.loads(response) no=result['no'] error=result['error'] if no == 0: result=result['data']['uinfo'] result[u'tieba_name']=tieba_name.decode('utf-8') else: result=tieba_name,error return no,result[/mw_shl_code] analyseQiandaoResult方法正是为了分析qiandao方法返回响应的方法,它所需参数正好是签到返回的结果,而这个响应结果,直接是以json形式存储的,所以我们可以用json模块直接提取出来,其中no是返回代码,0即登陆成功,1101代表已经登陆,1007代表今天签到次数超过100次,error即错误说明。 如果签到成功,响应中data对应值即是一些个人排名啊,贴吧排名,贴吧目录等项,uinfo代表个人信息,我们这里只取个人信息保存。最终返回响应代码与一个打包好的字典作为返回结果 [mw_shl_code=python,true]def printQiandaoResult(self,no,result): if no == 0: for key,value in self.result_list.items(): print "%s : %s" %(value,result[key]) else: print "贴吧 : %s" %result[0] print '签到失败 : %s'%result[1].encode('utf-8') print ''[/mw_shl_code] 从分析结果中我们最终打印出我们需要的结果。。这块就不多说了。 [mw_shl_code=python,true]def qiandaoAll(self,*except_list): self.qiandao_response_list=[self.qiandao(item) for item in self.getAllTiebaList() if item not in except_list] return self.qiandao_response_list[/mw_shl_code] qiandaoAll方法用于签到所有爱逛的贴吧,参数中except_list用于设定无需签到的贴吧,这里其实可以用多线程,不过仔细想想还是觉得略麻烦而且在gae上部署也很麻烦多以就放弃了 姬宅的签到与贴吧签到类似,只需要加上一个formhash即可提交。当然两者都需要先login,再qiandao
最后我们就可以来个一键签到了 [mw_shl_code=python,true]#!/usr/bin/env python # -*- coding: utf-8 -*- # # 一键签到.py # import qiandao,os def main(): jishuzhai=qiandao.JishuzhaiQiandao() baidu=qiandao.TiebaQiandao() jishuzhai.login() baidu.login() jishuzhai.qiandao() jishuzhai.printQiandaoResult() response_list=baidu.qiandaoAll() for item in response_list: baidu.printQiandaoResult(*baidu.analyseQiandaoResult(*item)) return 0 if __name__ == '__main__': main()[/mw_shl_code] 将这个代码文件设为可执行,需要签到时运行即可
自动签到的主体部分就到此结束了。。。 下来一篇就是将如何将这个脚本部署在gae上,并且用计划任务在12点附近进行签到。。。不过gae要求只能有最多30s的响应时间所以12点刚过那阵贴吧签到各种Deadline exceeded。。。。几乎到快到20才能勉强签上。。不知为何。。暂时也没有用多线程。。难道只有用多线程才能改进一下么 恩恩。。下一篇就是部署到gae上,并进行少量优化
发帖果然理会的人不多啊。。。而且自己话也说不太清楚。。。自己第一次写教程也请各位见谅。。 再。。求发糖#18t

回复

最近在做自动签到的应用玩

作者:破晓0123
最近在做自动签到的应用玩,受教了~ 另外顺便说下,技术宅网的签到真心好做....
查看回复

谢谢楼主啊

作者:小辉~
O(∩_∩)O谢谢楼主啊!
查看回复

淡淡滋味回复给帖子:7676654

作者:淡淡滋味
略犀利
查看回复

以前做过

作者:饭尐盒
以前做过post登陆,签到的还是爪机+1经验的。脚本一窍不通~一点看不懂但是还是支持o(*////▽////*)q
查看回复

stonegarlic回复给帖子:7676654

作者:stonegarlic
好长啊。。。。。
查看回复

话说大神您每天几乎都是第一个签到没问题么

作者:akira_ou
foodszhu 发表于 2013-4-2 16:02 受教了。。。话说大神您每天几乎都是第一个签到没问题么。。。
@ou#手動無壓力→_→
查看回复

簽到模式的

作者:foodszhu
akira_ou 发表于 2013-4-2 15:57 簽到模式的2是快速選擇,,社區沒搞出來所以沒顯示,,但是也是能用的 ...
受教了。。。话说大神您每天几乎都是第一个签到没问题么。。。
查看回复

簽到模式的

作者:akira_ou
@ou#簽到模式的2是快速選擇,,社區沒搞出來所以沒顯示,,但是也是能用的
查看回复
上一页
下一页
0%
站点地图友情链接:
喵宅苑
喵空间社区程序
喵宅苑 静态版
宅喵RPG地图编辑器
络合兔
Lanzainc
技术宅
小五四博客
莉可POI
Mithril.js
枫の主题社
Project1
午后少年
机智库
七濑胡桃
xiuno
幻想の日常
魂研社
Nothentai
0xffff
欲望之花
泽泽社长
淀粉月刊
HAYOU