【python】自动更新pu口袋校园活动
【python】自动更新pu口袋校园活动
脚本目标:
1. 自动爬取pu口袋校园活动,筛选出需要的活动,此处我的筛选条件是线上活动,因为可以不用去就可以白嫖学时
2. 自动发送邮件到QQ邮箱,每次只发送更新的活动,因为QQ邮箱的提醒可以在QQ里直接看到
3. 挂在后台,不显示控制台
已知条件:
1. pu口袋校园有网页版,可以直接登录,在网页上查看活动,和报名活动,所以可以写一个网页爬虫爬取数据
2. pu口袋校园在查看活动列表的时候不需要cookie就可以看到,如果需要点进活动页面查看活动的具体内容需要cookie,而活动地点是在具体内容页面里的,所以需要准备一份cookie
3. 整个网页没有反爬机制,不需要准备user-agent
4. 判断线上活动的方式:活动地点为空
5. 是服务器端渲染的网页,不需要用selenium
脚本思路:
1. 写一个简单的网页爬虫,爬取页面源代码,提取其中活动的具体内容的url
2. 爬取每个活动具体内容的源代码,筛选出活动地点为空的内容,将活动名称添加到列表
3. 将第一次整理出来的列表为初始化的列表,每次更新先和之前的列表比对,筛选出来新的活动,作为一个列表
4. 发送活动名称到QQ邮箱
代码实现:
先把需要在后面用到的内容写在前面
obj = re.compile(".*? <span class=\"b1\">活动地点:</span><a title=\"(?P<area>.*?)\">")
obj2 = re.compile(".*?<title>(?P<name>.*?)</title>")
header = {"Cookie": "TS_LOGGED_USER=-kowQgrvPgFq4iqGji4hPA5vH; PHPSESSID=51fb2a5a61c010f0465d0; Hm_lvt_dd3ea352543392a029ccf9da1be54a50=1639667636,1639918552,1639977234; TS_think_language=zh-CN; Hm_lpvt_dd3ea352543392a029ccf9da1be54a50=1639994037"}
这个链接点开可以得到活动列表页面https://xxx.pocketuni.net/index.php?app=event&mod=School&act=board&cat=all&&p=1
我选择爬取前面八页的活动列表,返回八页活动列表的链接
def get_page_url():
url_list=[]
for num in range(1,8+1):
url = f"https://xxx.pocketuni.net/index.php?app=event&mod=School&act=board&cat=all&&p={num}"
url_list.append(url)
return url_list
这个函数用来请求八页活动列表的页面源代码,并且得到每个活动具体内容的网页地址,用xpath解析,返回具体活动内容的链接
def handle(url_list):
child_url=[]
for url in url_list:
resp = requests.get(url)
resp.close()
resp_tree=etree.HTML(resp.text)
child_url.extend(resp_tree.xpath("/html/body/div[2]/div/div[3]/div[2]/div[1]/ul/li/div[2]/div[1]/a/@href"))
return child_url
这个函数用来请求所有,活动具体内容的源代码,并且用正则表达式筛选出活动地点和活动名称,将活动地点为空所对应的活动名称添加到active_name_list的列表里,返回符合条件的活动名称
def handle2(child_urls):
x=1
active_name_list=[]
for url in child_urls:
resp = requests.get(url,headers=header)
resp.close()
active_area = str(obj.findall(resp.text)).replace("[","").replace("]","").replace("'","").replace(" ","")
active_name = str(obj2.findall(resp.text)).replace("[","").replace("]","").replace("'","").replace(" ","")
if active_area =='':
active_name_list.append(active_name)
return active_name_list
比对出新更新的内容
if x==1: #x=1只在程序开始的时候初始化一次,判断是不是第一次执行程序,如果是就初始化old_list来作为下一次活动的比对条件
old_list = old_list+active_name_list
send_email(old_list)
x+=1
update_list = [x for x in active_name_list if x not in old_list] #将得到的新列表和old_list比对,将更新的内容保存在update_list并发送邮件
if len(update_list)==0:
print("未出现新活动,最近一次更新时间为",time.strftime('%H:%M:%S',time.localtime(time.time())))
else:
print("出现新活动,发送")
send_email(update_list)
这个函数用来发送邮件,用自己的163邮箱发送给自己的QQ邮箱,当然自己给自己的邮箱发送也是可以的。
此处授权密码是随便写的,用自己的授权密码。
关于发送邮件需要注意:自己的邮箱需要开通pop3/SMTP服务,会给一个授权码,username和password分别写自己的邮箱和授权密码,注意开放的端口,端口不正确会导致连接不上邮箱
def send_email(text):
smtpsrever = 'smtp.163.com'
# 发送邮件的用户名和密码
username = 'shui_feng_xxxxx@163.com'
password = 'NJXXXXXXXXXNB' # 授权密码
# 接收邮件的邮箱
receiver = '1609519xxx@qq.com'
# 创建邮件对象
message = MIMEMultipart('relate') #生成一个带附件的邮件对象
message = MIMEText(f'{text}', 'plain', 'utf-8')
subject = "第一次测试" # 邮件的主题
# 把邮件的信息组装到邮件对象里
message['from'] = username
message['to'] = receiver
message['subject'] = subject # 登录smtp服务器并发送邮件
smtp = smtplib.SMTP()
smtp.connect(smtpsrever)
smtp.login(username, password)
smtp.sendmail(username, receiver, message.as_string())
smtp.quit()
最后写一个主函数来执行这一切
if __name__=='__main__':
old_list=[]
x=1
while True:
url_list=get_page_url()
child_urls=handle(url_list)
active_name_list=handle2(child_urls)
if x==1:
old_list = old_list+active_name_list
send_email(old_list)
x+=1
update_list = [x for x in active_name_list if x not in old_list]
if len(update_list)==0:
print("未出现新活动,最近一次更新时间为",time.strftime('%H:%M:%S',time.localtime(time.time())))
else:
print("出现新活动,发送")
send_email(update_list)
time.sleep(60*60*24) #死循环,每二十四小时执行一次
最终功能代码
import requests
import os
import re
import time
from lxml import etree
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
obj = re.compile(".*? <span class=\"b1\">活动地点:</span><a title=\"(?P<area>.*?)\">")
obj2 = re.compile(".*?<title>(?P<name>.*?)</title>")
header = {"Cookie": "TS_LOGGED_USER=-kowQgrvPgFq4iqGji4hPA5vH; PHPSESSID=51fb2a5a61c010f0465d0; Hm_lvt_dd3ea352543392a029ccf9da1be54a50=1639667636,1639918552,1639977234; TS_think_language=zh-CN; Hm_lpvt_dd3ea352543392a029ccf9da1be54a50=1639994037"}
def handle(url_list):
child_url=[]
for url in url_list:
resp = requests.get(url)
resp.close()
resp_tree=etree.HTML(resp.text)
child_url.extend(resp_tree.xpath("/html/body/div[2]/div/div[3]/div[2]/div[1]/ul/li/div[2]/div[1]/a/@href"))
return child_url
def handle2(child_urls):
x=1
active_name_list=[]
for url in child_urls:
resp = requests.get(url,headers=header)
resp.close()
active_area = str(obj.findall(resp.text)).replace("[","").replace("]","").replace("'","").replace(" ","")
active_name =str(obj2.findall(resp.text)).replace("[","").replace("]","").replace("'","").replace(" ","")
if active_area =='':
active_name_list.append(active_name)
return active_name_list def send_email(text):
smtpsrever = 'smtp.163.com'
# 发送邮件的用户名和密码
username = 'shui_feng_XXXX@163.com'
password = 'NXXXXXXXXXB' # 授权密码
# 接收邮件的邮箱
receiver = '1609519XXX@qq.com'
# 创建邮件对象
message = MIMEMultipart('relate') # 生成一个带附件的邮件对象
message = MIMEText(f'{text}', 'plain', 'utf-8')
subject = "pu口袋校园活动" # 邮件的主题
# 把邮件的信息组装到邮件对象里
message['from'] = username
message['to'] = receiver
message['subject'] = subject
# 登录smtp服务器并发送邮件
smtp = smtplib.SMTP()
smtp.connect(smtpsrever)
smtp.login(username, password)
smtp.sendmail(username, receiver, message.as_string())
smtp.quit()
def get_page_url():
url_list=[]
for num in range(1,8+1):
url = f"https://XXX.pocketuni.net/index.php?app=event&mod=School&act=board&cat=all&&p={num}"
url_list.append(url)
return url_list
if __name__=='__main__':
old_list=[]
x=1
while True:
url_list=get_page_url()
child_urls=handle(url_list)
active_name_list=handle2(child_urls)
if x==1:
old_list = old_list+active_name_list
send_email(old_list)
x+=1
update_list = [x for x in active_name_list if x not in old_list]
if len(update_list)==0:
print("未出现新活动,最近一次更新时间为",time.strftime('%H:%M:%S',time.localtime(time.time())))
else:
print("出现新活动,发送")
send_email(update_list)
time.sleep(60*60*24)
实现后台运行的方法:使用pyinstaller打包软件时,用 -w 可以不显示控制台,但是在后台可以在后台看到它正在运行
所以只需要用pyinstaller -F -w pu口袋校园.py 再执行exe文件就可以后台运行程序,或者再加一个开机自启也可以
实现效果:


