[Python自动化办公]–从网页登录网易邮箱进行邮件搜索并下载邮件附件
使用说明
本文使用Python的selenium库进行操作邮箱登录、固定名称搜索邮件并下载附件,Python版本:3.9.16, selenium版本:4.19.0,EdgeBrowser版本:126.0.2592.87。
准备工作
安装Python及selenium不多赘述,可自行搜索安装,除了具备基本的Python编程知识外还需要了解网页知识。
安装Edge浏览器驱动:
查看当前使用的Edge浏览器版本:设置 -->关于 即可查看
驱动下载地址
下载并解压缩。记住文件路径,后面会用到。(浏览器会定期更新的话需要及时更新驱动)
编写代码
首先给出一段完整的代码,再来分步骤讲解。
完整demo
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from datetime import datetime, timedelta
import timedef input_info():'''用于生成文件名称字符如果你需要自动下载的邮件名称是每天根据日期变化的可以参考此函数进行适当修改'''# 获取当天日期today = datetime.now().date()# 获取当天日期减去2天的日期target_date = today - timedelta(days=2)# 格式化日期为“4月6日”的形式formatted_date = target_date.strftime("%m月%d日").lstrip("0").replace("月0", "月")# 拼接字符串res = formatted_date + "你要的邮件"return resdriver_path = r"C:\Users\JA043204\Desktop\getMail\edgedriver_win64\msedgedriver.exe"
edge_options = Options()
edge_options.use_chromium = True # 如果正在使用新的基于 Chromium 的 Edge,设置为 True
service = Service(executable_path=driver_path)driver = webdriver.Edge(service=service, options=edge_options)# 打开登录页面
driver.get("https://mailh.qiye.163.com/")# 填写用户名和密码
usrname = "yourusrname" # 需替换为自己的用户名
pwd = "yourpwd" # 需替换为自己的密码try:# 在 Selenium 4 中,推荐使用 find_element 方法代替 find_element_by_* 方法driver.find_element("id", "account_name").send_keys(usrname)driver.find_element("id", "password").send_keys(pwd)# 点击登录按钮driver.find_element("id", "submit-btn").click()# 等待一段时间,确保登录成功后的页面加载完成time.sleep(5)# 执行登录后的操作,比如获取用户信息等# 比如,获取登录后的页面标题print(driver.title)# 找到搜索的input框,并输入"质量部基础数据"input_box = driver.find_element(By.XPATH,'//input[@placeholder="搜索邮件"]')input_box.send_keys(input_info())# 发送回车键操作,触发搜索或相应的动作input_box.send_keys(Keys.RETURN)time.sleep(2)# 使用显式等待尝试定位元素target_div = WebDriverWait(driver, 3).until(EC.presence_of_element_located((By.XPATH, ('//span[@class="summary-content summary-content-maxwidth"]'))))target_div.click() # 点击打开邮件time.sleep(2)# 找到邮件后定位到打包下载邮件附件相关元素tar_a = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, '//span[@class="save-all"]')))driver.execute_script("arguments[0].click();", tar_a)finally:# 关闭浏览器if input("是否关闭浏览器? (y/n): ").lower().startswith('y'):driver.quit()
导入必要包
from selenium import webdriver
:- 导入 Selenium 的 WebDriver 类,用于启动浏览器和执行操作。
from selenium.webdriver.edge.service import Service
:- 导入 Edge 浏览器的 Service 类,用于配置和启动 Edge 浏览器的 WebDriver 服务。
from selenium.webdriver.edge.options import Options
:- 导入 Edge 浏览器的 Options 类,用于设置 Edge 浏览器的选项,如设置浏览器启动参数。
from selenium.webdriver.support.ui import WebDriverWait
:- 导入 WebDriverWait 类,用于显式等待页面元素加载并设定等待条件。
from selenium.webdriver.common.by import By
:- 导入 By 类,用于指定查找元素的方法,例如通过 ID、Class Name、XPath 等。
from selenium.webdriver.support import expected_conditions as EC
:- 导入 expected_conditions 模块,这是 WebDriverWait 的一部分,包含了预期条件,如元素可见、元素存在、元素包含文本等。
配置浏览器驱动
driver_path = r"C:\Users\JA043204\Desktop\getMail\edgedriver_win64\msedgedriver.exe" # 替换为准备工作中的路径
edge_options = Options()
edge_options.use_chromium = True # 如果正在使用新的基于 Chromium 的 Edge,设置为 True
service = Service(executable_path=driver_path)driver = webdriver.Edge(service=service, options=edge_options)
打开网页
使用 driver.get()
方法,传入参数为登录界面url。
从浏览器中定位元素
-
从浏览器打开登录界面,然后 按下
F12
打开开发工具。
-
使用检查元素来定位网页内容
先点击检查元素工具图标,然后点击用户名输入框
这样就能快速找到该元素网页源码的位置
使用selenium定位元素
-
通过元素 ID 定位:
使用find_element_by_id
方法可以通过元素的 ID 属性来定位元素。例如:element = driver.find_element_by_id("element_id")
-
通过元素名称定位:
使用find_element_by_name
方法可以通过元素的名称属性来定位元素。例如:element = driver.find_element_by_name("element_name")
-
通过类名定位:
使用find_element_by_class_name
方法可以通过元素的类名来定位元素。注意,如果有多个元素具有相同的类名,它会返回第一个匹配的元素。例如:element = driver.find_element_by_class_name("element_class")
-
通过标签名定位:
使用find_element_by_tag_name
方法可以通过元素的标签名来定位元素。例如:element = driver.find_element_by_tag_name("tag_name")
-
通过链接文本定位:
使用find_element_by_link_text
方法可以通过链接的文本内容来定位元素。例如:element = driver.find_element_by_link_text("Link Text")
-
通过部分链接文本定位:
使用find_element_by_partial_link_text
方法可以通过链接的部分文本内容来定位元素。例如:element = driver.find_element_by_partial_link_text("Partial Link Text")
-
通过 XPath 表达式定位:
使用find_element_by_xpath
方法可以通过 XPath 表达式来定位元素。XPath 是一种强大的定位方式,可以根据元素的层次结构、属性等来精确定位元素。例如:element = driver.find_element_by_xpath("//div[@id='example']/p[1]")
-
通过 CSS 选择器定位:
使用find_element_by_css_selector
方法可以通过 CSS 选择器来定位元素。CSS 选择器也是一种强大的定位方式,可以根据元素的样式、层次结构等来定位元素。例如:element = driver.find_element_by_css_selector("div#example > p:first-child")
在完整demo代码中只用到了元素ID定位和XPath定位,以上是不同的定位方式,可根据个人喜好选择使用,下面再介绍一下啊XPath表达式定位:XPath 是一种用于在 XML 文档中定位和选择元素的查询语言。它同样适用于 HTML 文档,因为 HTML 也可以被视为一种 XML 变体。以下是 XPath 的基本写法和一些常用的表达式:
- 选择元素:
- 绝对路径:从根节点开始的路径,以斜杠
/
开头。例如:/html/body/div
- 相对路径:相对于当前节点的路径,以双斜杠
//
开头。例如://div/p
- 绝对路径:从根节点开始的路径,以斜杠
- 谓语(Predicate):用于过滤元素的附加条件,放在方括号内。
- 例如:
//div[@class='content']
选择 class 属性为 ‘content’ 的 div 元素。
- 例如:
- 选取节点:
nodename
:选择所有指定节点名的元素。例如://div
选择所有 div 元素。*
:选择当前节点的所有子元素。@attribute
:选择当前节点的指定属性。例如://@href
选择所有 href 属性。text()
:选择当前节点的文本内容。
- 逻辑运算符:
and
,or
,not
:用于组合多个条件。
- 轴(Axis):用于指定相对于当前节点的节点集合。
ancestor
,parent
,child
,following-sibling
,preceding-sibling
等。
- 通配符:
*
:匹配任何元素节点。@*
:匹配任何属性节点。
- 函数:
name()
:获取当前节点的名称。contains()
:检查一个字符串是否包含另一个字符串。text()
:获取当前节点的文本内容。
例如,以下是一些示例 XPath 表达式:
//div[@id='content']
:选择 id 属性为 ‘content’ 的所有 div 元素。//a[@href='https://example.com']
:选择所有 href 属性为 ‘https://example.com’ 的 a 元素。//div[@class='main']//p
:选择 class 属性为 ‘main’ 的 div 元素下的所有 p 元素
比如现在我需要定位用户名输入框,那么根据网页源码可以写Xpath表达式为: //input[@id='account_name']
然后再网页元素界面按下 Ctrl+F
会跳出查找框,输入你写好的的XPath表达式后按下回车
可以看到查询结果之后在搜索框右侧有 1 of 1
字样表示当前是符合表达的结果中的唯一一个,定位的位置和刚才查找的网页源码一致,说明是我们想要的结果。
对网页元素进行操作
下面是操作详解:
- 定位元素:为了在网页上进行任何操作,Selenium需要首先找到需要操作的元素。定位元素通常通过选择器来完成,如ID、class、tag name、name、link text、partial link text、css selector或XPath。例如,
driver.find_element_by_id("username")
会找到ID为username
的元素。 - 操作输入框:可以通过
send_keys
方法向输入框(通常是<input>
标签)发送输入,如用户名或密码。例如,username_field.send_keys("myusername")
。 - 点击按钮:使用
click()
方法可以点击按钮或链接。例如,submit_button.click()
会点击ID为submit_button
的按钮。 - 提交表单:通过点击
<form>
标签上的提交按钮,或者直接调用submit()
方法可以在表单提交时触发动作。例如,form.submit()
会提交表单。 - 获取和设置元素属性:可以通过
get_attribute()
方法获取元素的属性值,还可以利用set_attribute()
方法设置属性值。例如,element.get_attribute("class")
会获取元素的class
属性值。 - 执行JavaScript:Selenium提供了一个
execute_script()
方法,可以用来执行任何JavaScript代码。这意味着可以通过JavaScript与DOM交互来完成操作。 - 处理下拉框:可以使用
select_by_visible_text()
,select_by_index()
,select_by_value()
等方法来选择下拉框中的选项。这些方法位于Select
类中。例如,dropdown.select_by_visible_text("option2")
会选择下拉框中的可见文本为option2
的选项。 - 处理弹出框:Selenium提供了的方法来处理JavaScript警告、确认框和提示框。例如,
alert.accept()
会确认一个警告框。 - 切换窗口:当网页上打开新窗口时,Selenium提供的方法
switch_to.window
可以用来切换到另一个窗口或标签页。例如,`driver.switch_to.window
对于登录界面我们要做的是,输入用户名和密码然后按下登录按钮也就是用到了 send_keys()
和 click()
方法
但是网页中的某些元素被JavaScript或css限制不可见或者不可点击,那么无法使用使用 click()
,这时候需要通过execute_script()
来完成点击操作。
比如完整demo中的 driver.execute_script("arguments[0].click();", tar_a)
然后解释一下下面这段代码
tar_a = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, '//span[@class="save-all"]')))
WebDriverWait(driver, 5)
:WebDriverWait
是 Selenium 提供的等待方式,它会在指定的时间内等待某个条件成立后继续执行下面的代码。driver
是你创建的 WebDriver 实例,用于控制浏览器的操作。5
是最长等待时间,即最多等待5秒。
.until()
方法:until()
方法是WebDriverWait
的一个函数,它接受一个条件(Expected Condition,EC)作为参数,并且会不断地调用这个条件,直到返回True
或者超过最长等待时间为止。
EC.presence_of_element_located((By.XPATH, '//span[@class="save-all"]'))
:EC.presence_of_element_located
是预定义的一个条件,表示等待直到页面上至少出现一个满足条件的元素。(By.XPATH, '//span[@class="save-all"]')
是定位元素的方式,指定了使用 XPath 来找到页面上class
属性为"save-all"
的span
元素。
tar_a = ...
:- 最后将等待到的元素赋值给变量
tar_a
,这样就可以进一步操作这个元素了。
- 最后将等待到的元素赋值给变量
综上所述,这段代码的作用是等待页面中的一个 span
元素,该元素的 class
属性为 "save-all"
,等待时间最多为5秒。一旦找到该元素,就将它赋值给变量 tar_a
,以便后续对该元素进行操作,比如点击或者获取其文本内容等。
an[@class=“save-all”]')是定位元素的方式,指定了使用 XPath 来找到页面上
class属性为
"save-all"的
span元素。 4.
tar_a = …: - 最后将等待到的元素赋值给变量
tar_a`,这样就可以进一步操作这个元素了。
综上所述,这段代码的作用是等待页面中的一个 span
元素,该元素的 class
属性为 "save-all"
,等待时间最多为5秒。一旦找到该元素,就将它赋值给变量 tar_a
,以便后续对该元素进行操作,比如点击或者获取其文本内容等。
最后,对于网页验证这一步骤在这个示例中不涉及,可以从代码中启动网页,填写信息登录后获取手机验证码并填写,之后一段时间网站cookie会保留登录信息。