每日主动衰弱打卡(Python+腾讯云服务器)
1.配置须要
python3.7,Chrome或者Edeg浏览器,Chrome驱动或者Edge驱动
#须要配置selenium库,baidu-aip库,pillOW库,在终端执行以下命令pip install seleniumpip install pillowpip 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 seleniumpip3 install pillowpip3 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-chromebaseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearchenabled=1gpgcheck=1gpgkey=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 zipunzip 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 sysimport timefrom aip import AipOcrfrom selenium import webdriverfrom selenium.webdriver.support.wait import WebDriverWaitfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.chrome.service import Servicefrom PIL import Imageimport smtplibfrom email.mime.text import MIMETextfrom email.utils import formataddrclass 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()
运行后果图: