python自动化获取Google邮箱验证码
2023-4-26
| 2023-4-25
0  |  0 分钟
type
Post
status
Published
date
Apr 26, 2023
slug
09
summary
tags
Python
开发
category
技术分享
icon
password
在参考博主代码的基础上,进行改进,这是原文链接:https://blog.csdn.net/weixin_38640052/article/details/118240671
 
以微软账户注册为例,我通过爬虫,向微软提交注册信息,使用谷歌邮箱接收注册验证码,通过python实现自动化读取邮箱中最新未读邮件,提取出验证码。

一、改进内容

1.在获取全部未读取的邮件时,应使用self.conn.uid('search', None, "UNSEEN") ,
而不是 self.conn.uid('search', None, "ALL") 。
 
前者仅查询未读取的邮件,而后者查询全部邮件,有可能导致遍历过多的邮件并且浪费时间。
 
2.由于原代码中有很多个 try 和 except 语句,可能会导致信息不够详细,很难确定导致问题的原因。为了定位问题,可以尝试使用 Python 的 logging 模块来记录程序的运行日志
 
添加以下行,用于记录日志:
import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
 
在 get_list_message_two 函数中,我们可以添加以下行,用于记录每次查找验证码的详细日志:
logging.debug(f'Trying to find verification code in email from {mail_from}') if re.search(r'\b\d{4}\b', body): code = re.search(r'\b\d{4}\b', body).group() logging.info(f'Found verification code {code} in email from {mail_from}') return code else: logging.debug(f'No verification code found in email from {mail_from}')
 
这样,当 run() 函数运行时,日志信息会被记录到控制台。如果某个操作失败了,可以查看日志信息来确定导致问题的原因。
 
3.由于验证码的格式不同,我们需要相应地修改正则表达式:
 
regex = r'(?:[^\d]|^)(\d{4})(?:\D|$)'
notion image
 

二、修改后的完整代码:

import imaplib import email import re import logging class Receiver: def __init__(self, email_user, email_password, imap_server): self.email_user = email_user self.email_password = email_password self.imap_server = imap_server self.imap_port = 993 # IMAP协议专用端口,该端口可根据各个邮箱厂家的协议绑定 self.connection = self.connect_mail() def connect_mail(self): connection = imaplib.IMAP4_SSL(host=self.imap_server, port=self.imap_port) connection.login(self.email_user, self.email_password) connection.list() # 列出邮箱中所有的列表,如:收件箱、垃圾箱、草稿箱等 connection.select('INBOX') # 选择收件箱(默认) return connection def get_mail_list(self): # 使用 "UNSEEN" 标记获取未读的邮件列表 result, data = self.connection.uid('search', None, "UNSEEN") mail_id_list = data[0].split() mail_id_list.reverse() # 将邮件列表反转,以便处理最新的邮件 return mail_id_list def get_email_body(self, message): try: # 判断邮件是否为多部分的 if message.is_multipart(): # 邮件为多部分的,进一步获取它的第一部分 return self.get_email_body(message.get_payload(0)) else: return message.get_payload(None, decode=True) except: return '' def get_verification_code(self, email_body, sender): # 定义验证码的正则表达式 regex_pattern = r'(?:[^\d]|^)(\d{4})(?:\D|$)' pattern = re.compile(regex_pattern) logging.debug(f'尝试在来自 {sender} 的邮件中查找验证码') match = pattern.search(email_body) # 如果找到了验证码,记录相关信息 verification_code = match.group() if match is not None else None if verification_code is not None: logging.info(f'在来自 {sender} 的邮件中找到验证码 {verification_code}') else: logging.debug(f'未在来自 {sender} 的邮件中找到验证码') return verification_code def get_new_verification_code(self): # 获取未读的邮件列表 mail_id_list = self.get_mail_list() # 处理最新的邮件 for mail_id in mail_id_list: result, data = self.connection.uid('fetch', mail_id, '(RFC822)') self.connection.uid('STORE', mail_id, '+FLAGS', '\\Seen') # 将邮件标记为已读 email_message = email.message_from_bytes(data[0][1]) try: email_subject = email.header.make_header(email.header.decode_header(email_message['SUBJECT'])) email_sender = email.header.make_header(email.header.decode_header(email_message['From'])) logging.info("邮件主题 --- [%s]", email_subject) logging.info("邮件发送者 --- [%s]", email_sender) # 判断发送者和邮件主题是否包含关键词 if 'account-security-noreply@accountprotection.microsoft.com' in str(email_sender): try: email_body = str(self.get_email_body(email_message), encoding='utf-8') # 提取验证码 verification_code = self.get_verification_code(email_body, email_sender) if verification_code is not None: print(f'最新的验证码为:{verification_code}') return verification_code except Exception as error: logging.error(f'解析邮件正文时发生错误: {error}') except Exception as error: logging.error(f'解析邮件标题时发生错误: {error}') def run(self): try: self.get_new_verification_code() except Exception as error: logging.error(f'处理邮箱时发生错误: {error}') finally: self.connection.logout() if __name__ == '__main__': # 设置日志级别为 DEBUG,记录所有日志信息,可以根据需要修改该参数 logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') # 修改以下三个参数为实际账户的参数 email_user = 'your_email_address' email_password = 'your_email_password' imap_server = 'your_imap_server_address' email_receiver = Receiver(email_user, email_password, imap_server) email_receiver.run()
 
运行代码后,让我们在控制台查看下日志信息,从而了解代码的运行情况。如果你需要更改日志级别,只需修改 basicConfig 中的 level 参数即可。
notion image
 
代码执行完毕后,我们查看下谷歌邮箱后台,自动从未读状态变为已读取。
notion image
 

三、衍生用法

你可以修改代码,将接收到的验证码传递给其它程序,剩下的步骤就看你的想象力了。
技术分享
  • Python
  • 开发
  • 抱歉,我忘了纪念昨天反众
    目录