当前位置: 首页 > article >正文

Python:百度贴吧实现自动化签到

早知道,还是python。

Github项目仓库在这。

相关API

签到+贴吧列表

签到分为两个接口,PC端签到一次经验+2,而移动端签到则是一次经验+6。该用哪个接口已经很明显了。不过这里还是列出PC端的签到API。

# PC端签到接口
# sign_url = "https://tieba.baidu.com/sign/add"

# 移动端签到接口
# sign_url = "https://c.tieba.baidu.com/c/c/forum/sign"

贴吧列表如果是通过“爱逛的吧”去获取,很明显不全。所以我是通过爬取“关注的吧”页面来获取贴吧列表的。

https://tieba.baidu.com/i/i/forum?&pn=1
https://tieba.baidu.com/i/i/forum?&pn=2
...

 

实现思路

获取列表+发起签到请求

获取列表前,需要BDUSS+STOKEN拿到tbs。在发帖和签到的时候payload里头都会包含这个tbs,没有就发不出去,估计是用户标识符一类的东西。

tbs_url = "https://tieba.baidu.com/dc/common/tbs"
response = json.loads(
        requests.get(tbs_url, cookies={"BDUSS": BDUSS, "STOKEN": STOKEN}).text
    )
login_state = response["is_login"]
if login_state == 1:
    logger.debug("登录成功")
else:
    logger.debug(login_state)
    raise Exception("登录失败")
return response["tbs"], BDUSS, STOKEN

获取贴吧列表比较简单粗暴,Cookies带上BDUSS和STOKEN,再用get方法获取页面的html,再用正则表达式去拿出贴吧名和对应的贴吧链接。

<tr>
    <td><a href="/f?kw=%C9%EE%DB%DA%BC%BC%CA%F5%B4%F3%D1%A7" title="深圳技术大学">深圳技术大学</a></td>
    <td><a class="cur_exp" target="_blank"
            href="/f/like/level?kw=%C9%EE%DB%DA%BC%BC%CA%F5%B4%F3%D1%A7&lv_t=lv_nav_intro">17788</a></td>
    <td><a style="display:block;" class="like_badge badge_lv3_1" title="13级会员" target="_blank"
            href="/f/like/level?kw=%C9%EE%DB%DA%BC%BC%CA%F5%B4%F3%D1%A7&lv_t=lv_nav_intro">
            <div class="like_badge_title">内牛满面</div>
            <div class="like_badge_lv">13</div>
        </a></td>
    <td><span
            onclick="ForumManager.undo_like(this.getAttribute('balvid'), this.getAttribute('balvname'), this.getAttribute('tbs'))"
            balvid="23311541" balvname="%C9%EE%DB%DA%BC%BC%CA%F5%B4%F3%D1%A7" tbs="a527b042d6559d351726813316"><img
                class="pt" src='//tb1.bdstatic.com/tb/static-member/img/close.gif' /></span>
    </td>
</tr>

不过用PC端的“关注的吧”接口除了bduss之外,还必须得带上stoken才能拿到数据。拿到的贴吧列表存不存到本地,看个人需求。我是选择全部存到本地json。

# 从百度贴吧获取关注的贴吧列表
# 结果保存到tieba_dict.json文件中
def get_tieba_dict():
    tieba_dict = {}
    _, BDUSS, STOKEN = get_cookies()
    Cookies = {
        "BDUSS": BDUSS,
        "STOKEN": STOKEN,
    }
    page = 1
    tieba_sum = 0
    while True:
        mylike_url = "https://tieba.baidu.com/f/like/mylike?&pn=" + str(page)
        try:
            response = requests.get(mylike_url, cookies=Cookies)
        except Exception as e:
            raise Exception("请求失败:" + str(e))
        data = extract_data(response.text)
        if data == []:
            break
        for i in data:
            tieba_name = re.search(r"<a.*?>(.*?)</a>", i).group(1)
            tieba_url = prefix + re.search(r"href=\"(.*?)\"", i).group(1)
            if tieba_name is not None:
                tieba_sum += 1
            tieba_dict[tieba_name] = tieba_url
        page += 1
    with open("tieba_dict.json", "w", encoding="utf-8") as f:
        json.dump(tieba_dict, f, ensure_ascii=False)

发起签到请求分为两部分,payload需要带上贴吧名和tbs标识。如果用的移动端签到接口还需要带上它们md5加密后的十六进制结果。我调这接口的时候一直报“未知错误”,后面参考了其他repo才发现要带上这么个参数。

sign_str = f"kw={tieba_name}tbs={tbs}tiebaclient!!!"
sign = hashlib.md5(sign_str.encode("utf-8")).hexdigest()
payload = {
    "kw": tieba_name,
    "tbs": tbs,
    "sign": sign,
}

Cookies只需要bduss,stoken只有在获取贴吧列表时才用得到。

Cookies = {
    "BDUSS": BDUSS,
}
resp = requests.post(
    sign_url,
    cookies=Cookies,
    data=payload,
)

如果签到成功,返回的json会包含user_info。失败的话直接就是error_code,可以在这做个校验。比如GTA5吧,女权吧这种被关闭的吧,如果直接调接口签到,就会在这报错。

    if "user_info" in resp.json():
        logger.debug("签到成功:" + tieba_name + "吧")
        return True
    elif resp.json()["error_code"] == "160002":
        # 已签到
        logger.error(
            "签到失败:" + tieba_name + "吧" + " 失败原因:" + resp.json()["error_msg"]
        )
    else:
        logger.error("签到失败:" + tieba_name + "吧")
        logger.debug(str(resp.json()))
        logger.error("失败原因:" + resp.json()["error_msg"]

目前不知道签到过快会怎么样,总之我加了1~5秒的随机。貌似PC端才会检测签到过快,有时候我一个小时内连续签到98个贴吧就会触发机制,导致当天内的其他在PC端上签到,都需要带上captcha验证码。移动端签到不受影响。


http://www.kler.cn/news/321520.html

相关文章:

  • Spring是什么
  • 有源蜂鸣器(5V STM32)
  • 无人机之虚拟云台技术篇
  • LeetCode 137. 只出现一次的数字 II
  • Linux安装vim超详细教程
  • MySQL重点,面试题
  • 深入Android UI开发:从自定义View到高级布局技巧的全面学习资料
  • RestSharp简介
  • 通信工程学习:什么是SDN软件定义网络
  • 电脑如何设置代理IP:详细步骤指南
  • STM32 入门教程(江科大教材)#笔记4
  • 01.前端面试题之ts:说说如何在Vue项目中应用TypeScript?
  • 趣笔阁爬虫实验
  • Hadoop FileSystem Shell 常用操作命令
  • GO Message Bus
  • 【Python报错已解决】AttributeError: ‘tuple‘ object has no attribute ‘log_softmax‘
  • 华为为什么要做三折叠屏手机?
  • (已解决)torch.load的时候发生错误ModuleNotFoundError: No module named ‘models‘
  • kafka分区和副本的关系?
  • 深度学习:ResNet残差神经网络
  • 【OpenSSL】OpenSSL 教程
  • C++ 数据类型分类
  • Android12的netd分析
  • 解析Vue2源码中的diff算法
  • kafka下载配置
  • 深度学习自编码器 - 得益于深度的指数增益篇
  • 数据集-目标检测系列-口罩检测数据集 mask>> DataBall
  • 自动驾驶综述 | 定位、感知、规划常见算法汇总
  • 网络编程(5)——模拟伪闭包实现连接的安全回收
  • GitLab发送邮件功能详解:如何配置自动化?