This project is completed with python+selenium+ddddocr+email. Selenium is used because my technology is limited and I can't crack the js encryption of the login interface (in Shaanxi); Ddocr is an open source verification code recognition project on github, with a high recognition rate; Reminders are sent by email.
The reason for doing this project is that every week the League Secretary has to check who hasn't studied one by one, and then remind one by one. It's too hard, so I made this script to reduce the work of the League secretary.
At present, I have only realized in Shaanxi. Friends in other regions can refer to my implementation ideas and change them.
Finished products and use course in Shaanxi: One click reminder tool for Youth Learning - [ Shaanxi region ]_ Beep beep beep_ bilibili
catalogue
1.selenium+webdriver configuration
3. Analyze the data through token
2, Verification code identification module
tips: a module is a file
1, Login + analysis module
1.selenium+webdriver configuration
For example, you have edge browser on your computer, and then go to selenium's official website to download the corresponding version of webdriver of edge browser.
After downloading, unzip the driver to the project directory, and then call it like this (I use this to facilitate packaging):
driver = webdriver.Edge(executable_path='msedgedriver.exe')
You can also configure environment variables. Please Baidu for details.
2. Login + get token
You can see my login() function
Here's an explanation of why you don't save the token, because the valid period of the Shaanxi website token is only 2 hours.
3. Analyze the data through token
You can see my getRequest() function
import requests import json from selenium import webdriver import time from LogSystem import writeLog import base64 from io import BytesIO from PIL import Image import re from OCR import ddocr class qndxx: def __init__(self, account, passwd): self.account = account self.password = passwd self.token = "" def base64_to_image(self, base64_str): base64_data = re.sub('^data:image/.+;base64,', '', base64_str) byte_data = base64.b64decode(base64_data) image_data = BytesIO(byte_data) img = Image.open(image_data) return img def login(self): # There is a token value in the successful cookie url = "https://www.sxgqt.org.cn/bgsxv2/login?redirect=%2Fbgsxv2%2Freunion%2Fmember%2FmemberList" try: driver = webdriver.Edge(executable_path='msedgedriver.exe') except Exception: print("Please update Edge Browser to latest version-ver100") return driver.implicitly_wait(3) # Recessive waiting for 3s # tkinter.messagebox.showerror('prompt ',' just enter the verification code, do not click the login button on the web page ') while 1: driver.get(url) time.sleep(0.5) driver.find_element("xpath", "//*[@id='pane-first']/div/div/form/div[1]/div/div/input").send_keys( self.account) driver.find_element("xpath", "//*[@id='pane-first']/div/div/form/div[2]/div/div/input").send_keys( self.password) ce = driver.find_element("xpath", "//*[@id='pane-first']/div/div/form/div[3]/div/img").get_attribute("src") img = self.base64_to_image(ce) img.save('code.png') verfCode = ddocr('code.png') # tkinter.messagebox.showerror('prompt ',' enter the verification code and then close the pop-up window ') driver.find_element("xpath", "//*[@id='pane-first']/div/div/form/div[3]/div/div/input").send_keys( verfCode) time.sleep(1) driver.find_element("xpath", "//*[@id='pane-first']/div/div/form/button").click() time.sleep(1) cur_cookies = driver.get_cookies() if cur_cookies[0]["name"] == "token": break # print(cur_cookies[0]["value"]) self.token = cur_cookies[0]["value"] # with open("222222.txt", "w") as f: # f.write(json.dumps(cur_cookies)) driver.quit() return True def getRequest(self): list_meixue = [] if self.login(): head = { "token": self.token, "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.68" } url = "https://www.sxgqt.org.cn/bgsxapiv2/regiment?page=1&rows=100&keyword=&oid=100612025&leagueStatus=&goHomeStatus=&memberCardStatus=&isPartyMember=&isAll=" url_qing = "https://www.sxgqt.org.cn/bgsxapiv2/regiment/youngList?oid=100612025&keyword=&isAll=&page=1&rows=15" text_data = requests.get(url=url, headers=head).text data = json.loads(text_data) # print(data) for line in data['data']['data']: if line["isStudy"] == "no": list_meixue.append(line['realname']) text_data = requests.get(url=url_qing, headers=head).text data = json.loads(text_data) # print(data) for line in data['data']['data']: if line["isStudy"] == "no": list_meixue.append(line['realname']) if len(list_meixue) == 0: print("All the major studies of this period have been completed") else: line1 = "common%d I didn't study this period" % len(list_meixue) line2 = " ".join(list_meixue) print(line1) print(line2) writeLog(line1) writeLog(line2) return list_meixue
2, Verification code identification module
import ddddocr def ddocr(file): try: ocr = ddddocr.DdddOcr() with open(file, 'rb') as f: img_bytes = f.read() res = ocr.classification(img_bytes) return res except: print("Failed to obtain verification code, please continue!")
3, Mail sending module
import smtplib from email.mime.text import MIMEText from email.header import Header from email.mime.multipart import MIMEMultipart def send_mail(accountList, eAccount, eAuthorizationCode, eTitle, eContent): msg_from = eAccount # Sender email passwd = eAuthorizationCode # It's the authorization code above to_addr = accountList # Recipient email, list # print(to) # Set message content # The MIMEMultipart class can put anything msg = MIMEMultipart() content = eContent # Add content msg.attach(MIMEText(content, 'plain', 'utf-8')) # Set message subject msg['Subject'] = eTitle # Set sender information msg['From'] = 'Youth Learning reminder Bot' # Set recipient information msg['To'] = 'Students without youth study' # Start sending try: temp_flag_email = msg_from.split("@")[-1] if temp_flag_email == "qq.com": # Send via SSL, server address and port s = smtplib.SMTP_SSL("smtp.qq.com", 465) elif temp_flag_email == "163.com": s = smtplib.SMTP_SSL("smtp.163.com", 465) elif temp_flag_email == "gmail.com": s = smtplib.SMTP_SSL("smtp.gmail.com", 465) elif temp_flag_email == "126.com": s = smtplib.SMTP_SSL("smtp.126.com", 465) else: # If there is no match, QQ email will be used by default s = smtplib.SMTP_SSL("smtp.qq.com", 465) # Login mailbox s.login(msg_from, passwd) # Start sending res = s.sendmail(msg_from, to_addr, msg.as_string()) if len(res) != 0: print("Sending failed, error code:", res) s.quit() print("Mail sent successfully") except smtplib.SMTPException as e: print("Mail sending failed!!", e)
4, Program entry module
Read the configuration from the config file before starting the program
import configparser import os from qndxx import qndxx from send_emile import send_mail # Configuration initialization cf = configparser.ConfigParser() cf.read("config.ini", encoding="utf8") account = cf.get("accountPart", "account") password = cf.get("accountPart", "password") eAccount = cf.get("sendEmail", "eAccount") eAuthorizationCode = cf.get("sendEmail", "eAuthorizationCode") eTitle = cf.get("emailContent", "eTitle") eContent = cf.get("emailContent", "eContent") print("Configuration initialization--complete") print("Please check before use config Is the file configured correctly") # print("mail sending test mode, recipient: xxxx@qq.com ") # print("click the OK button in the pop-up window, and the program will continue to run") qn = qndxx(account, password) list_meixue = qn.getRequest() list_email = [] if input("Send reminder email(1 Send, 0 don't send): ") == "1": for line in list_meixue: try: email = cf.get("emailList", line) list_email.append(email) except Exception: print(line + "\t Mailbox not initialized") if len(list_meixue) == len(list_email): send_mail(list_email, eAccount, eAuthorizationCode, eTitle, eContent) else: print("Please in config File initializes everyone's mailbox before running") os.system("pause")
config.ini file configuration
[accountPart]
; Fill in the account and password of Shaanxi Youth big data service platform, https://www.sxgqt.org.cn/bgsxv2/login?redirect=%2Fbgsxv2%2Freunion%2Fmember%2FmemberList
account=6666666666
password=123456
[sendEmail]
; To fill in your own email account, you need to open SMTP service
eAccount=xxxxx@qq.com
; Authorization code
eAuthorizationCode=xxxxxxxxxxx
[emailList]
; Fill in the name and email address of class members. There can be no blank space. If it is not filled in, you can only use the function of viewing the list of students who have not studied
Zhang San= 66666666@qq.com
Li Si= 123456@qq.com
[emailContent]
; Fill in the header and content of the message, and no line breaks are allowed
eTitle = please learn youth learning now!!
eContent = please learn youth learning now!! -- xxx remind Bot
V. log module
import time # LogText: data to be recorded def writeLog(LogText=''): # Formatted as 2021-08-05 09:42:08 time_true = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) filename = "./Log.txt" with open(filename, 'a+', encoding="utf8") as f: f.writelines([time_true, "\t", LogText + "\n"])
Finally, if you need specific explanation (solution ideas of each part + packaging tutorial), you can leave a message. If you need more, I will issue a detailed article to explain.