且此时桌面没有控制台窗口的显示
小脚本完成,按照脚本给的活动名称报名就可以了,看有的线上活动会显示扫码签到,所以要注意一下,一般无需签到或者外勤签到都可以白嫖学时
后记:关于脚本的更改
不同的学校我觉得页面应该都长差不多,毕竟都是pu口袋校园,只是要把脚本中以下内容改一下
1. 活动列表的页面url
2. 访问时的cookie
3. 发送的邮箱,授权密码,接收的邮箱
4. 根据自己的需要,重写筛选的条件
ENDING.............
【python】自动更新pu口袋校园活动的更多相关文章
- python自动更新pom文件
前言 项目越来越多,版本管理越来越麻烦,在项目上我使用 maven version 来进行版本管理.主要还是在分布式项目中模块众多的场景中使用,毕竟各个模块对外的版本需要保持统一. 关于这个插件如何使 ...
- python自动更新升级失败解决方案
1,使用python -m pip install --upgrade pip升级失败 2,使用python -m pip install -U --force-reinstall pip依然失败 3 ...
- 江西财经大学第一届程序设计竞赛 G题 小Q的口袋校园
链接:https://www.nowcoder.com/acm/contest/115/G来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536 ...
- python学习笔记(Tkinter编程利用Treeview实现表格自动更新)
博主今天总结这段时间抽空写的一个GUI编程项目 功能是查看本地打印机队列,可选择指定队列重新打印 直接上图 UI设计包括3个区域左上方,右上方和下方列表区域 使用网格grid方法来分配位置 下面是界面 ...
- python一招完美搞定Chromedriver的自动更新
日常的web自动化过程中,我们常常用python selenium库来操纵Chrome浏览器实现网页的自动化.这其中有个比较头疼的问题:Chrome的更新频率非常频繁,与之对应的Chromedrive ...
- python自动开发之(django)第十九天
一.路由系统,URL 1.函数及类 函数:url(r'^index/', views.index), 类:url(r'^home/', views.Home.as_view()), 2.顺序 url( ...
- git 利用hook 实现服务器自动更新代码
如何利用git的hook实现提交代码后自动更新? 因为个人开发经常需要提交代码,每次都需要连接服务器去pull代码,重启服务器就显得十分繁琐,因此github提供了一个时间钩子,用户push代码后可以 ...
- 利用python自动生成verilog模块例化模板
一.前言 初入职场,一直忙着熟悉工作,就没什么时间更新博客.今天受“利奇马”的影响,只好宅在家中,写写技术文章.芯片设计规模日益庞大,编写脚本成了芯片开发人员必要的软技能.模块端口动不动就几十上百个, ...
- 用Python自动办公,做职场高手(完结)
教程目录: ┣━07.S2 Word自动化处理,又快又好做文档┃ ┣━36 本章介绍┣━08.[Word]S2-1 轻松用Python快速生成Word文档┃ ┣━45.[真实案例]S2-1-3 批 ...
随机推荐
- Rancher无法登录 容器报错X509:certificate has expired or is not ye valid
在某天需要发布新版本的时候,发现rancher无法登录,于是到服务器上查看rancher日志,发现以下内容: 参考rancher文档中独立容器Rancher Server证书更新解决 1. 进入容器 ...
- celery介绍、架构、快速使用、包结构,celery执行异步、延迟、定时任务,django中使用celery,定时更新首页轮播图效果实现,数据加入redis缓存的坑及解决
今日内容概要 celery介绍,架构 celery 快速使用 celery包结构 celery执行异步任务 celery执行延迟任务 celery执行定时任务 django中使用celery 定时更新 ...
- cookie、sessionStorage、localStorage的区别?
数据存储位置 三者都是存储在游览器本地的 区别在于cookie是服务器端写入的,而sessionStorage.localStorage是由前端写入的 生命周期 cookie的生命周期是由服务器端写入 ...
- Linux 环境变量配置的 6 种方法,建议收藏
关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ Linux环境变量配置 在自定义安装软件的时候,经常需要配置环境变量,下面列举出各种对环境变量 ...
- 没错,华为开始对IoT下手了!
最近,有很多粉丝在后台私信 想知道目前最热的技术是什么? 小编觉得,5G时代到来 物联网技术将迎来快速的发展 加上目前,国内物联网人才短缺 每年人才缺口达百万 IoT物联网将成为最热门的技术 最近,小 ...
- 【面试普通人VS高手系列】讲一下wait和notify这个为什么要在synchronized代码块中?
一个工作七年的小伙伴,竟然不知道"wait"和"notify"为什么要在Synchronized代码块里面. 好吧,如果屏幕前的你也不知道,请在评论区打上&qu ...
- numpy学习笔记Ⅰ
一直被numpy和matplotlib困扰,打算好好学习一下,也是从自己的观点,学对自己帮助最大的部分 主要参考<https: www.runoob.com="" numpy ...
- .Net 6 WebApi 项目部署到 Linux 系统上的 Docker 容器
1.创建一个基础的WebApi项目 注意:因为发布时候,Dockerfile文件必须和解决方案.cspro文件放在同级,所以建议勾上这个,当时遇到这个问题,导致打包镜像时找不到.cspro文件,搞了好 ...
- SM3和Blake
在此给出SM3和Blake的对比 哈希函数 哈希算法 (Hash Algorithm) 是将任意长度的数据映射为固定长度数据的算法,也称为消息摘要.一般情况下,哈希算法有两个特点, 一是原始数据的细微 ...
- Java高并发-Java内存模型和线程安全
一.原子性 原子性是指一个操作是不可中断的.即使在多个线程一起执行的时候,一个操作一旦开始,就不会被其它线程干扰. i++是原子操作吗? 不是,包含3个操作:读i,i=i+1,写i 32位的机子上读取 ...