Python爬虫学习笔记之极限滑动验证码的识别
代码:
import time
from io import BytesIO
from PIL import Image
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC EMAIL = '' # 邮箱 密码需要自己注册
PASSWORD = ''
BORDER = 6
INIT_LEFT = 60 class CrackGeetest():
def __init__(self):
self.url = 'https://account.geetest.com/login'
self.browser = webdriver.Chrome()
self.wait = WebDriverWait(self.browser, 20)
self.email = EMAIL
self.password = PASSWORD def __del__(self):
self.browser.close() def get_geetest_button(self):
"""
获取初始验证按钮
:return:
"""
button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_radar_tip')))
return button def get_position(self):
"""
获取验证码位置
:return: 验证码位置元组
"""
img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_canvas_img')))
time.sleep(2)
location = img.location
size = img.size
top, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size[
'width']
return (top, bottom, left, right) def get_screenshot(self):
"""
获取网页截图
:return: 截图对象
"""
screenshot = self.browser.get_screenshot_as_png()
screenshot = Image.open(BytesIO(screenshot))
return screenshot def get_slider(self):
"""
获取滑块
:return: 滑块对象
"""
slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_slider_button')))
return slider def get_geetest_image(self, name='captcha.png'):
"""
获取验证码图片
:return: 图片对象
"""
top, bottom, left, right = self.get_position()
print('验证码位置', top, bottom, left, right)
screenshot = self.get_screenshot()
captcha = screenshot.crop((left, top, right, bottom))
captcha.save(name)
return captcha def open(self):
"""
打开网页输入用户名密码
:return: None
"""
self.browser.get(self.url)
email = self.wait.until(EC.presence_of_element_located((By.ID, 'email')))
password = self.wait.until(EC.presence_of_element_located((By.ID, 'password')))
email.send_keys(self.email)
password.send_keys(self.password) def get_gap(self, image1, image2):
"""
获取缺口偏移量
:param image1: 不带缺口图片
:param image2: 带缺口图片
:return:
"""
left = 60
for i in range(left, image1.size[0]):
for j in range(image1.size[1]):
if not self.is_pixel_equal(image1, image2, i, j):
left = i
return left
return left def is_pixel_equal(self, image1, image2, x, y):
"""
判断两个像素是否相同
:param image1: 图片1
:param image2: 图片2
:param x: 位置x
:param y: 位置y
:return: 像素是否相同
"""
# 取两个图片的像素点
pixel1 = image1.load()[x, y]
pixel2 = image2.load()[x, y]
threshold = 60
if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs(
pixel1[2] - pixel2[2]) < threshold:
return True
else:
return False def get_track(self, distance):
"""
根据偏移量获取移动轨迹
:param distance: 偏移量
:return: 移动轨迹
"""
# 移动轨迹
track = []
# 当前位移
current = 0
# 减速阈值
mid = distance * 4 / 5
# 计算间隔
t = 0.2
# 初速度
v = 0 while current < distance:
if current < mid:
# 加速度为正2
a = 2
else:
# 加速度为负3
a = -3
# 初速度v0
v0 = v
# 当前速度v = v0 + at
v = v0 + a * t
# 移动距离x = v0t + 1/2 * a * t^2
move = v0 * t + 1 / 2 * a * t * t
# 当前位移
current += move
# 加入轨迹
track.append(round(move))
return track def move_to_gap(self, slider, track):
"""
拖动滑块到缺口处
:param slider: 滑块
:param track: 轨迹
:return:
"""
ActionChains(self.browser).click_and_hold(slider).perform()
for x in track:
ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform()
time.sleep(0.5)
ActionChains(self.browser).release().perform() def login(self):
"""
登录
:return: None
"""
submit = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'login-btn')))
submit.click()
time.sleep(10)
print('登录成功') def crack(self):
# 输入用户名密码
self.open()
# 点击验证按钮
button = self.get_geetest_button()
button.click()
# 获取验证码图片
image1 = self.get_geetest_image('captcha1.png')
# 点按呼出缺口
slider = self.get_slider()
slider.click()
# 获取带缺口的验证码图片
image2 = self.get_geetest_image('captcha2.png')
# 获取缺口位置
gap = self.get_gap(image1, image2)
print('缺口位置', gap)
# 减去缺口位移
gap -= BORDER
# 获取移动轨迹
track = self.get_track(gap)
print('滑动轨迹', track)
# 拖动滑块
self.move_to_gap(slider, track) success = self.wait.until(
EC.text_to_be_present_in_element((By.CLASS_NAME, 'geetest_success_radar_tip_content'), '验证成功'))
print(success) # 失败后重试
if not success:
self.crack()
else:
self.login() if __name__ == '__main__':
crack = CrackGeetest()
crack.crack()
Python爬虫学习笔记之极限滑动验证码的识别的更多相关文章
- Python爬虫学习笔记之点触验证码的识别
代码: Chaojiying.py: #!/usr/bin/env python # coding:utf-8 import requests from hashlib import md5 clas ...
- python爬虫学习笔记(一)——环境配置(windows系统)
在进行python爬虫学习前,需要进行如下准备工作: python3+pip官方配置 1.Anaconda(推荐,包括python和相关库) [推荐地址:清华镜像] https://mirrors ...
- Python爬虫学习笔记之微信宫格验证码的识别(存在问题)
本节我们将介绍新浪微博宫格验证码的识别.微博宫格验证码是一种新型交互式验证码,每个宫格之间会有一条 指示连线,指示了应该的滑动轨迹.我们要按照滑动轨迹依次从起始宫格滑动到终止宫格,才可以完成验证,如 ...
- Python爬虫学习笔记(三)
Cookies: 以抓取https://www.yaozh.com/为例 Test1(不使用cookies): 代码: import urllib.request # 1.添加URL url = &q ...
- Python爬虫学习笔记——豆瓣登陆(一)
#-*- coding:utf-8 -*- import requests from bs4 import BeautifulSoup import html5lib import re import ...
- python爬虫学习笔记
爬虫的分类 1.通用爬虫:通用爬虫是搜索引擎(Baidu.Google.Yahoo等)“抓取系统”的重要组成部分.主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份. 简单来讲就是尽可 ...
- Python、pip和scrapy的安装——Python爬虫学习笔记1
Python作为爬虫语言非常受欢迎,近期项目需要,很是学习了一番Python,在此记录学习过程:首先因为是初学,而且当时要求很快速的出demo,所以首先想到的是框架,一番查找选用了Python界大名鼎 ...
- 一入爬虫深似海,从此游戏是路人!总结我的python爬虫学习笔记!
前言 还记得是大学2年级的时候,偶然之间看到了学长在学习python:我就坐在旁边看他敲着代码,感觉很好奇.感觉很酷,从那之后,我就想和学长一样的厉害,就想让学长教我,请他吃了一周的饭,他答应了.从此 ...
- Python爬虫学习笔记——豆瓣登陆(三)
之前是不会想到登陆一个豆瓣会需要写三次博客,修改三次代码的. 本来昨天上午之前的代码用的挺好的,下午时候,我重新注册了一个号,怕豆瓣大号被封,想用小号爬,然后就开始出问题了,发现无法模拟登陆豆瓣了,开 ...
随机推荐
- facebook演讲
任何为了更大愿景工作的人,可能会被称为疯子,即使你最终获得成功. 任何为了复杂问题工作的人,都会因为不能全面了解挑战而被指责,即使你不可能事先了解一切. 任何抓住主动权先行一步的人,都会因为步子太快而 ...
- 左值&右值
一.引子 我们所谓的左值.右值,正确的说法应该是左值表达式.右值表达式. 因为C++的表达式不是左值就是右值. 在C中,左值指的是既能够出现在等号左边也能出现在等号右边的表达式,右值指的则是只能出现在 ...
- Special Offer! Super Price 999 Bourles!
Description Polycarpus is an amateur businessman. Recently he was surprised to find out that the mar ...
- Thunder团队第五周 - Scrum会议3
Scrum会议3 小组名称:Thunder 项目名称:i阅app Scrum Master:王航 工作照片: 苗威同学在拍照,所以不在照片内. 参会成员: 王航(Master):http://www. ...
- 2019寒假训练营寒假作业(三) 对Sketch——CM-Sketch的理解(理论题部分)
目录 实验题部分 基本题 1.简述sketch: 2.Count-min Sketch: 开放题部分 理论部分 1.解释为什么 sketch 可以省空间 2.用流程图描述Count-min sketc ...
- HDU 2163 Palindromes
http://acm.hdu.edu.cn/showproblem.php?pid=2163 Problem Description Write a program to determine whet ...
- LoadRunner中执行命令行
在LoadRunner可以使用函数system()来调用系统指令,结果同在批处理里执行一样,但是system()有个缺陷:无法获取命令的返回结果. 也许可以用`echo command > fi ...
- 第三部分shell编程3(shell脚本2)
7. if 判断一些特殊用法 if [ -z $a ] 这个表示当变量a的值为空时会怎么样if grep -q '123' 1.txt; then 表示如果1.txt中含有'123'的行时会怎么样if ...
- [OS] 多线程--第一次亲密接触CreateThread与_beginthreadex本质区别
转自:http://blog.csdn.net/morewindows/article/details/7421759 本文将带领你与多线程作第一次亲密接触,并深入分析CreateThread与_be ...
- Java接口成员变量
定义接口 使用interface来定义一个接口.接口定义同类的定义类似,也是分为接口的声明和接口体,当中接口体由常量定义和方法定义两部分组成.定义接口的基本格式例如以下: [修饰符] inter ...