BaiduTieba_AutoSign——数据收集篇

之前说要总结签到器的思路,今天就从数据分析开始吧~

由于签到器利用的是模拟浏览器发送http请求,所以第一步肯定是去了解一下每个步骤都要提交什么参数,用的是post还是get方法,返回给用户的又是什么内容。

这里我用的是FireFox + HTTP Header,这个插件可以很轻易地截取浏览器的数据包。

第一步研究登录百度ID的过程。百度2.0标准的登录网址是:https://passport.baidu.com/v2/?login ,在这个网页里面提交用户名和密码,就能够进行登录了。

打开HTTP Header插件,然后进行登录,再返回来看下截获到的数据包。

1

这里登录用的是post方法,上面红色框里面的内容就是我们要提交的数据,看起来还是挺多的= =

在百度上各种乱搜,总算找到了其中必要的参数:

username=
password=
token=
mem_pass=on
safeflg=0
tpl=mn
charset=utf-8
index=0
isPhone=false
loginType=1

下面几项基本上是固定了的,具体是什么意思就不解释了。重点是上面的三个,username、password和token值。username和password很好理解,就是你的用户名和密码。至于token值,是一个随机值,每次登录使用的token都不一样。那么我们从哪里去获取这个值呢?

token其实主要跟你电脑里面cookies有关。每次访问百度的页面时,百度都会在你的PC里存一个cookies,然后这个token值与cookies是相关的。其实百度也提供了一个接口供我们去读取这个值:

https://passport.baidu.com/v2/api/?getapi&class=login&tpl=mn&tangram=false

这里返回的是这样一组数据:

var bdPass=bdPass||{}; 
bdPass.api=bdPass.api||{}; 
bdPass.api.params=bdPass.api.params||{}; 
bdPass.api.params.login_token='fc05aa638b54417093435fcd9b3aeac7'; 
bdPass.api.params.login_tpl='mn'; 
document.write('');

可以看到token值就在其中。这时你可以尝试把你浏览器的cookies清空,然后再次去访问这个网址,就会获得另外一个token值,具体的关系就不研究了。取出token值得方法有很多,我在程序中运用的是正则表达式,毕竟这么短的文本还是很容易去匹配的。

登录的参数我们解决了,那么这个包发出去之后,百度会给我们回复什么呢?

我们所用的插件貌似只给我们返回了一个跳转链接:

/v3Jump.html?err_no=4&callback=parent.bd__pcbs__kvi1nt&needToModifyPassword=0&codeString=&userName=&phoneNumber=&mail=&hao123Param=&u=https://passport.baidu.com/&secState=&gotourl=

这里我们借用python的urllib.request.read(),把返回的具体内容读出来。(部分敏感信息被我用*替换了。。)

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<script type="text/javascript">
var url = encodeURI('https://passport.baidu.com/jump.html?error=0&callback=&index=0&username=lkyghy459&phonenumber=1353*******&mail=li******3.com&tpl=mn&u=https%3A%2F%2Fpassport.baidu.com%2F&needToModifyPassword=0&gotourl=&hao123Param=WlViV3BrWkV4T1dEWkhhRT*******************xSXdTa3RsTWtGNmNYcEpPVlJqYUhsLWIwNVNRVkZCUVVGQkpDUUFBQUFBQUFBQUFBRUFBQUNSYkNvQmJHdDVaMmg1TkRVNUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFISnhYRkZ5Y1Z4UmJH');
//parent.callback(url)
window.location.replace(url);
</script>
</body>
</html>

这个页面实现的是url跳转,而登录成功的标志就在于那个url里面的error这个参数。如果返回是0,那么就是登录成功;如果是其他数值就是没成功,具体参数意义我也不太清楚。。所以在程序里面我们只要抓取error的值就知道登录十分成功了。可以采用正则表达式,也可以用python里面的urllib.parse.urlparse模块分析url。

登录这一步解决了,接下来就是签到这一块。首先来模拟一下签到的方式。(以dota2吧为例子)

2

这里的参数就简单多了:

ie=utf-8
kw=dota2
tbs=47f4f89a9b1162a41365014007

