邮箱密码更新

起因

公司邮箱因安全因素,每 3 个月,就必须重新设置一次密码;受够了每 3 个月就重新更新一下密码的日子。就写个脚本,设置一个定时任务,每 3 个月就去更新一下密码,这样就舒服了。

基础依赖配置

以下是在 OSX 系统上的操作

  • 安装扩展

python3 -m pip install selenium

  • 下载驱动

官网下载 : https://github.com/mozilla/geckodriver/
我的镜像 : https://github.com/AIRKcn/resources/blob/master/python/geckodriver-v0.26.0-macos.tar.gz

  • 安装驱动
tar zxvf geckodriver-v0.26.0-macos.tar.gz
cp ~/Downloads/geckodriver /usr/local/bin

在命令行中通过 geckodriver -V 能正常看到版本信息就说明已经安装成功了。

代码

主脚本代码基于 python3,文件名 update_my_mail_password.py,内容如下

'''
使用模拟浏览器方式请求公司邮箱服务,并完成邮箱密码的更新
'''
from selenium import webdriver
import os, time

user = {
	'username': u'xxxxx', # username of email
	'domain': u'mail.com', # domain of email
	'password': u'password', # normal password
	'temp': u'tmp_password', # middle of change password for update
}

class MailBox:
	# email homepage
	start_url = 'https://web.mail.com/'
	# browser client object
	c = False

	current = False

	def init(self):
		if self.c is not False:
			return self.c

		self.c = webdriver.Firefox()

		time.sleep(1)

	def update_password(self):
		# 设置
		time.sleep(1)
		print('1. 打开设置面板 (1 sec)')
		self.c.find_element_by_css_selector('div.icon[data-trigger="setting"]').click()
		time.sleep(1)

		# 邮箱密码
		print('2. 邮箱密码 选项页 (1 sec)')
		self.c.find_element_by_css_selector('li[data-trigger="account.password"]').click()
		time.sleep(1)

		print('填写邮箱密码变更 ... 用临时密码替换原密码')
		self._update_password(user['password'], user['temp'])
		print('恢复邮箱密码变更 ... 再用原始密码更新')
		self._update_password(user['temp'], user['password'])

		return True

	def _update_password(self, old, new):
		# 修改密码
		print('3. 打开修改密码表单 (2 sec)')
		self.c.find_element_by_css_selector('button[data-action="editPwd"]').click()

		time.sleep(2)
		# 填写邮箱旧密码 / 新密码 / 确认新密码
		js = []
		js.append("jQuery('input[name=\"oldPassword\"]').val('"+old+"'); ")
		js.append("jQuery('input[name=\"newPassword\"]').val('"+new+"'); ")
		js.append("jQuery('input[name=\"rePassword\"]').val('"+new+"'); ")
		js.append("jQuery('input[name=\"oldPassword\"]').focus(); ")
		js_seg = "\n".join(js)
		print('填用户密码信息 ... (3 sec)')
		self.c.execute_script(js_seg)
		self.c.find_element_by_css_selector('input[name="oldPassword"]').click()
		time.sleep(2)
		# 保存
		self.c.find_element_by_css_selector('button[data-action="changePwd"]').click()
		print('保存完成! (3 sec)')
		time.sleep(3)
		return True

	def login_mailbox(self):
		if self.current is False:
			# open start page
			self._login_auth()
		else:
			self._return_mailbox()

	'''
	登录邮箱首页
	'''
	def _login_auth(self):
		self.c.get(self.start_url)
		print('打开 Web 邮箱首页 ... (3 secs)')
		time.sleep(3)
		js = "document.getElementById('uid').setAttribute('value', '"+user['username']+"');"
		print('填写用户名 ... ' + user['username'])
		self.c.execute_script(js)

		js = "document.getElementById('domain').setAttribute('value', '"+user['domain']+"');"
		print('填写邮箱后缀 ... ' + user['domain'])
		self.c.execute_script(js)

		js = "document.getElementById('password').setAttribute('value', '"+user['password']+"');"
		print('填写邮箱原始密码 ... ******')

		self.c.execute_script(js)
		js = "document.getElementById('face').setAttribute('value', 'XT5');"
		self.c.execute_script(js)

		js = "document.getElementById('saveUsername').click();"
		self.c.execute_script(js)

		self.c.find_elements_by_class_name('submit')[0].click()
		print('提交用户信息,登录邮箱首页 ... (5 sec)')
		time.sleep(5)

		self.current = 'MAILBOX'
		return True

	'''
	返回邮箱首页
	'''
	def _return_mailbox(self):
		self.c.find_element_by_css_selector('.logo a[data-trigger="mail.welcome"]').get_attribute('class').click()
		print('返回邮箱首页 ... (5 sec)')
		time.sleep(5)
		self.current = 'MAILBOX'
		return True

	'''
	关闭浏览器
	'''
	def close(self):
		print('关闭浏览器')
		self.c.close()

b = MailBox()
b.init()
b.login_mailbox()
b.update_password()
b.close()

更新密码

在脚本所在目录执行

python3 update_my_mail_password.py

静静等待代码更新成功吧!

说明

以上代码只是一个功能框架的思路描述

  • 我们使用邮箱是允许更新密码后,再次更新近期历史使用过的密码的,所以这个方法是可以成功的,如果密码不允许设置之前使用过的,则需要进行多次更新密码 比如 1 -> 2 -> 3 -> 4 -> 5 -> 1,其中数字表示密码内容。
  • 不同的邮箱的页面结构有所不同,需要自行处理。
  • 里面有很多丑陋的 time.sleep() 暂时还没有细想用什么方式去处理更好。

总之代码里还有很多可以提升和优化的地方,一个小时的作品,就先这样吧,实用为王,遇到问题再改吧。

参考

赞赏