Python爬虫 - 01.实现贴吧一键签到

作为一名吧友,日常水贴赚经验是必不可少的,同样每天签到水经验也是基操了,为了能快速签到,度娘也是贴心地提供了一键签到的功能,每天上去点一下即可。虽然这个功能很贴心,但是还是要人为操作一下,如果哪天断签了,经验又要重新开始算,所以我打算写一 Python 签到脚本,然后放服务器中每天定时执行一下,实现全自动化签到。

一、分析

贴吧签到有两种方法实现,一是一个吧一个吧地签到,费时费力,二是一键签到,这个不错。一键签到有个限制,每天的0点到1点不能使用的,只能在其他时间段使用,如果想在这个时间段签到,只能一个一个来。当然最简单的操作就是把定时任务设置在1点钟后。

所以,先实现一键签到的功能,后续再实现逐一签到的功能,步骤如下:

  1. 提取接口
  2. 分析接口的请求头,请求参数及响应数据
  3. 编码
  4. 设置定时任务

二、提取接口

打开浏览器,访问 tieba.baidu.com ,登录贴吧
F12打开开发者工具,选择网络标签,先清空一下,排除干扰项
在页面中找到一键签到的按钮,如图

贴吧
点击一键签到,弹出如下窗口

贴吧
点击开始签到,注意观察开发者工具网络标签的变化,啪~ 啪~几下就出现了下面几个请求

开发者工具
后面几个是请求图片文件的,明显不是我们想要的,只有第一个请求,响应类型是json,请求的路径也很明显了,onekeySignin1,所以这个就是目标请求接口了,下面开始分析这个接口的请求数据

三、分析接口

接口
https://tieba.baidu.com/tbmall/onekeySignin1
请求报文

通过开发者工具得到请求报文如下:

POST /tbmall/onekeySignin1 HTTP/1.1
Host: tieba.baidu.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 39
Origin: https://tieba.baidu.com
DNT: 1
Connection: keep-alive
Referer: https://tieba.baidu.com/
Cookie: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Pragma: no-cache
Cache-Control: no-cache

这个请求也没有什么特别的,只要保证几个关键请求头信息即可,如CookieUser-AgentReferer这几个常用的反爬的字段

请求参数

请求参数如下:

ie: "utf-8"
tbs: "ba1c01bc6543721c1xxxxxxxxxx"

这里两个参数,第一个是编码,第二个不知道是啥,这是个关键点。

对于这种不明参数,一般都是两种情况,第一是页面或者JS文件中的隐藏数据,第二种就是通过JS动态生成的加密数据,通常都是先去页面中找,如果能找到那就好办了,如果找不到再去分析JS。

先从页面中找,在开发者工具中点击查看器(Elements),按 Ctrl + F 输入参数名称 tbs 按回车,出来两个结果,第一个是一个空值,按回车选择下一个,发现新大陆,这个参数跟上面的有点像,不,不能说有一点像,简直就是一模一样,这样我们就拿到了tbs这个参数

tbs参数

响应结果

响应正确结果如下:

{
  "no": 0,
  "error": "",
  "data": {
  	// 响应数据
	// ......
	}
}

响应结果肯定有很多种,这里不可能一一列举,而且有一些是很难遇到的,这里只要保证每天第一次签到结果的状态码(no0)和提示不是报错就行,这里列举一两个响应提示

用户已经完成签到的情况

{
  "no": 2280006,
  "error": "forums is signed",
  "data": {
    "signedForumAmount": 1,
    "signedForumAmountFail": 0,
    "unsignedForumAmount": 0,
    "vipExtraSignedForumAmount": 0,
    "forum_list": null,
    "gradeNoVip": 999,
    "gradeVip": 999,
    "lowlev_presign": 1
  }
}

用户没有登录的情况

{
  "no": 1990055,
  "error": "用户没有实名认证",
  "data": ""
}

四、编码

下面开始编码,分以下几个步骤:

  1. 发送请求下载HTML页面
  2. 从HTML中提取tbs参数
  3. 发送请求进行一键签到
  4. 判断响应结果是否正确,打印消息
#!/usr/bin/env python3
#-*- coding: utf-8 -*-
'''
实现百度贴吧一键签到
API: 
一键签到 POST https://tieba.baidu.com/tbmall/onekeySignin1

注意事项:
1、百度贴吧0点到1点是不能够使用一键签到的
'''
__author__ = "Conca"

import requests
import re
from lxml import etree
import time
from datetime import datetime
import os
import json

headers = {
    "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0",
    "Referer": "https://tieba.baidu.com/",
    "Cookie": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", # 替换为你的cookie
}

# 获取页面参数 tbs
def getTbs():
    try:
        tbs = ""
        url = "https://tieba.baidu.com/"

        # 发送请求,下载贴吧HTML页面
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        response.encoding = response.apparent_encoding

        html = response.text
        
        # 用正则表达示从HTML中提取参数 tbs 的值,
        # 正则表达式学得不太好,用得有点呆板,凑合用
        match = re.search(r'PageData.tbs = "(.*)";PageData.is_iPad', html)
        if match:
            tbs = match.group(0).split('"')[1]
        
        return tbs
    except:
        print("获取参数tbs失败")
        return None

# 一键签到
def tiebaOnekeySignin():    

    tbs = getTbs()

    # 获取参数tbs失败则退出签到
    if not tbs:
        print("获取参数tbs失败,签到失败")
        return

    url = "https://tieba.baidu.com/tbmall/onekeySignin1"
    data = {
        "ie": "utf-8",
        "tbs": tbs
    }

    try:
        # 发送请求进行签到
        response = requests.post(url, data=data, headers=headers)
        response.raise_for_status()
        response.encoding = response.apparent_encoding

        # 分析响应结果 
        content = response.json()
        code = content.get("no")

        # 打印提示
        if code == 0:
            print("贴吧一键签到成功")
        elif code == 2280006:
            print("全部吧都已经签过了")
        else:
            print("一键签到失败,请重试")
    except Exception as e:
        print("一键签到发生错误:", e)

def main():
    print("-----------百度贴吧开始签到-------------")

    print("正在执行一键签到……")
    tiebaOnekeySignin()

    print("-----------百度贴吧签到结束-------------")

if __name__ == "__main__":
    main()        

只要把你的cookie替换上面的xxxxx运行即可,有些参数可以自定义,如User-Agent

五、设置定时任务

下面简单介绍一下,放到服务器中让脚本自动运行的操作,以Ubuntu为例子。
前提是服务器中安装了Python环境,相关的库

Cron服务常用命令

这里有个小坑,Ubuntu的服务是cron不是crondCentOScrond

用以下命令启动和停止cron服务:

$ service cron start
$ service cron stop
$ service cron restart
$ service cron reload

查看当前用户的crontab

$ crontab -l

编辑crontab

$ crontab -e

删除crontab

$ crontab -r

查看crontab运行状态

$ service cron status

详细教程:Linux crontab 命令

定时任务

下面开始编辑任务

$ crontab -e

输入

1 1 * * * python3 /home/yourname/tieba_signin.py

意思是每天的凌晨01点01分执行命令python3 /home/yourname/tieba_signin.py

Ctrl+O保存, Ctrl+X 退出就可以了

六、总结

这个脚本虽然简单的实现了一键签到,但还是有很多问题没有考虑进去,比如一键签到是有很多限制的,如7级以下的吧不能签到,一次只能50个,如果关注了超过50个,还有7级以下的吧,那么这个脚本就不太灵了,所以后续要进行逐一签到,把这些坑都填上

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值