首先我们使用python写一个脚本对扣丁学堂进行签到请求,要进行请求肯定要知道请求的是post还是GET。

好的那么我们打开浏览器,进入扣丁学堂个人主页,这里有一个签到按钮,每天点击签到即可获得一个丁豆,可以用来买课,我们先不要点击签到,因为点击了签到后就不可以再次点击了,签到过后就会显示已签到,就无法完成抓包请求了。那么我们先打开浏览器的开发者模式,也就是浏览器的F12健,切换到network模式,然后再点击签到按钮,这时候再看network里面就有一个网址

network

然后我们点进去,在进headers里面,可以看到网页刚刚发送的请求头信息,可以看到刚刚发送的请求是GET请求,请求网址是:http://www.codingke.com/my/sign?r=0.025347213714072003,我们且不看后面的参数r=0.025347213714072003,因为我们也不知道这是啥,那么我们把它删除,然后再看一下删除了参数的网址:http://www.codingke.com/my/sign,因为是GET请求,所以我们可以把这个网址直接放在浏览器的地址栏回车发送出去,然后看看会出现什么样的结果

image-20210318192437075

发现返回了一个json,然后内容是今天已经签到过了,所以,我们就可以得出,

http://www.codingke.com/my/sign就是我们要找的签到地址,那么意思就是直接写一个代码发送GET请求就完了呗,那我们应该怎样发送呢?这里可以有两种方法,一种是cookie,一种是发送账号密码登录后再进行签到请求,我们都知道只要带着cookie发送请求就可以跳过账号密码请求页面,那么我们可以来编写一个python代码来试一下。

很简单,因为只要发送简单的GET请求,所以我们只需要写一个GET请求的python代码,如下

import requests

# 要请求的网址
url = 'http://www.codingke.com/my/sign'
header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/89.0.4389.90 Safari/537.36 ',
    'Cookie': '填你的cookie'
}
r = requests.get(url, headers=header)
print(r.text)

cookie可以到扣丁学堂首页按F12抓到GET请求查看请求头即可,执行代码后返回到结果如下:

{"success":"今天已经签到过了","code":2}
进程已结束,退出代码为 0

可以看到,我们成功的进行了请求,并且返回了正确的数据,但是这个方法等到第二天我再去看的时候显示请求失败了,这是为什么呢,我们再回浏览器登录扣丁学堂,发现扣丁学堂的登录状态已经退出了,使用cookie登录的确是一个不长久的办法,但是没想到扣丁学堂的cokkie只能保持很短的一段时间。那么我们只能用第二种方法了,那就是使用账号密码进行登录,幸运的是扣丁学堂的登录方式并没有设置验证码,也为我们写脚本省了不少时间。

那么我们对扣丁学堂的登录界面进行发送请求,那么首先我们要知道扣丁学堂的登录网址,那么我们在扣丁学堂的首页把鼠标放到我们的头像上,点击安全退出。

loginOut

然后我们就可以发现我们成功的来到了扣丁学堂的登录页面

loginkouding

然后浏览器的地址栏有一个地址:http://www.codingke.com/login,这就是我们要找的扣丁学堂登录地址了,那么我们要对扣丁学堂发送登录请求,我们可以用Fiddler来查看扣丁发送的请求,为什么不用谷歌的F12呢,也是可以的,但是我们按F12查看扣丁学堂的network请求后发现他有一个请求转发,页面进行了跳转后network页面就会自动刷新,而且很快,你要点击停止的话很难来得及,所以我们就使用这款Fiddler抓包工具来查看请求,这样就不会漏掉我们想要的数据了。我们先打开Fiddler软件,然后我们点击开始,就可以去浏览器里输入账号密码了,输入完账号密码之后我们发现有一个登录请求地址是http://www.codingke.com/login_check的发送了我们账号和密码的字段

fillder

在Fiddler中我们可以清楚的看到发送的字段名是_username和_passsword还有一个不知道是什么的一串字符串,我们暂且忽略掉最后一个,前两个我们可以一眼看出就是我们的账号和密码,就算看不出来看后面的值也可以知道就是我们刚刚手动输入的账号密码,不信你再试一遍看看。那么我们就知道要发送这两个字段去给服务器,那么我们编写代码如下:

import requests

