使用Selenium破解新浪微博的四宫格验证码
作者:回忆不说话 发布时间:2021-06-16 11:22:28
标签:python,selenium,验证码
在我们爬虫的时候经常会遇到验证码,新浪微博的验证码是四宫格形式。
可以采用模板验证码的破解方式,也就是把所有验证码的情况全部列出来,然后拿验证码的图片和这所有情况中的图片进行对比,然后获取验证码,再通过selenium自动拖拽点击,进行破解。
我们将验证码四个点标注为1234,那么所有的情况就是以下24种情况。
数字代表箭头指向:
1234 | 2134 | 3124 | 4321 |
1243 | 2143 | 3142 | 4312 |
1342 | 2314 | 3214 | 4123 |
1324 | 2341 | 3241 | 4132 |
1423 | 2413 | 3412 | 4213 |
1432 | 2431 | 3421 | 4231 |
所有的情况就是以上24种。我们将这24中验证码的情况放在一个文件夹内,当我们在登录的时候用获取的验证码截图去和所有的情况一一对比,然后获取完全相同的验证码,进行点击即可。代码如下:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.action_chains import ActionChains
import time
from PIL import Image
from io import BytesIO
from os import listdir
USERNAME = ''
PASSWORD = ''
class CrackWeiboSlide():
def __init__(self):
self.url = 'https://passport.weibo.cn/signin/login'
self.browser = webdriver.Chrome()
self.wait = WebDriverWait(self.browser,20)
self.username = USERNAME
self.password = PASSWORD
def __del__(self):
self.browser.close()
def open(self):
"""
打开网页输入用户名密码登录
:return: None
"""
self.browser.get(self.url)
username = self.wait.until(EC.presence_of_element_located((By.ID,'loginName')))
password = self.wait.until(EC.presence_of_element_located((By.ID,'loginPassword')))
submit = self.wait.until(EC.element_to_be_clickable((By.ID, 'loginAction')))
username.send_keys(self.username)
password.send_keys(self.password)
submit.click()
def get_position(self):
"""
获取验证码的位置
:return: 位置
"""
try:
img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME,'patt-shadow')))
except TimeoutException:
print('未出现验证码')
self.open()
time.sleep(2)
location = img.location
size = img.size
top=location['y']
bottom = location['y']+size['height']
left = location['x']
right = location['x']+size['width']
return (top,bottom,left,right)
def get_screenshot(self):
"""
获取截图
:return:截图
"""
screentshot = self.browser.get_screenshot_as_png()
# BytesIO将网页截图转换成二进制
screentshot = Image.open(BytesIO(screentshot))
return screentshot
def get_image(self,name):
"""获取验证码图片"""
top,bottom,left,right = self.get_position()
print('验证码位置',top,bottom,left,right)
screenshot = self.get_screenshot()
# crop()将图片裁剪出来,后面需要一个参数
captcha = screenshot.crop((left,top,right,bottom))
captcha.save(name)
return captcha
def detect_image(self,image):
"""
匹配图片
:param self:
:param image: 图片
:return: 拖动顺序
"""
# 图片所在的文件夹
for template_name in listdir('templates/'):
print('正在匹配',template_name)
template = Image.open('templates/'+template_name)
# 匹配图片
if self.same_img(image,template):
# 将匹配到的文件名转换为列表
numbers = [int(number)for number in list(template_name.split('.')[0])]
print('拖动顺序',numbers)
return numbers
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]
# 偏差量等于60
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 same_img(self,image,template):
"""
识别相似的验证码
:param image: 准备识别的验证码
:param template: 模板
:return:
"""
# 相似度阈值
threshold = 0.99
count = 0
# 匹配所有像素点
for x in range(image.width):
for y in range(image.height):
# 判断像素
if self.is_pixel_equal(image,template,x,y):
count+=1
result = float(count)/(image.width*image.height)
if result>threshold:
print('成功匹配')
return True
return False
def move(self,numbers):
"""
根据顺序拖动,此处接收的参数为前面的验证码的顺序列表
:param numbers:
:return:
"""
# 获取四宫格的四个点
circles = self.browser.find_elements_by_css_selector('.patt-wrap .patt-circ')
print('-----------------',circles)
dx = dy =0
for index in range(4):
circle = circles[numbers[index]-1]
if index == 0:
# 点击第一个点
ActionChains(self.browser).move_to_element_with_offset(circle,circle.size['width']/2,circle.size['height']/2).click_and_hold().perform()
else:
# 慢慢移动
times = 30
for i in range(times):
ActionChains(self.browser).move_by_offset(dx/times,dy/times).perform()
time.sleep(1/times)
if index == 3:
# 松开鼠标
ActionChains(self.browser).release().perform()
else:
# 计算下次的偏移
dx = circles[numbers[index+1]-1].location['x'] - circle.location['x']
dy = circles[numbers[index+1]-1].location['y'] - circle.location['y']
def crack(self):
"""
破解入口
:return:
"""
self.open()
# 获取验证码图片
image = self.get_image('captcha.png')
numbers = self.detect_image(image)
self.move(numbers)
time.sleep(10)
print('识别结束')
if __name__ == '__main__':
crack = CrackWeiboSlide()
crack.crack()
设置自己的账号密码即可实现。
有时候会匹配不上,图片相似度阈值达不到0.99以上,这个时候可能是我们收集的验证码图片过时了,重新开启图片收集程序,运行收集一下即可。
收集图片程序代码如下:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
import time
from PIL import Image
from io import BytesIO
from os import listdir
USERNAME = '18239831004'
PASSWORD = 'qweqweqwe'
class CrackWeiboSlide():
def __init__(self):
self.url = 'https://passport.weibo.cn/signin/login'
self.browser = webdriver.Chrome()
self.wait = WebDriverWait(self.browser,20)
self.username = USERNAME
self.password = PASSWORD
def __del__(self):
self.browser.close()
def open(self):
"""
打开网页输入用户名密码登录
:return: None
"""
self.browser.get(self.url)
username = self.wait.until(EC.presence_of_element_located((By.ID,'loginName')))
password = self.wait.until(EC.presence_of_element_located((By.ID,'loginPassword')))
submit = self.wait.until(EC.element_to_be_clickable((By.ID, 'loginAction')))
username.send_keys(self.username)
password.send_keys(self.password)
submit.click()
def get_position(self):
"""
获取验证码的位置
:return: 位置
"""
try:
img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME,'patt-shadow')))
except TimeoutException:
print('未出现验证码')
self.open()
time.sleep(2)
location = img.location
size = img.size
top=location['y']
bottom = location['y']+size['height']
left = location['x']
right = location['x']+size['width']
return (top,bottom,left,right)
def get_screenshot(self):
"""
获取截图
:return:截图
"""
screentshot = self.browser.get_screenshot_as_png()
# BytesIO将网页截图转换成二进制
screentshot = Image.open(BytesIO(screentshot))
return screentshot
def get_image(self,name):
"""获取验证码图片"""
top,bottom,left,right = self.get_position()
print('验证码位置',top,bottom,left,right)
screenshot = self.get_screenshot()
# crop()将图片裁剪出来,后面需要一个参数
captcha = screenshot.crop((left,top,right,bottom))
captcha.save(name)
return captcha
# 获取所有的验证码
def main(self):
count = 0
while True:
name = str(count)+'.png'
self.open()
self.get_image(name)
count+=1
if __name__ == '__main__':
crack = CrackWeiboSlide()
crack.main()
来源:https://blog.csdn.net/qq_39138295/article/details/82888722


