Python+腾讯云服务器实现每日自动健康打卡

作者:图爱森 时间:2023-08-18 00:22:44 

1.配置需要

python3.7,Chrome或者Edeg浏览器,Chrome驱动或者Edge驱动


#需要配置selenium库,baidu-aip库,pillOW库,在终端执行以下命令
pip install selenium
pip install pillow
pip install baidu-aip

2.实现功能

1.模拟登录说唱大学微服务,需要百度OCR智能识别API接口识别验证码(免费获取)

2.虚拟位置信息填写,注释:其余信息保留上一天信息

3.反馈打卡信息到QQ邮箱,注释:需要自行配置POP3/ SMTP服务

4.挂到腾讯云服务上,每天定时自动打卡

3.参考链接

百度OCR智能识别的API调用链接

QQ邮箱配置链接

腾讯云服务器上运行(免费1个月)选择轻量应用服务器,我选的linux系统,这里的实例也是linux

4.linux服务器配置

参考腾讯文档,远程登录linux实例

1.以root登录

2.下载Python3.7,升级pip,yum,更换国内源

3.安装库,执行以下命令


pip3 install selenium
pip3 install pillow
pip3 install baidu-aip

4.在linux上安装谷歌浏览器和驱动

在目录 /etc/yum.repos.d/ 下新建文件 google-chrome.repo


cd /etc/yum.repos.d/
vim google-chrome.repo

vim命名编辑google-chrome.repo文件,输入如下内容:


[google-chrome]

name=google-chrome

baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch

enabled=1

gpgcheck=1

gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub

具体操作:按i插入,按Esc,然后Shift+;,输入qw,然后按Enter退出

安装浏览器,依次输入以下命令


yum -y install google-chrome-stable --nogpgcheck
# 检查版本信息
google-chrome --version
# 找到google_chrome路径:我对应的路径是/usr/bin/google-chrome,输入路径创建软连接
which google-chrome
# 创建软连接
ln -s /usr/bin/google-chrome /bin/chrome
# 安装驱动
wget https://npm.taobao.org/mirrors/chromedriver/88.0.4324.96/chromedriver_linux64.zip
# 解压
yum -y install zip
unzip chromedriver_linux64.zip
# 转移chromedriver到/user/bin目录下
sudo mv chromedriver /usr/bin
# 解决root运行chrome问题
vim /opt/google/chrome/google-chrome
# 将最后一行改为如下:
exec -a "$0" "$HERE/chrome" "$@" --no-sandbox $HOME

将Python自动运行程序写到linux里:


vim automatic.py
# 然后把程序复制进去

测试运行:


python3 automatic.py

利用crontab定时运行python脚本:(输入如下命令)


crontab -e
# 从左到右依次表示分、时、日、月、周,设置为每天0:01自动打卡
1 0 * * * /usr/bin/python3 /root/automatic.py
# 启动服务
service crond restart

5.代码部分

有详细解释


import sys
import time
from aip import AipOcr
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
from PIL import Image
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

class LogIn:
   def __init__(self, user, passwd, path, lat=30.630869, long=104.083748):
       self.target = 'https://wfw.scu.edu.cn/ncov/wap/default/index'  # 说唱大学微服务地址
       self.username = str(user)  # 用户名
       self.password = str(passwd)  # 密码
       self.lat = lat  # 纬度
       self.long = long  # 经度
       self.path = path

def main(self):
       attempt = 0
       print('\n准备')
       chrome_options = webdriver.ChromeOptions()
       # 设置 * 面显示参数,因为要放在linux服务器上运行,无法显示界面,调试的时候需要把下面五行注释掉,显示chrome界面
       chrome_options.add_argument('--no-sandbox')
       chrome_options.add_argument('window-size=1920x1080')
       chrome_options.add_argument('--disable-gpu')
       chrome_options.add_argument('--hide-scrollbars')
       chrome_options.add_argument('--headless')

s = Service(self.path)
       browser = webdriver.Chrome(service=s, options=chrome_options)# 加载 chromedriver,用edge的就去下载edgedriver
       print('开始')
       while True:
           browser.delete_all_cookies()  # 清空cookie
           browser.get(self.target)
           try:  # 切换为账号密码登录
               browser.switch_to.frame('loginIframe')  # 切换frame
               switch_element = WebDriverWait(browser, 10).until(
                   EC.element_to_be_clickable((By.XPATH, '/html/body/div/div/div[2]/div[2]/div[1]/div/div[3]'))
               ) # 找到对应元素位置
               switch_element.click() # 点击切换
           except Exception as error:
               print('network wrong...\n', error)