ie这个参数应该是编码的意思,然后kw就是贴吧名字,tbs字面上理解应该是贴吧的session id,跟贴吧有关。虽然它是个变值,每次都不一样,不过可以多次使用,重点是可以直接从该贴吧的源码里面找出来。

3

这里获取tbs的方法就不多说了,跟上面的差不多。

主要来看一下签到返回的数据。贴吧签到返回的内容是json格式(一种类似XML的格式),读起来非常简单,而且python也有json库可以调用。先来看一下成功签到返回的内容:

{
    "no":0,
    "error":"",
    "data":{
            "uinfo":
                    {
                    "is_sign_in":1,
                    "user_sign_rank":79,
                    "sign_time":1364794633,
                    "cont_sign_num":1,
                    "cout_total_sing_num":1
                    },
            "finfo":{
            "forum_info":
                        {
                        "forum_id":975822,
                        "forum_name":"",
                        "level_1_dir_name":"\u53f0\u6e7e\u7535\u89c6\u5267"
                        },
            "current_rank_info":{
                                "sign_count":79
                                },
            "level_1_dir_name":"\u7535\u89c6\u5267",
            "level_2_dir_name":"\u53f0\u6e7e\u7535\u89c6\u5267"
            },
    "sign_version":1}
}

最主要的是no这个参数,如果是0则签到成功,其他代码就是不成功。然后是data.uinfo的内容,is_sign_in:今天是否签到,user_sign_rank:用户签到排名,sign_time:签到时间(这是UNIX标准时间,需要转换),cont_sign_num:连续签到天数,cout_total_sing_num:本月签到天数。其它根据字面意思都挺好理解的。由于这里用的是unicode编码,所以其中的中文需要转码才能正常显示。

接下来是签到失败的其中一种返回内容:

{
    "no":1012,
    "error":"\u670d\u52a1\u5668\u6253\u778c\u7761\u4e86\uff0c\u518d\u7b7e\u4e00\u6b21\u6572\u9192\u5b83",
    "data":""
}

显然这里no是错误代码,至于error里面的内容就是告诉你失败的原因,比如说:签到速度太快,今天已经签到等。

最后来说一下如何去获取用户的“我喜欢的贴吧”列表。我们平时可以从“我的i贴吧”这个页面去获取我喜欢的贴吧列表,其实它们都是以json的格式放在这个页面的代码里面。

4

这里一堆数据看似杂乱无章,但是只要稍微Tab几下,就会看出来这是每个贴吧的详细信息。这里我把其中一两个贴出来:

{
    'is_manager': False, 
    'id': 0, 
    'favo_type': 'favo', 
    'url': '/f?kw=dota2', 
    'feed_item_balv': 
                    {
                        'is_sign': 1, 
                        'is_black': 0, 
                        'forum_name': 'dota2', 
                        'score_left': 26, 
                        'level_name': '放码过来', 
                        'user_id': 19557521, 
                        'is_like': 1, 
                        'level_id': 7, 
                        'cur_score': 474, 
                        'forum_id': 1627732
                    }, 
    'new_feeds_num': 0, 
    'name': 'dota2', 
    'isCustomer': 0
}, 
{
    'is_manager': False, 
    'id': 0, 
    'favo_type': 'favo', 
    'url': '/f?kw=%CD%F5%D0%C4%C1%E8', 
    'feed_item_balv': 
                    {
                        'is_sign': 1, 
                        'is_black': 0, 
                        'forum_name': '王心凌', 
                        'score_left': 11, 
                        'level_name': '凌宝贝', 
                        'user_id': 19557521, 
                        'is_like': 1, 
                        'level_id': 4, 
                        'cur_score': 39, 
                        'forum_id': 28931
                    }, 
    'new_feeds_num': 0, 
    'name': '王心凌', 
    'isCustomer': 0
},

每一个子块里面的name就是贴吧的名字了,这里面还有很多有用的信息,大家就多多挖掘吧~

基本上要获取的信息就是这些了,今天就先写到这,是时候去碎觉了~

« 返回