使用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()

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • selenium+python实现自动化登录的方法

    Selenium Python 提供了一个简单的API 便于我们使用 Selenium WebDriver编写 功能/验收测试. 通过Selenium Python的API,你可以直观地使用所有的 Selenium WebDriver 功能 .Selenium Python提供了一个很方便的接口来驱动 Selenium WebDriver , 例如Firefox.Chrome.Ie,以及Remote,目前支持的python版本有2.7或3.2以上. selenium 可以自动化测试.抢票.爬虫等

  • Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能示例

    本文实例讲述了Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能.分享给大家供大家参考,具体如下: import re from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected

  • python+selenium识别验证码并登录的示例代码

    由于工作需要,登录网站需要用到验证码.最初是研究过验证码识别的,但是总是不能获取到我需要的那个验证码.直到这周五,才想起这事来,昨天顺利的解决了. 下面正题: python版本:3.4.3 所需要的代码库:PIL,selenium,tesseract 先上代码: #coding:utf-8 import subprocess from PIL import Image from PIL import ImageOps from selenium import webdriver import t

  • Python+selenium 获取浏览器窗口坐标、句柄的方法

    1.0 获取浏览器窗口坐标 python目录可找到Webdriver.py 文件定义了get_window_rect()函数,可获取窗口的坐标和大小(长宽),但出现"Command not found"的情况.set_window_rect()函数也一样. def get_window_rect(self): """ Gets the x, y coordinates of the window as well as height and width of

  • Python使用selenium实现网页用户名 密码 验证码自动登录功能

    好久没有学python了,反正各种理由吧(懒惰总会有千千万万的理由),最近网上学习了一下selenium,实现了一个简单的自动登录网页,具体如下. 1.安装selenium: 如果你已经安装好anaconda3,直接在windows的dos窗口输入命令安装selenium: python -m pip install --upgrade pip 查看版本pip show selenium 2.接着去http://chromedriver.storage.googleapis.com/index.

  • Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息示例

    本文实例讲述了Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息.分享给大家供大家参考,具体如下: import time from multiprocessing import Pool from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.web

  • python selenium UI自动化解决验证码的4种方法

    本文介绍了python selenium UI自动化解决验证码的4种方法,分享给大家,具体如下: 测试环境 windows7+ firefox50+ geckodriver # firefox浏览器驱动 python3 selenium3 selenium UI自动化解决验证码的4种方法:去掉验证码.设置万能码.验证码识别技术-tesseract.添加cookie登录,本次主要讲解验证码识别技术-tesseract和添加cookie登录. 1. 去掉验证码 去掉验证码,直接通过用户名和密码登陆网

  • Python+Selenium+PIL+Tesseract自动识别验证码进行一键登录

    本文介绍了Python+Selenium+PIL+Tesseract自动识别验证码进行一键登录,分享给大家,具体如下: Python 2.7 IDE Pycharm 5.0.3 Firefox浏览器:47.0.1 Selenium PIL Pytesser Tesseract 扯淡 ​ 我相信每个脚本都有自己的故事,我这个脚本来源于自己GRD教务系统,每次进行登录时,即使我输入全部正确,第一次登录一定是登不上去的!我不知道设计人员什么想法?难道是为了反爬机制?你以为一次登不上,我tm就不爬了?我

  • Python Selenium Cookie 绕过验证码实现登录示例代码

    之前介绍过通过cookie 绕过验证码实现登录的方法.这里并不多余,会增加分析和另外一种方法实现登录. 1.思路介绍  1.1.直接看代码,内有详细注释说明 # FileName : Wm_Cookie_Login.py # Author : Adil # DateTime : 2018/3/20 19:47 # SoftWare : PyCharm from selenium import webdriver import time url = 'https://system.address'

  • selenium+python实现1688网站验证码图片的截取功能

    1. 背景 •在1688网站爬取数据时,如果访问过于频繁,无论用户是否已经登录,就会弹出如下所示的验证码登录框. 一般的验证码是类似于如下的元素(通过链接单独加载进页面,而不是嵌入图片元素): <img id="J_CheckCodeImg1" width="100" height="30" onmousedown="return false;" src="//pin.aliyun.com/get_img?id

  • Python+selenium实现自动循环扔QQ邮箱漂流瓶

    本文实例为大家分享了Python自动循环扔QQ邮箱漂流瓶的具体代码,供大家参考,具体内容如下 Python代码如下: # coding=utf-8 from selenium import webdriver from time import sleep from random import randint def auto_throw(): """扔瓶子""" driver = webdriver.Chrome() driver.get(&qu

随机推荐