今天写一下python加selenium自动化登录,包括获取邮箱验证码和普通验证码两种。
一:邮件验证码的。
用pip安装selenium
pip install selenium
from selenium import webdriver
首先是selenium 模块。
driver = webdriver.Chrome("./chromedriver.exe")
# 请求百度 链接
url = 'http://www.baidu.com'
# 执行操作,打开浏览器输入url
driver.get(url)
运行上面的脚本如果打开一个新的谷歌浏览器页面并打开了百度页面证明selenium没有问题。如果报错大概率driver版本不对,需要下载对应你自己
浏览器版本的driver版本,也可以看下迷龙大佬公众号测试开发实战课写的Python+requests下载与当前Chrome对应的chromedriver可以自动下载最新的driver。
替换打开地址为我们要登录的网址。在用户名输入框右键。
观察这个元素。我这里这个元素有id,id一般值是唯一的。所以我们可以通过id定位这个元素。
username="用户名"
password="密码"
browser.find_element_by_id("accountId").clear() #清空元素内容
browser.find_element_by_id("accountId").send_keys(username) #向元素中填入内容
browser.find_element_by_id("password").clear()
browser.find_element_by_id("password").send_keys(password)
除了通过id还是classname,xpath等方法,读者按照自己所登陆的元素具体分析。
checkbutton = browser.find_element_by_class_name("check_type") #查找class名字为check_type的元素
checkbutton.find_elements_by_tag_name("span")[1].click() #选择上面元素子元素的第二个span标签元素并点击
接下来就是发送邮箱验证码及获取验证码并点击登录了。
browser.find_element_by_id("获取邮箱验证码的id").click() #获取验证码
time.sleep(3) #为了保证邮件发送了等待三秒
result = get_content() #获取邮箱验证码的函数
result=re.findall(r'\d{6}', result) #验证码为六位数字通过正则获取
browser.find_element_by_id("验证码输入框id").send_keys(result) #输入验证码
browser.find_element_by_id("登录id").click() # 提交按钮
下面是获取通过邮箱获取最新邮件的代码。使用的是163邮箱,注意要打开
pop服务才可以。
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
import poplib
# 输入邮件地址, 口令和POP3服务器地址:
email = '用户名'#input('Email: ')
password = '授权码'#input('Password: ')
pop3_server = 'pop.163.com'#input('POP3 server: ')
result=""
def guess_charset(msg):
charset = msg.get_charset()
if charset is None:
content_type = msg.get('Content-Type', '').lower()
pos = content_type.find('charset=')
if pos >= 0:
charset = content_type[pos + 8:].strip()
return charset
def decode_str(s):
value, charset = decode_header(s)[0]
if charset:
value = value.decode(charset)
return value
def print_info(msg, indent=0):
if indent == 0:
for header in ['From', 'To', 'Subject']:
value = msg.get(header, '')
if value:
if header=='Subject':
value = decode_str(value)
else:
hdr, addr = parseaddr(value)
name = decode_str(hdr)
value = u'%s <%s>' % (name, addr)
print('%s%s: %s' % (' ' * indent, header, value))
if (msg.is_multipart()):
parts = msg.get_payload()
for n, part in enumerate(parts):
print('%spart %s' % (' ' * indent, n))
print('%s--------------------' % (' ' * indent))
print_info(part, indent + 1)
else:
content_type = msg.get_content_type()
if content_type=='text/plain' or content_type=='text/html':
content = msg.get_payload(decode=True)
charset = guess_charset(msg)
if charset:
content = content.decode(charset)
print('%sText: %s' % (' ' * indent, content + '...'))
global result
result=content
else:
print('%sAttachment: %s' % (' ' * indent, content_type))
def get_content():
# 连接到POP3服务器:
server = poplib.POP3(pop3_server)
# 可以打开或关闭调试信息:
server.set_debuglevel(1)
# 可选:打印POP3服务器的欢迎文字:
# print(server.getwelcome().decode('utf-8'))
# 身份认证:
server.user(email)
server.pass_(password)
# stat()返回邮件数量和占用空间:
# print('Messages: %s. Size: %s' % server.stat())
# list()返回所有邮件的编号:
resp, mails, octets = server.list()
# 可以查看返回的列表类似[b'1 82923', b'2 2184', ...]
# print(mails)
# 获取最新一封邮件, 注意索引号从1开始:
index = len(mails)
resp, lines, octets = server.retr(index)
# lines存储了邮件的原始文本的每一行,
# 可以获得整个邮件的原始文本:
msg_content = b'\r\n'.join(lines).decode('utf-8')
# 稍后解析出邮件:
msg = Parser().parsestr(msg_content)
print_info(msg)
# 可以根据邮件索引号直接从服务器删除邮件:
# server.dele(index)
# 关闭连接:
server.quit()
return result
if __name__ == '__main__':
result=get_content()
print(result)
下面讲一下普通验证码。首先要保存验证码。这里用了两个方法。
方法一:
通过url获取下载
url = browser.find_element_by_id("checkCodeImg").get_attribute('src') # 验证码地址
valcode = requests.get(url)
path = "code.png"
temp = open(path, "wb")
temp.write(valcode.content)
temp.close()
方法二:
截图整个页面保存本地以后,定位验证码位置剪切。
imgelement = browser.find_element_by_id("验证码id")
browser.save_screenshot('printscreen.png')
# 定位验证码
location = imgelement.location # 获取验证码x,y轴坐标
size = imgelement.size # 获取验证码的长宽
rangle = (int(location['x']), int(location['y']), int(location['x'] + size['width']),
int(location['y'] + size['height'])) # 写成我们需要截取的位置坐标
i = Image.open("printscreen.png") # 打开截图
frame4 = i.crop(rangle) # 使用Image的crop函数,从截图中再次截取我们需要的区域
path='code.png'
frame4.save(path) # 保存我们接下来的验证码图片 进行打码
解析验证码,输入验证码提交。
code = Analysis(path)
browser.find_element_by_id("验证码输入框id").clear() # 验证码填写地址
browser.find_element_by_id("验证码输入框id").send_keys(code) # 验证码填写地址
browser.find_element_by_id("提交id").click() # 提交按钮
下面是具体的解析验证码函数。
def Analysis(path):
setThreshold(path,110)
image = Image.open(path) #图片二值化
# print (image.format, image.size, image.mode)
# image.show()
a = pytesseract.image_to_string(image,lang="eng",config='--psm 10 --oem 3 -c tessedit_char_whitelist=0123456789')
print(a)
# print(len(a))
return a
def setThreshold(path,threshold=130):
img = Image.open(path)
# 模式L”为灰色图像,它的每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同的灰度。
Img = img.convert('L')
Img.save(path)
# 自定义灰度界限,大于这个值为黑色,小于这个值为白色
table = []
for i in range(256):
if i < threshold:
table.append(0)
else:
table.append(1)
# 图片二值化
photo = Img.point(table, '1')
photo.save(path)
今天就到这里吧,下班溜了。明天水个sql查数据库存redis然后测试后再存redis对比两次数据库变化的。