# 输入账号和密码
           input_user = browser.find_element(by=By.XPATH, value='/html/body/div/div/div[2]/div[2]/div[2]/div[3]/div[1]/div[2]/div/input')
           input_user.send_keys(self.username)
           input_pwd = browser.find_element(by=By.XPATH, value='/html/body/div/div/div[2]/div[2]/div[2]/div[3]/div[2]/div[2]/div/input')
           input_pwd.send_keys(self.password)
           time.sleep(1)

# 截图验证码并识别(这里用的百度云的免费OCR),需要自行注册,不会的可以参考这篇博客:https://www.cnblogs.com/xiaowenshu/p/11792012.html

ver_btn = browser.find_element(by=By.CLASS_NAME, value='van-field__button')
           ver_btn.click()# 刷新验证码
           # 获取图片元素的位置
           loc = ver_btn.location
           # 获取图片的宽高
           size = ver_btn.size
           # 获取验证码上下左右的位置
           left = loc['x']
           top = loc['y']
           right = (loc['x'] + size['width'])
           botom = (loc['y'] + size['height'])
           val = (left, top, right, botom)

print(loc)
           print(size)
           # 验证码截图保存到当前目录下ver.png
           # 打开网页截图
           browser.save_screenshot('full.png')
           # 通过上下左右的值,去截取验证码
           pic = Image.open('full.png')
           ver_pic = pic.crop(val)
           ver_pic.save('ver.png')

verification = self.Vertification('ver.png')
           print('verification code:' + verification) # 识别验证码完毕

input_ver = browser.find_element(by=By.XPATH, value='/html/body/div/div/div[2]/div[2]/div[2]/div[3]/div[3]/div[2]/div/input')
           input_ver.send_keys(verification)
           browser.find_element(by=By.XPATH, value='/html/body/div/div/div[2]/div[2]/div[2]/div[3]/button').click()  # 点击登录
           time.sleep(5)  # 等待跳转
           if browser.current_url == self.target:
               break # 登录成功,退出循环
           attempt += 1
           if attempt == 5: # 有时候网页会卡,即使密码正确也登录不上去,每次循环尝试5次登录(一般5次内能登录上去)
               print('请检查账号密码,或稍后再试!')
               browser.quit()
               sys.exit()

# 获取地理位置并提交
       browser.execute_cdp_cmd(
           "Browser.grantPermissions",  # 授权地理位置信息
           {
               "origin": "https://wfw.scu.edu.cn/",
               "permissions": ["geolocation"]
           },
       )
       browser.execute_cdp_cmd(
           "Emulation.setGeolocationOverride",  # 虚拟位置
           {
               "latitude": self.lat,
               "longitude": self.long,
               "accuracy": 50,
           },
       )
       try:  # 提交位置信息
           area_element = WebDriverWait(browser, 10).until(
               EC.element_to_be_clickable((By.NAME, 'area'))
           )
           area_element.click()
       except Exception as error:
           print('get location wrong...\n', error)

time.sleep(2)  # 等待位置信息

"""
       邮箱信息,没有单独写个函数,需要配置QQ邮箱,开启POP3/ SMTP服务,并获取授权码
       因为是提醒自己打卡,所以自己是发件人,自己是收件人
       填入授权码
       """
       # 建立邮箱信息
       my_sender = 'XXX@qq.com'  # 发件人邮箱账号
       my_pass = 'XXX'  # 发件人邮箱密码(当时申请smtp给的口令)
       my_user = 'XXX@qq.com'  # 收件人邮箱账号

browser.find_element(by=By.XPATH, value='/html/body/div[1]/div/div/section/div[5]/div/a').click()  # 提交信息
       try:
           ok_element = WebDriverWait(browser, 3).until(
               EC.element_to_be_clickable((By.XPATH, '/html/body/div[4]/div/div[2]/div[2]'))  # 提交按钮
           )
           ok_element.click()
           print(self.username, 'success!')

WebDriverWait(browser, 3).until(
               EC.presence_of_element_located((By.XPATH, '/html/body/div[5]/div/div[1]'))  # 成功对话框标题
           )
           title_success = browser.find_element(by=By.XPATH, value='/html/body/div[5]/div/div[1]').get_attribute("innerHTML")
           print('From website:', title_success)

msg = MIMEText('打卡成功', 'plain', 'utf-8')
           msg['From'] = formataddr(["终极打卡人", my_sender])  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
           msg['To'] = formataddr(["打工人", my_user])  # 括号里的对应收件人邮箱昵称、收件人邮箱账号
           msg['Subject'] = "打卡提示"  # 邮件的主题,也可以说是标题

