Python3爬虫里关于识别微博宫格验证码的知识点详解_python

来源:脚本之家  责任编辑:小易  

python大版本间有不兼容性的,所以,最好是用对应的版本,但只要大版本相同就可以了www.zgxue.com防采集请勿采集本网。

本节我们来介绍一下新浪微博宫格验证码的识别,此验证码是一种新型交互式验证码,每个宫格之间会有一条指示连线,指示了我们应该的滑动轨迹,我们需要按照滑动轨迹依次从起始宫格一直滑动到终止宫格才可以完成验证,如图所示:

链接:https://pan.baidu.com/s/1rJsOsEAE3IIWX5JTDS2JGg 密码:GG8g 7天过期,尽早转存

c808da57dd4d397325e5bd7a0299b69.png

鼠标滑动后的轨迹会以黄色的连线来标识,如图所示:

Cookie是指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的 然后再抓取其他页面,这样就达到了你的目的。爬虫过程中只用python来保存cookie信息

69fdbb1356285e0d75130a7556dc8aa.png

我们可以访问新浪微博移动版登录页面就可以看到如上验证码,链接为:https://passport.weibo.cn/signin/login,当然也不是每次都会出现验证码,一般当频繁登录或者账号存在安全风险的时候会出现。

data = urllib.parse.urlencode(values).encode(encoding='UTF8') 试下。

接下来我们就来试着识别一下此类验证码。

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647#给你个例子参考 验证码请求一次就变了#!/usr/bin/python&

1. 本节目标

对于只是读取某几个网站更新内容的爬虫完全没必要在python代码中实现增量的功能,直接在item中增加Url字段。 item['Url'] = response.url 然后在数据端把储存url的column设置

本节我们的目标是用程序来识别并通过微博宫格验证码的验证。

如何运行爬虫代码,爬虫代码有很多,这里列举最常见的爬虫代码的运行方法工具/原料 有python环境的pc一台方法/步骤 打开python爬虫代码的源码目录,通常开始文

2. 准备工作

