针对常见的验证机制:验证码进行分析和识别,可以使用传统和 OCR 技术或者基于神经网络的机器学习技术
使用一个合适的技术将登录网站 1 的验证码进行识别,并由代码自动登录。注意事项:所有信息必须由代码自动填入并且自动操作,如果人工填入任何信息或使用人工交互,此项目不得分。
import time
import numpy as np
import pytesseract
from PIL import Image
import re
from selenium import webdriver
from retrying import retry
from io import BytesIO
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import TimeoutException
# retrying库是用来设置浏览器重登次数的,io库是用来获取图片的
# 将处理验证码的方法封装成一个函数方便调用
def process_image(image):
"""
图片处理函数提取出正确的验证码
:param image: 验证码图片
:return: 返回字符串
"""
# 将图片转换为灰度图像,只有黑和白两种颜色
demo = image.convert('L')
# 将图像转换为多维数组
arr = np.array(demo)
# 设置灰度阈值
threshold = 100
# 进行筛选,超过阈值的像素变为白色,没有超过的变为黑色
arr = np.where(arr > threshold, 255, 0)
# 将筛选过的数组又转换为图像
final_image = Image.fromarray(arr.astype('uint8'))
# 将图像内容识别为文本
txt = pytesseract.image_to_string(final_image)
# 匹配
result = re.sub(r'\W', "", txt)
return result
# 设置了10次重登次数,当函数返回结果为false的时候就进行重试'
@retry(stop_max_attempt_number=10, retry_on_result=lambda x: x is False)
css-selector 元素定位方式
driver.find_element(By.CSS_SELECTOR, '[value="1"]')
driver.find_element(By.CSS_SELECTOR, '.a.b.c.d[value="1"]')
#
表示 id 属性.
表示 class 属性[]
表示所有属性:[id="1"]
, [class="a"]
a
input[value="1"]
, input 标签和 value 值组合去定位>
表示父子元素之间的关系
div > input
表示我们要找的元素有一个父节点是 divdiv#id input.class
id="id"
的 div 元素,在该 div 元素的子孙节点中有个 input 标签,该 input 标签中有个class="class"
的属性,我们要定位的就是这个 input 标签
<...>
-
browser.find_element(By.CSS_SELECTOR, '.username input[type="text"]').send_keys('admin')
-
browser.find_element(By.CSS_SELECTOR, '.password input[type="password"]').send_keys('admin')
-
browser.find_element(By.CSS_SELECTOR, '.captcha input[type="text"]').send_keys(txt)
-
browser.find_element(By.CSS_SELECTOR, '.login').click()
# 设置登录函数
def login():
# 模拟浏览器访问练习网址
browser.get('https://captcha7.scrape.center/')
# 找到用户名输入这个节点并输入admin用户名
browser.find_element(By.CSS_SELECTOR, '.username input[type="text"]').send_keys('admin')
# 同理,找到密码输入这个节点并输入admin
browser.find_element(By.CSS_SELECTOR, '.password input[type="password"]').send_keys('admin')
# 验证码节点
captcha = browser.find_element(By.CSS_SELECTOR, '#captcha')
# 获取验证码图片
image = Image.open(BytesIO(captcha.screenshot_as_png))
# 调用函数处理图片识别验证码
txt = process_image(image)
# 输入验证码
browser.find_element(By.CSS_SELECTOR, '.captcha input[type="text"]').send_keys(txt)
# 点击登录按钮
browser.find_element(By.CSS_SELECTOR, '.login').click()
# 当登录成功这个文本所在元素出现说明登录成功,页面保留10秒后退出浏览器
try:
WebDriverWait(browser, 10).until(ec.presence_of_element_located((By.XPATH, '//h2[contains(., "登录成功")]')))
time.sleep(10)
browser.close()
return True
except TimeoutException:
return False
模拟浏览器并调用登录函数
'设置模拟chrome浏览器并调用登录函数'
if __name__ == '__main__':
browser = webdriver.Chrome()
login()
实验要求 2
实现对于带有验证登录方式(如验证码,滑动条,拼图,语序点击,空间推理,图文点击等)的常见网站
实验过程
登录 csdn,验证方式:滑动条
导入的包
# coding=utf-8
import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
class Login():
# 打开浏览器驱动
def __init__(self):
self.url = 'https://passport.csdn.net/login?code=applets'
self.browser = webdriver.Chrome()
# 获取登录按钮对象 选择 账号密码登录
def get_pass_button(self):
button = self.browser.find_element(By.XPATH, '/html/body/div[2]/div/div[2]/div[2]/div[1]/div[1]/div[1]/span[4]')
return button
# 打开网址,输入用户名。密码
def open(self, username, password):
self.browser.get(self.url)
self.get_pass_button().click()
self.browser.find_element(By.XPATH, '//input[@autocomplete="username"]').send_keys(username)
time.sleep(2)
self.browser.find_element(By.XPATH, '//input[@autocomplete="current-password"]').send_keys(password)
# 调用 open方法,输入用户名。密码,
# 调用 get_geetest_button方法,点击按钮
def log(self):
# 输入用户名密码
self.open('***', '***')
time.sleep(2)
# 点击登录按钮
self.browser.find_element(By.XPATH, '//button[@class="base-button"]').click()
time.sleep(2)
# 获取拖拽的滑动验证码块
# 按钮xpath
slideblock = self.browser.find_element(By.XPATH, '//*[@id="nc_1_n1z"]')
# 鼠标点击滑动块不松开
ActionChains(self.browser).click_and_hold(slideblock).perform()
# 将圆球滑至相对起点位置的 右边xx
ActionChains(self.browser).move_by_offset(xoffset=80, yoffset=0).perform()
ActionChains(self.browser).move_by_offset(xoffset=160, yoffset=80).perform()
ActionChains(self.browser).move_by_offset(xoffset=260, yoffset=160).perform()
time.sleep(1)
# 放开滑动块
ActionChains(self.browser).release(slideblock).perform()
time.sleep(10)
# 关闭浏览器,释放资源
# self.browser.close()
# 程序主入口
if __name__ == '__main__':
login = Login()
login.log()