猜你喜欢
- 前言Python代码缩进和测试模块是大家学习python必不可少的一部分,本文主要介绍了关于Python代码缩进和测试模块的相关内容,分享出
- 今天在写一个研究生创新项目申报书时涉及到一个python画图问题,对于在x轴各个区段显示自定义的字符串有些疑问,特此记录。界面如下所示:代码
- 一、如何将列表数据写入文件 ⾸先,我们来看看下⾯这段代码,并思考:这段代码有没有问题,如果有问题的话,要怎么改?li = [
- 记录的MySQL 5.7.9安装教程,分享给大家环境介绍:操作系统:Centos 7.1mysql数据库版本:mysql5.7.9mysql
- 一、临时表实现分步处理1.概述当需要的结果需要经过多次处理后才能最终得到我们需要的结果时,就可以使用临时表,这里临时表就起到了一个中间处理的
- Python 的 Queue 模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列Lifo
- 父层: <div class="col-xs-12"> <div class
- 官方文档:http://www.layui.com/demo/layedit.html官网文档目前是不支持layedit扩展式的。自己手动实
- 引言:在微信小程序里,比如商品展示页面的商品详情会有图片展示,PC端设置的商品详情是PC端的宽度,所以在小程序里图片会显示不全,这时就应该做
- 学习目标根据原型设计编译自动化数据生成器,熟悉wxPython的基本用法。界面原型设计界面原型设计分析输入参数:最大长度最小长度组成规则多少
- Python2>>> >>> isinstance(b'abc', bytes)True
- Vue页面、组件之间传参方式繁多,此处罗列出常用的几种方式,欢迎审阅补充。一丶路由传参这里的路由传参以编程式 router.push(...
- 详解MySQL导出指定表中的数据要求:1. 不导出创表的语句,因为表已经建好:默认会导出,先drop table然后create table
- 1:readline()file = open("sample.txt") while 1: line =
- javascript中要判断一个变量是否为array通常是比较困难的,因为var a = [];alert(t
- 今天我们整理了ip地址和身份证的javascript验证方法。虽然ip地址和身份证的验证不是很经常会遇到,但是大家也可以研究一下js代码,里
- 一、Beautiful Soup的介绍Beautiful Soup是一个强大的解析工具,它借助网页结构和属性等特性来解析网页。它提供一些函数
- Tensorflow 提供了一种统一的格式来存储数据,这个格式就是TFRecord,上一篇文章中所提到的方法当数据的来源更复杂,每个样例中的
- def report_hook(count, block_size, total_size):... &n
- 简介本文主要给大家介绍了关于go语言安装使用protobuf的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。pr