# 要请求的网址
url = 'http://www.codingke.com/login_check'
header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/89.0.4389.90 Safari/537.36 ',
    'Cookie': 'UM_distinctid=178450d263e148-0bac1bb3c67232-5771031-162ee1-178450d2641c1; '
              'CNZZDATA1256018185=436213958-1616065336-null%7C1616065336; '
              'Hm_lvt_7d5fe787f1dd300413ad4b53656dc0b1=1616066193; 53gid2=10074621437020; 53gid0=10074621437020; '
              '53gid1=10074621437020; 53revisit=1616066205585; 53kf_72165667_from_host=www.codingke.com; '
              '53kf_72165667_keyword=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DF-cUml-NIKj2oF5LBx2zwBm'
              '-hL1jGE_tuUOhOpqqeQws6TYAghf7oR-wJIDAaZc3%26wd%3D%26eqid%3Dd2f2fed900005682000000066053368a; '
              '53kf_72165667_land_page=http%253A%252F%252Fwww.codingke.com%252F; kf_72165667_land_page_ok=1; '
              '53uvid=1; onliner_zdfq72165667=0; Invite_code=375108; visitor_type=old; '
              'PHPSESSID=n6tj5epaajuicg1912p5dd7572; tgw_l7_route=1da6220a8c6aee8fae7fcb8ec6e1299a; '
              'Hm_lpvt_7d5fe787f1dd300413ad4b53656dc0b1=1616070611 ',
    '_username': '你的账号',
    '_password': '你的密码'
}
r = requests.post(url, headers=header)
print(r.text)

但是运行过后我们通过输出结果可以看到,并没有登录,还是停在登录的界面,所以我们用Fiddler尝试一下,是不是我们缺少了其他的字段值就请求不成功呢。

于是我们对每一次的请求都进行修改,先把最后一个不知道是什么的字符串删除,结果请求成功,我们再把其他的请求头中的字段一一删除,但是每次不管是删除哪一个都返回一个错误,也就是说我们必须保证字段的完整性再发送请求即可,那么我们怎么才能获取到这么多的字段值呢?获取到了又该怎么保存,重新发送请求的话之前的请求获取的字段就会失效。那么这时候就要请出我们的Session了,Session可以保持我们在同一个窗口下进行请求,也就是说你所有的请求都是基于同一页面的,所以数据一般不会发生改变,那么我们就可以进行操作了

经过不断的尝试我们可以发现,字段中那个不知道是干嘛的字符串在login界面也有存在,我们按F12来查看一下

loginmeta

而且不止这一处,再往下找找发现还有一处隐藏起来的input标签里也有相同的字段

inputkouding

那么我们只要可以获取其中一处的值就可以了,然后其他的字段值因为都是固定的所以我们可以写成常量,那么我们就可以编写如下python代码

# -*- coding: utf8 -*-
import requests
import re
session = requests.Session()
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                'Chrome/89.0.4389.82 '
                'Safari/537.36 '
}
res = session.get('http://www.codingke.com/login', headers=headers)
pattern = re.compile('name="_csrf_token" value="(.*)"')
token = pattern.search(res.text)[1]
data = {
    '_username': '你的账号(手机号)',
    '_password': '你的密码',
    '_csrf_token': token,
    'Host': 'www.codingke.com',
    'Proxy-Connection': 'keep-alive',
    'Content-Length': '95',
    'Accept': '*/*',
    'X-CSRF-Token': token,
    'X-Requested-With': 'XMLHttpRequest',
    'User-Agent': headers['User-Agent'],
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
    'Origin': 'http://www.codingke.com',
    'Referer': 'http://www.codingke.com/login',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'zh-CN,zh;q=0.9'
}
resp = session.post("http://www.codingke.com/login_check", data=data)
try:
        response = session.get("http://www.codingke.com/my/sign", headers=headers)
        rJson = response.json()
        if rJson['code']==1:
            print('签到成功')
        elif rJson['code']==2:
            print('已经签到过了')
except:
        print('账号或密码错误')

这里使用了正则表达式去匹配input当中的字符串值,然后发送post登录请求,再使用session在同一窗口下去请求签到页面,因为签到页面返回一个json,所以我们直接接收json类型的数据再进行判断,如果异常也就是没有返回json就是登录失败了

最后再提供一个云函数的版本,一天白嫖一个豆,一百天就可以免费买一套课程啦

腾讯云函数版本:

# -*- coding: utf8 -*-
import requests
import re


def main_handler(event, context):
    session = requests.Session()
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/89.0.4389.82 '
                      'Safari/537.36 '
    }
    res = session.get('http://www.codingke.com/login', headers=headers)
    pattern = re.compile('name="_csrf_token" value="(.*)"')
    token = pattern.search(res.text)[1]
    data = {
        '_username': '你的手机号',
        '_password': '你的密码',
        '_csrf_token': token,
        'Host': 'www.codingke.com',
        'Proxy-Connection': 'keep-alive',
        'Content-Length': '95',
        'Accept': '*/*',
        'X-CSRF-Token': token,
        'X-Requested-With': 'XMLHttpRequest',
        'User-Agent': headers['User-Agent'],
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'Origin': 'http://www.codingke.com',
        'Referer': 'http://www.codingke.com/login',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-CN,zh;q=0.9'
    }
    resp = session.post("http://www.codingke.com/login_check", data=data)
    try:
        response = session.get("http://www.codingke.com/my/sign", headers=headers)
        rJson = response.json()
        if rJson['code'] == 1:
            print('签到成功')
        elif rJson['code'] == 2:
            print('已经签到过了')
    except:
        print('账号或密码错误')