之前我们实现了ssb的登录,但是每天第一次登录都只会给你两银币,这对于我喜欢搜集各种资源的人来说还是太少了,那怎么办呢?没错其实除了登录外,每天评论的前三次也给银币。那我就实现自动回复功能。
效果图:
流程分析:
我们先来看看平时是怎么回复的:
(1)点击链接,进入小说首页
https://www.feb.sbooook.com/forum.php?mod=viewthread&tid=859439&extra= 这个就是这本书的接口,多观察就会发现其中只有tid是变化的。
(2) 点击回复,进入回复框
https://www.feb.sbooook.com/forum.php?mod=post&action=reply&fid=40&tid=859439&infloat=yes&handlekey=reply&inajax=1&ajaxtarget=fwin_content_reply
这个就是下面回复框的接口,一样多请求几次发现只有fid 和tid是变化的
(3)选择回复并发送
发送肯定也是有接口的,并且它一定会是个post请求(下图为回复api)
表单参数:
不难发现表单参数里的fid和tid和回复框的接口是一样的。但是表单数据有怎么从哪来的?其实表单数据都是从前面的表单框里面提取出来的,也就我们请求了回复框,它就会返回这些数据过来。我们只需要正则匹配一下参数就行了。
回复框里参数:
但是这里它返回的只有5个参数,还是有一个message里面没有,其实从名称也可以看到出来这个参数就是我们回复的话,那为啥会是这个样子而不是中文?其实这是因为在处理中文参数时,它会自动帮我们使用urlencode 进行编码,所以这里的message其实就是编译后的结果。
参数和接口都已分析完毕,接下来就是代码实现了
代码实现:
# -*- coding:utf-8 -*- import re import requests import random class Comment: def __init__(self, user_name, user_password, c_url): """ 自动登录账号 :param user_name: 用户名 :param user_password: 用户密码 :param c_url: 评论书籍url """ self.user_name = user_name self.user_pwd = user_password self.c_url = c_url self.base_url = "https://www.feb.sbooook.com/" self.session = requests.session() self.user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.76" self.logging_api = f"{self.base_url}member.php?mod=logging&action=login&loginsubmit=yes&infloat=yes&lssubmit=yes&inajax=1 " # 登录接口 self.headers = { "Cache-Control": "no-cache", "Content-Type": "application/x-www-form-urlencoded", "Pragma": "no-cache", "Referer": self.base_url, "User-Agent": self.user_agent } self.book_page = self.session.get(url=self.c_url, headers=self.headers).text # 匹配fromhash self.formhash = re.findall('<input type="hidden" name="formhash" value="(.*)" />', self.book_page)[0] # 表单参数 data = { 'username': self.user_name, 'password': self.user_pwd, 'formhash': self.formhash, 'quickforward': "yes", 'handlekey': "ls"} # 登录账号 res = self.session.post(url=self.logging_api, headers=self.headers, data=data).text if f"window.location.href='{self.base_url}';" in res: print(f'账号:{self.user_name} 登录成功!!!') else: print('登录失败,请重试!!!') def comment(self): """ 自动回复功能 :return: """ # 匹配回复按钮 url = self.c_url comment_text = ["啥也不说了,楼主就是给力!", "看了LZ的帖子,我只想说一句很好很强大!", "谢谢楼主分享,祝搜书吧越办越好!"] # 回复信息 book_page = self.session.get(url=url, headers=self.headers).text # 小说首页 book_name = re.findall('<title>(.*?)</title>', book_page)[0] comment_btn_url = re.findall('''onclick="showWindow.'reply', '(.*?)'."''', book_page)[0] # 匹配回复按钮url tid = re.findall("tid=(.*)", comment_btn_url)[0] # 匹配tid fid = re.findall("fid=(.*?)&", comment_btn_url)[0] # 匹配fid comment_headers = { "Cache-Control": "no-cache", "Content-Type": "application/x-www-form-urlencoded", "Pragma": "no-cache", "upgrade-insecure-requests": "1", "Referer": f"{self.base_url}forum.php?mod=viewthread&tid={tid}&extra=", "User-Agent": self.user_agent } comment_box_url = f"{self.base_url}{comment_btn_url}&infloat=yes&handlekey=reply&inajax=1&ajaxtarget=fwin_content_reply" # 回复框api comment_box = self.session.get(url=comment_box_url, headers=comment_headers).text # 回复框 comment_data = {"formhash": re.findall('<input type="hidden" name="formhash" id="formhash" value="(.*)" />', comment_box)[0], "handlekey": "register", "noticeauthor": re.findall('<input type="hidden" name="noticeauthor" value="(.*)" />', comment_box)[0], "noticetrimstr": re.findall('<input type="hidden" name="noticetrimstr" value="(.*)" />', comment_box)[0], "noticeauthormsg": re.findall('<input type="hidden" name="noticeauthormsg" value="(.*)" />', comment_box)[0], "usesig": re.findall('<input type="hidden" name="usesig" value="(.*)"/>', comment_box)[0], "subject": re.findall( '<input name="subject" id="subject" class="px" value="(.*)" tabindex="21" style="width: 25em" />', comment_box)[0], "message": random.choice(comment_text).encode('gbk') } comment_api = f"{self.base_url}forum.php?mod=post&infloat=yes&action=reply&fid={fid}&extra=&tid={tid}&replysubmit=yes&inajax=1" # 回复api res_text = self.session.post(url=comment_api, headers=comment_headers, data=comment_data).text if "errorhandle_register" in res_text: print(self.user_name + re.findall("errorhandle_register.'(.*?)'", res_text)[0]) elif "succeedhandle_register" in res_text: print(f"{self.user_name} 回复 {book_name} 成功!") if __name__ == '__main__': user_namr = '' # 搜书吧用户名 password = '' # 搜书吧密码 comment_url = "https://www.feb.sbooook.com/forum.php?mod=viewthread&tid=859439&extra=" # 评论书籍url Comment(user_namr, password, comment_url).comment()
至此,自动回复功能已经实现了,但其实它还不算是真正地的全自动,只能说是半自动因为我们还需要自己去复制小说的链接,同时没有异常处理(因为它的服务器在平时也容易出错,这就是我为什么不建议使用多线程/进程的原因),还要担心如果它的完成换域名了(经常换)我们又要自己去修改代码比较麻烦,其实以上也有相应解决办法,在此不多阐述。
以上纯属娱乐,如有问题还请大佬指出。