『python爬虫』requests实战-精易论坛自动签到(保姆级图文+实现代码)
『python爬虫』requests实战-精易论坛自动签到(保姆级图文+实现代码)
目录
欢迎关注 『python爬虫』 专栏,持续更新中
欢迎关注 『python爬虫』 专栏,持续更新中
实现效果
API命令解析
re.findall 匹配内容,用于在我们得到的网页源码中查找指定的内容
在这个示例中,我们使用 re.findall() 查找了字符串 text 中所有的数字,并将它们以列表的形式返回给变量 numbers。r’\d+’ 是一个正则表达式模式,用于匹配一个或多个数字。
你可以根据实际需要调整正则表达式模式,以便在字符串中查找特定的内容。
希望这个示例对你有所帮助。如果你有任何其他问题,欢迎随时向我提问。
import re
# 匹配所有数字
text = "The recipe calls for 2 cups of sugar and 1 cup of flour."
numbers = re.findall(r'\d+', text)
print(numbers) # 输出 ['2', '1']
session.post() 和 session.get()
都是 requests 库中的方法,用于发送 HTTP 请求。
session.get() 方法用于发送 GET 请求,而 session.post() 方法用于发送 POST 请求。通常情况下,GET 请求用于获取数据,POST 请求用于提交数据。
以下是一个示例代码,演示如何使用 session.get() 和 session.post() 方法发送 HTTP 请求
import requests
# 创建 Session 对象
session = requests.session()
# 发送 GET 请求
response = session.get('http://example.com')
# 发送 POST 请求
data = {'username': 'user', 'password': 'pass'}
response = session.post('http://example.com/login', data=data)
在这个例子中,我们首先创建了一个 Session 对象,并将其赋值给变量 session。然后,我们使用 session.get() 方法发送了一个 GET 请求,并将响应保存到变量 response 中。接下来,我们使用 session.post() 方法发送了一个 POST 请求,并将表单数据传递给服务器。
需要注意的是,使用 session 对象发送请求时,所有的请求都会使用同一个 Session,这可以确保在多个请求之间共享 Cookies 等信息。
实现思路
库
因为日常登录有滑块验证码,所以打算采用cookie的方式登录访问,同时涉及多个请求,就用requests和配套的lxml,匹配元素有用到re库用于正则匹配.
import requests
import re
import time
from lxml import etree
cookie怎么抓取
一般性的思路都是f12打开网络抓包,在登录页面的跳转时分析.
登录的一瞬间你最先看到了login.html,反正一般来说找这种login的(除非写网页的是什么特殊写法的自学成才的```一般都是有login字眼的)
在请求表头中找到cookie
cookie登录如何实现
requests.session() 是一个类,用于创建一个全局的 Session 对象,该对象可以跨请求保持某些参数,比如 Cookies。在使用 requests 库发送多个请求时,使用 Session 对象可以减少重复操作,提高代码执行效率。
使用 requests.session() 创建 Session 对象后,你可以像使用 requests.get() 或 requests.post() 一样发送 HTTP 请求,只不过在发送请求时,session 对象会自动记录 Cookies。这样就可以保持用户的登录状态,或者利用 Cookies 等信息来实现其他功能。
下面的代码中同时用到了伪装请求头,最终的rep是返回的网页源码.
headers = {
'cookie': 'xxxxxx',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'
}
session = requests.session()
url_page = 'https://bbs.125.la/plugin.php?id=dsu_paulsign:sign'
#1.登录得到帖子
rep = session.get(url=url_page, headers=headers)#rep是返回的网页源码
得到FORMHASH参数
如果没有传入"FORMHASH"参数会报错
hot_message = re.findall(r'/thread-14(.*).html" target="_blank"', rep.text)#获取首页热门的帖子地址
# print(hot_message)
#['812294-1-1', '812481-1-1', '812254-1-1', '812156-1-1', '812348-1-1', '812474-1-1', '812182-1-1', '812359-1-1', '812267-1-1', '812159-1-1', '810464-1-1', '810459-1-1', '810334-1-1', '808876-1-1', '807810-1-1', '766025-1-1', '777673-1-1', '793375-1-1', '783395-1-1', '804966-1-1']
formhash = re.findall(r'formhash=(.*)">退出', rep.text)
print("formhash:{}".format(formhash))#['e5eexxxx]
# formhash=xxxxxxx 看起来是一个表单提交时的参数。
# formhash 是一个用于防止 CSRF(跨站请求伪造)攻击的安全令牌,也是后面签到需要用到的参数。
url_page = 'https://bbs.125.la/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1'
自动签到
抓到了签到的包
请求网址:
https://bbs.125.la/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1
rep = session.post(url=url_page, headers=headers,
data={'formhash': formhash, "submit": "1", "targerurl": "", "todaysay": "", "qdxq": "kx"})
print("签到结果:" + re.findall(r'{"status":0,"msg":"(.*)"}', rep.text)[0])
自动评分
#3.自动评分
for i in range(0, len(hot_message)):
url_page = 'https://bbs.125.la/thread-14' + hot_message[i] +'.html'
rep = session.get(url=url_page, headers=headers)
if rep.status_code == 200:
print('进入帖子详情页成功')
tree = etree.HTML(rep.text)
a_list = tree.xpath('//*[@id="ak_rate"]/@onclick')
addr = a_list[0]
str1 = addr.split(',')
str2 = str1[1].split('&')
tid1 = str2[2]
pid1 = str2[3]
tid2 = tid1.split('=')[1]
pid2 = pid1.split('=')[1]
pid3 = pid2.split('\'')[0]
tid = tid2
pid = pid3 # 获取到tid与pid
formash1 = tree.xpath('//*[@id="vfastpost"]/input/@value')
formash = formash1[0] # 获取到formash
# print("获取pid={}与tid={}与formash={}成功,开始自动评分".format(pid, tid, formash))
# 开始评分
url_score = 'https://bbs.125.la/forum.php?mod=misc&action=rate&ratesubmit=yes&infloat=yes&inajax=1'
data = 'formhash=' + formash + '&tid=' + tid + '&pid=' + pid + '&referer=https%3A%2F%2Fbbs.125.la%2Fforum.php%3Fmod%3Dviewthread%26tid%3D' + tid + '%26page%3D0%23pid' + pid + '&handlekey=rate&score4=%2B1&reason=%E6%84%9F%E8%B0%A2%E5%88%86%E4%BA%AB%EF%BC%8C%E5%BE%88%E7%BB%99%E5%8A%9B%EF%BC%81%7E'
headers['Content-Type'] = 'application/x-www-form-urlencoded'
headers['Referer'] = 'https://bbs.125.la/thread-14720892-1-1.html'
rep_score = session.post(url=url_score, data=data, headers=headers) #开始评分请求,rep_score是评分返回的源码
rep_score_result=rep_score.status_code # 200表示评分成功
if rep_score_result==200:
print("评分推送成功,任务:{}".format(i))
else:
print("评分推送失败,任务:{}".format(i))
score_message=re.findall(r'CDATA\[(.*)<scrip', rep_score.text)[0]
result = re.search(r'class="showmenu">积分: (\d+)</a>', rep.text)
if result:
number = result.group(1) # 提取匹配到的数字部分
print("评分反馈:{},积分:{}".format(score_message,number))
else:
number=-1
print("未找到匹配的内容,积分:{}".format(number))
time.sleep(2)
error_limit = rep_score.text.find("超过限制")
if error_limit != -1:
print("已经完成评分次数{},24小时评分数超过限制,退出".format(i))
break;
else:
print('进入帖子失败')
实现代码
import requests
import re
import time
from lxml import etree
def dailyTask():
headers = {
'cookie': 'xxxxxxxxx',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'
}
session = requests.session()
url_page = 'https://bbs.125.la/plugin.php?id=dsu_paulsign:sign'
#1.登录得到帖子
rep = session.get(url=url_page, headers=headers)#rep是返回的网页源码
hot_message = re.findall(r'/thread-14(.*).html" target="_blank"', rep.text)#获取首页热门的帖子地址
# print(hot_message)
#['812294-1-1', '812481-1-1', '812254-1-1', '812156-1-1', '812348-1-1', '812474-1-1', '812182-1-1', '812359-1-1', '812267-1-1', '812159-1-1', '810464-1-1', '810459-1-1', '810334-1-1', '808876-1-1', '807810-1-1', '766025-1-1', '777673-1-1', '793375-1-1', '783395-1-1', '804966-1-1']
formhash = re.findall(r'formhash=(.*)">退出', rep.text)
print("formhash:{}".format(formhash))#['e5eexxxx]
# formhash=xxxxxxx 看起来是一个表单提交时的参数。
# formhash 是一个用于防止 CSRF(跨站请求伪造)攻击的安全令牌,也是后面签到需要用到的参数。
url_page = 'https://bbs.125.la/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1'
#2.自动签到
rep = session.post(url=url_page, headers=headers,
data={'formhash': formhash, "submit": "1", "targerurl": "", "todaysay": "", "qdxq": "kx"})
print("签到结果:" + re.findall(r'{"status":0,"msg":"(.*)"}', rep.text)[0])
#3.自动评分
for i in range(0, len(hot_message)):
url_page = 'https://bbs.125.la/thread-14' + hot_message[i] +'.html'
rep = session.get(url=url_page, headers=headers)
if rep.status_code == 200:
print('进入帖子详情页成功')
tree = etree.HTML(rep.text)
a_list = tree.xpath('//*[@id="ak_rate"]/@onclick')
addr = a_list[0]
str1 = addr.split(',')
str2 = str1[1].split('&')
tid1 = str2[2]
pid1 = str2[3]
tid2 = tid1.split('=')[1]
pid2 = pid1.split('=')[1]
pid3 = pid2.split('\'')[0]
tid = tid2
pid = pid3 # 获取到tid与pid
formash1 = tree.xpath('//*[@id="vfastpost"]/input/@value')
formash = formash1[0] # 获取到formash
# print("获取pid={}与tid={}与formash={}成功,开始自动评分".format(pid, tid, formash))
# 开始评分
url_score = 'https://bbs.125.la/forum.php?mod=misc&action=rate&ratesubmit=yes&infloat=yes&inajax=1'
data = 'formhash=' + formash + '&tid=' + tid + '&pid=' + pid + '&referer=https%3A%2F%2Fbbs.125.la%2Fforum.php%3Fmod%3Dviewthread%26tid%3D' + tid + '%26page%3D0%23pid' + pid + '&handlekey=rate&score4=%2B1&reason=%E6%84%9F%E8%B0%A2%E5%88%86%E4%BA%AB%EF%BC%8C%E5%BE%88%E7%BB%99%E5%8A%9B%EF%BC%81%7E'
headers['Content-Type'] = 'application/x-www-form-urlencoded'
headers['Referer'] = 'https://bbs.125.la/thread-14720892-1-1.html'
rep_score = session.post(url=url_score, data=data, headers=headers) #开始评分请求,rep_score是评分返回的源码
rep_score_result=rep_score.status_code # 200表示评分成功
if rep_score_result==200:
print("评分推送成功,任务:{}".format(i))
else:
print("评分推送失败,任务:{}".format(i))
score_message=re.findall(r'CDATA\[(.*)<scrip', rep_score.text)[0]
result = re.search(r'class="showmenu">积分: (\d+)</a>', rep.text)
if result:
number = result.group(1) # 提取匹配到的数字部分
print("评分反馈:{},积分:{}".format(score_message,number))
else:
number=-1
print("未找到匹配的内容,积分:{}".format(number))
time.sleep(2)
error_limit = rep_score.text.find("超过限制")
if error_limit != -1:
print("已经完成评分次数{},24小时评分数超过限制,退出".format(i))
break;
else:
print('进入帖子失败')
if __name__ == '__main__':
dailyTask()
print("执行完毕~")
后续优化
青龙面板+pushplus微信通知~~
总结
大家喜欢的话,给个👍,点个关注!给大家分享更多计算机专业学生的求学之路!
版权声明:
发现你走远了@mzh原创作品,转载必须标注原文链接
Copyright 2023 mzh
Crated:2023-3-1
欢迎关注 『python爬虫』 专栏,持续更新中
欢迎关注 『python爬虫』 专栏,持续更新中
『未完待续』
更多推荐
所有评论(0)