server = smtplib.SMTP_SSL("smtp.qq.com", 465)  # 发件人邮箱中的SMTP服务器,端口是465
           server.login(my_sender, my_pass)  # 括号中对应的是发件人邮箱账号、邮箱密码
           server.sendmail(my_sender, [my_user, ], msg.as_string())  # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
           server.quit()  # 关闭连接
       except:
           info = browser.find_element(by=By.CLASS_NAME, value='wapat-title').get_attribute('innerHTML')
           print('From website |', self.username, ':', info)

msg = MIMEText('打卡失败,请手动打卡', 'plain', 'utf-8')
           msg['From'] = formataddr(["终极打卡人", my_sender])
           msg['To'] = formataddr(["打工人", my_user])
           msg['Subject'] = "打卡提示"

server = smtplib.SMTP_SSL("smtp.qq.com", 465)
           server.login(my_sender, my_pass)
           server.sendmail(my_sender, [my_user, ], msg.as_string())
           server.quit()
       browser.quit()

"""
   函数声明:
   调用百度OCR的API,需要输入以下API接口:
           APP_ID = '***'
           API_KEY = '***'
           SECRET_KEY = '***'
   传入截取图片url,传出识别结果字符串
   """
   def Vertification(self, url):

# 创建AipOcr
       """ 你的 APPID AK SK """
       APP_ID = 'XXX'
       API_KEY = 'XXX'
       SECRET_KEY = 'XXX'

client = AipOcr(APP_ID, API_KEY, SECRET_KEY)

# 文字识别高精度版本

""" 读取图片 """
       def get_file_content(url):
           with open(url, 'rb') as fp:
               return fp.read()

image = get_file_content('ver.png')

""" 调用通用文字识别(含位置高精度版) """
       result = client.accurate(image)
       print(str(result))
       res = result['words_result'][0]['words']
       return str(res)

# """ 如果有可选参数 """
       # options = {}
       # options["recognize_granularity"] = "big"
       # options["detect_direction"] = "true"
       # options["vertexes_location"] = "true"
       # options["probability"] = "true"
       #
       # """ 带参数调用通用文字识别(含位置高精度版) """
       # client.accurate(image, options)

if __name__ == '__main__':

"""
   用户输入区:
   学号用户名
   密码(一般为身份证后六位)
   定位地点的经纬度
   """
   username = 'XXX'  # 用户名(学号)
   password = 'XXX'  # 密码
   latitude = 30.630869  # 虚拟位置纬度
   longitude = 104.083748  # 经度

path = '.\chromedriver\chromedriver.exe' #chromedriver路径
   # path = '/usr/bin/chromedriver' # linux服务器上的chromedriver路径
   t = LogIn(user=username, passwd=password, lat=latitude, long=longitude, path=path)
   t.main()

6.运行结果图

Python+腾讯云服务器实现每日自动健康打卡

来源:https://www.cnblogs.com/tuaisen/p/15640592.html

标签:Python,腾讯云服务器,自动打卡
0
投稿

猜你喜欢

  • Python Flask入门之模板

    2023-10-05 01:44:10
  • Python实现SMTP发送邮件详细教程

    2021-05-10 03:01:01
  • Python元素集合的列表切片

    2023-08-08 23:08:57
  • 用electron 打包发布集成vue2.0项目的操作过程

    2024-05-09 15:22:59
  • 网站设计中的面包屑[译]

    2009-03-22 15:42:00
  • SQL查询超时的设置方法(关于timeout的处理)

    2024-01-15 21:07:55
  • MySQL 5.6 (Win7 64位)下载、安装与配置图文教程

    2024-01-20 21:13:52
  • python 机器学习之支持向量机非线性回归SVR模型

    2022-06-17 20:23:55
  • python自动化测试通过日志3分钟定位bug

    2021-09-12 10:11:19
  • graphql---go http请求使用详解

    2024-02-07 08:11:56
  • 纯JavaScript实现的分页插件实例

    2024-06-09 12:08:26
  • asp如何用FSO对象显示一个文本文件?

    2010-06-09 18:41:00
  • 简单了解Django ContentType内置组件

    2022-08-04 08:57:16
  • Python学习之不同数据类型间的转换总结

    2021-10-04 06:06:57
  • flask中使用SQLAlchemy进行辅助开发的代码

    2021-09-10 07:46:43
  • vue+axios+java实现文件上传功能

    2024-04-30 10:40:32
  • Python读取视频的两种方法(imageio和cv2)

    2023-10-04 13:45:06
  • python pprint模块中print()和pprint()两者的区别

    2023-10-18 07:34:18
  • ASP.Net Core MVC基础系列之中间件

    2024-05-09 09:04:47
  • Mysql 数据库双机热备的配置方法

    2010-06-09 19:13:00
  • asp之家 网络编程 m.aspxhome.com