给你一段演示代码,参考一下。import re text = '''<tr>张三</tr> <tr> </tr> <tr>李四</tr> <tr>王五</tr

本次我们使用的 Python 库是 Selenium,使用的浏览器为 Chrome,在此之前请确保已经正确安装好了 Selenium 库、Chrome浏览器并配置好了 ChromeDriver,相关流程可以参考第一章的说明。

你可以看一下python的爬虫框架scrapy,这里面已经包含了写爬虫的大部分功能,自己只需要编写两三个模块,就可以完成一个爬虫。 如果解决了您的问题请采纳! 如果未解决请继

3. 识别思路

都差不多,不行就两个都安上,开发嘛,谁没个十几二十个解释器呢,

要识别首先要从探寻规律入手,那么首先我们找到的规律就是此验证码的四个宫格一定是有连线经过的,而且每一条连线上都会相应的指示箭头,连线的形状多样,如C型、Z型、X型等等,如图 8-26、8-27、8-28 所示:

列表取0取说明atuple空re没匹配 事先判断 if not atuple: do something

babe340e4b98b3cbf1a091e4862e382.png

C 型

fc0de58fa2fbd0957c1bd109fcd1832.png

Z 型

13817fa14ba20b5077fc3e401a712f7.png

X 型

而同时我们发现同一种类型它的连线轨迹是相同的,唯一不同的就是连线的方向,如图所示:

定位数据源选择错误了

54b97ce0aa679ce58ae0363dae6e600.png

反向连线

from Tkinter import * import ImageTk root = Tk() img = ImageTk.PhotoImage(file='bg.jpg') Label(root, text="abc", image=img).pack(side="top") root.mainl

10a6b1e9df0e73fde5939ebb77f21aa.png

正向连线

请问楼主三年后现在哪个城市薪资如何、感觉前景如何。谢谢

这两种验证码的连线轨迹是相同的,但是由于连线上面的指示箭头不同导致滑动的宫格顺序就有所不同。

个人感觉开课吧比较好,它的Python商业爬虫课程是廖雪峰研发的,大神级人物研发的课程一定和之前在学校学的有所区别。

所以要完全识别滑动宫格顺序的话就需要具体识别出箭头的朝向,而观察一下整个验证码箭头朝向一共可能有 8 种,而且会出现在不同的位置,如果要写一个箭头方向识别算法的话需要都考虑到不同箭头所在的位置,我们需要找出各个位置的箭头的像素点坐标,同时识别算法还需要计算其像素点变化规律,这个工作量就变得比较大。

def download_poster_image(movie):   #定义一个下载图片函数     src = movie  #取出它的url &nb

这时我们可以考虑用模板匹配的方法,模板匹配的意思就是将一些识别目标提前保存下来并做好标记,称作模板,在这里我们就可以获取验证码图片并做好拖动顺序的标记当做模板。在匹配的时候来对比要新识别的目标和每一个模板哪个是匹配的,如果找到匹配的模板,则被匹配到的模板就和新识别的目标是相同的,这样就成功识别出了要新识别的目标了。模板匹配在图像识别中也是非常常用的一种方法,实现简单而且易用性好。

模板匹配方法如果要效果好的话,我们必须要收集到足够多的模板才可以,而对于微博宫格验证码来说,宫格就 4 个,验证码的样式最多就是 4 3 2 * 1 = 24种,所以我们可以直接将所有模板都收集下来。

所以接下来我们需要考虑的就是用何种模板来进行匹配,是只匹配箭头还是匹配整个验证码全图呢?我们来权衡一下这两种方式的匹配精度和工作量:

首先是精度问题。如果要匹配箭头的话,我们比对的目标只有几个像素点范围的箭头,而且我们需要精确知道各个箭头所在的像素点,一旦像素点有所偏差,那么匹配模板的时候会直接错位,导致匹配结果大打折扣。如果匹配全图,我们无需关心箭头所在位置,同时还有连线帮助辅助匹配,所以匹配精度上显然是全图匹配精度更高。

其次是工作量的问题。如果要匹配箭头的话,我们需要将所有不同朝向的箭头模板都保存下来,而相同位置箭头的朝向可能不一,相同朝向的箭头位置可能不一,这时候我们需要都算出各个箭头的位置并将其逐个截出来保存成模板,同时在匹配的时候也需要依次去探寻验证码对应位置是否有匹配模板。如果匹配全图的话,我们不需要关心每个箭头的位置和朝向,只需要将验证码全图保存下来即可,在匹配的时候也不需要再去计算箭头的位置,所以工作量上明显是匹配全图更小。

所以综上考虑,我们选用全图匹配的方式来进行识别。

所以到此为止,我们就可以使用全图模板匹配的方法来识别这个宫格验证码了,找到匹配的模板之后,我们就可以得到事先为模板定义的拖动顺序,然后模拟拖动即可。

4. 获取模板

在开始之前,我们需要做一下准备工作,先将 24 张验证码全图保存下来,保存工作难道需要手工来做吗?当然不是的,因为验证码是随机的,一共有 24 种,所以我们可以写一段程序来批量保存一些验证码图片,然后从中筛选出需要的图片就好了,代码如下:

import timefrom io import BytesIOfrom PIL import Imagefrom selenium import webdriverfrom selenium.common.exceptions import TimeoutExceptionfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECUSERNAME = ''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, 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_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 main(self):        """        批量获取验证码        :return: 图片对象        """        count = 0        while True:            self.open()            self.get_image(str(count) + '.png')            count += 1if __name__ == '__main__':    crack = CrackWeiboSlide()    crack.main()

其中这里需要将 USERNAME 和 PASSWORD 修改为自己微博的用户名密码,运行一段时间后便可以发现在本地多了很多以数字命名的验证码,如图所示:

8862c6f4e72c8a9360977dd1551f450.png

在这里我们只需要挑选出不同的24张验证码图片并命名保存就好了,名称可以直接取作宫格的滑动的顺序,如某张验证码图片如图所示:

7f4be7fcd9c15409a1825503f516632.png

我们将其命名为 4132.png 即可,也就是代表滑动顺序为 4-1-3-2,按照这样的规则,我们将验证码整理为如下 24 张图,如图 所示:

8951ce26a9b854bf71e8dbe661525f9.png

如上的 24 张图就是我们的模板,接下来我们在识别的时候只需要遍历模板进行匹配即可。

5. 模板匹配

上面的代码已经实现了将验证码保存下来的功能,通过调用 get_image() 方法我们便可以得到验证码图片对象,得到验证码对象之后我们就需要对其进行模板匹配了,定义如下的方法进行匹配:

from os import listdirdef detect_image(self, image):    """    匹配图片    :param image: 图片    :return: 拖动顺序    """    for template_name in listdir(TEMPLATES_FOLDER):        print('正在匹配', template_name)        template = Image.open(TEMPLATES_FOLDER + template_name)        if self.same_image(image, template):            # 返回顺序            numbers = [int(number) for number in list(template_name.split('.')[0])]            print('拖动顺序', numbers)            return numbers

在这里 TEMPLATES_FOLDER 就是模板所在的文件夹,在这里我们用 listdir() 方法将所有模板的文件名称获取出来,然后对其进行遍历,通过 same_image() 方法对验证码和模板进行比对,如果成功匹配,那么就将匹配到的模板文件名转为列表,如匹配到了 3124.png,则返回结果 [3, 1, 2, 4]。

比对的方法实现如下:

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 = 20    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 Falsedef same_image(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

在这里比对图片也是利用了遍历像素的方法,same_image() 方法接收两个参数,image 为待检测的验证码图片对象,template 是模板对象,由于二者大小是完全一致的,所以在这里我们遍历了图片的所有像素点,比对二者同一位置的像素点是否相同,如果相同就计数加 1,最后计算一下相同的像素点占总像素的比例,如果该比例超过一定阈值那就判定为图片完全相同,匹配成功。在这里设定阈值为 0.99,即如果二者有 0.99 以上的相似比则代表匹配成功。

这样通过上面的方法,依次匹配 24 个模板,如果验证码图片正常,总能找到一个匹配的模板,这样最后就可以得到宫格的滑动顺序了。

6. 模拟拖动

得到了滑动顺序之后,我们接下来就是根据滑动顺序来拖动鼠标连接各个宫格了,方法实现如下:

def move(self, numbers):    """    根据顺序拖动    :param numbers:    :return:    """    # 获得四个按点    circles = self.browser.find_elements_by_css_selector('.patt-wrap .patt-circ')    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']

在这里方法接收的参数就是宫格的点按顺序,如 [3, 1, 2, 4]。首先我们利用 find_elements_by_css_selector() 方法获取到四个宫格元素,是一个列表形式,每个元素代表一个宫格,接下来我们遍历了宫格的点按顺序,再做一系列对应操作。

其中如果是第一个宫格,那就直接鼠标点击并保持动作,否则移动到下一个宫格。如果是最后一个宫格,那就松开鼠标,否则计算移动到下一个宫格的偏移量。

通过四次循环,我们便可以成功操作浏览器完成宫格验证码的拖拽填充,松开鼠标之后即可识别成功。

运行效果如图所示:

44688c90c52ec03255e0028c83f7f74.png

鼠标会慢慢的从起始位置移动到终止位置,最后一个宫格松开之后便完成了验证码的识别。

至此,微博宫格验证码的识别就全部完成了。

识别完成之后验证码窗口会自动关闭,接下来直接点击登录按钮即可完成微博登录。

7. 本节代码

本节代码地址为:https://github.com/Python3WebSpider/CrackWeiboSlide

8. 结语

本节我们介绍了一种常用的模板匹配识别图片的方式来识别验证码,并模拟了鼠标拖拽动作来实现验证码的识别。如果遇到类似的验证码,可以采用同样的思路进行识别。

你的问题有点大而空,这个要看你具体爬什么数据,另外你有没有基础(若没有,先学习下基本的语法),以下是我写的爬CPU性能的,参考内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • python3爬虫关于识别点触点选验证码的实例讲解
  • python3爬虫关于识别检验滑动验证码的实例
  • python3爬虫中识别图形验证码的实例讲解
  • python3网络爬虫开发实战之极验滑动验证码的识别
  • python实现二维码扫码自动登录淘宝
  • laravel+dingo/api 自定义响应的实现
  • python django搭建layui提交表单,表格,图标的实例
  • python异步任务队列示例
  • 选择python进行数据分析的理由和优势
  • python实现解析bit torrent种子文件内容的方法
  • python网络编程之文件下载实例分析
  • pyshp创建shp点文件的方法
  • python爬虫动态ip代理防止被封的方法
  • python中那些 pythonic的写法详解
  • python 怎么写爬虫
  • python爬虫学习必须要对应软件版本吗
  • Python爬虫好学吗?
  • 有没有比较好的Python爬虫视频教程?
  • python3爬虫视频教程求分享
  • python 爬虫为什么要获取响应的cookie
  • python3爬虫POST传递参数问题
  • python 爬虫,关于验证码的问题。输入验证码才能搜索。
  • 基于python的scrapy爬虫,关于增量爬取是怎么处理的
  • 关于python爬虫
  • python爬虫里用next_sibling函数如果html里是空行要怎么跳过?
  • 在哪里编写python网络爬虫
  • 用Python写网络爬虫的书,是用Python2还是Python3写的
  • 用python编写爬虫程序,IndexError: list index out of range
  • Python2爬虫下载的图片为什么会打不开
  • 关于python3tkinter里加入图片用grib()的方法
  • 学习python两年多的时间,想找一些爬虫类的小项目做一些兼职...
  • Python商业爬虫课程课程培训哪家好?
  • python 网络爬虫,怎么自动保存图片
  • 能否将Python的爬虫伪装成Google或百度的蜘蛛
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全vbsdos/bathtahtcpythonperl游戏相关vba远程脚本coldfusionruby专题autoitseraphzonepowershelllinux shellluagolangerlang其它首页python3爬虫关于识别点触点选验证码的实例讲解python3爬虫关于识别检验滑动验证码的实例python3爬虫中识别图形验证码的实例讲解python3网络爬虫开发实战之极验滑动验证码的识别python实现二维码扫码自动登录淘宝laravel+dingo/api 自定义响应的实现python django搭建layui提交表单,表格,图标的实例python异步任务队列示例选择python进行数据分析的理由和优势python实现解析bit torrent种子文件内容的方法python网络编程之文件下载实例分析pyshp创建shp点文件的方法python爬虫动态ip代理防止被封的方法python中那些 pythonic的写法详解python入门教程 超详细1小时学会python 列表(list)操作方法详解python 元组(tuple)操作详解pycharm 2020最新永久激活码(附python 字典(dictionary)操作详解pycharm 使用心得(一)安装和首python strip()函数 介绍python 中文乱码问题深入分析python中使用xlrd、xlwt操作excepython科学计算环境推荐——anacpython如何计算语句执行时间python求正态分布曲线下面积实例浅谈pandas series 和 numpy array中的相python数据可视化:泊松分布详解python连接mysql、mongodb、redis、memca对python .txt文件读取及数据处理方法总结python版微信红包分配算法python 阶乘累加和的实例flask框架的学习指南之用户登录管理python使用myqr制作专属动态彩色二维码功
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved