Python大佬手把手带你用爬虫破解——滑动验证码识别

Posted 克金森沐沐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python大佬手把手带你用爬虫破解——滑动验证码识别相关的知识,希望对你有一定的参考价值。

做爬虫总会遇到各种各样的反爬限制,反爬的第一道防线往往在登录就出现了,为了限制爬虫自动登录,各家使出了浑身解数,所谓道高一尺魔高一丈。

小小课堂

在这里插入图片描述
步骤:
(1)计算滑动距离
(2)模拟人滑动(总体思路是先快再慢)

下面我们先来看下豆瓣登录界面在这里插入图片描述这个时候我们通过输错密码的方法,使其出现验证码。在这里插入图片描述

多滑动和刷新几次,发现一些规律,y轴不变,x轴在变化,豆瓣这个滑动验证码,x轴距离大概207左右,如果需要精确测量,需要使用像素对比。
在这里插入图片描述接来下通过selenium找到滑块,移动就行了,但是有一个问题,如果直接(x1,y1)移动到(x2,y2),相当于瞬移的效果,时间非常短,可能会被对方检测到。
在这里插入图片描述
接下来需要使用模拟真实人的点击滑动轨迹,一般是先加速再加速,假设是匀加速和匀减速。
滑动之后,如果不通过,可以刷新按钮,再进行滑动,直到通过(因为通过后一般页面开始跳转title不同或找其他的对比找到不同)

模拟匀加速和匀减速

在这里插入图片描述
代码实现:

def get_tracks(distance, rate=0.6, t=0.2, v=0):
    """
    将distance分割成小段的距离
    :param distance: 总距离
    :param rate: 加速减速的临界比例
    :param a1: 加速度
    :param a2: 减速度
    :param t: 单位时间
    :param t: 初始速度
    :return: 小段的距离集合
    """
    tracks = []
    # 加速减速的临界值
    mid = rate * distance
    # 当前位移
    s = 0
    # 循环
    while s < distance:
        # 初始速度
        v0 = v
        if s < mid:
            a = 20
        else:
            a = -3
        # 计算当前t时间段走的距离
        s0 = v0 * t + 0.5 * a * t * t
        # 计算当前速度
        v = v0 + a * t
        # 四舍五入距离,因为像素没有小数
        tracks.append(round(s0))
        # 计算当前距离
        s += s0

    return tracks

if __name__ == '__main__':
    tracks = get_tracks(100)
    print(tracks)
    print(sum(tracks))
123456789101112131415161718192021222324252627282930313233343536373839

下面我们来看下运行结果:在这里插入图片描述

我们可以看到已经完成了模拟匀加速与匀减速的操作。

分析登录页面

在这里插入图片描述
首先通过URL,我们找到了

https://accounts.douban.com/passport/login

打开之后的页面如下:在这里插入图片描述

下面我们先来看下正常人是怎样登录豆瓣的。在这里插入图片描述

下面我们就开始分析页面,通过selenium完成这些操作。

分析网页结构

在这里插入图片描述

  1. 密码登录

在这里插入图片描述

//*[@id="account"]/div[2]/div[2]/div/div[1]/ul[1]/li[2]
1
  1. 用户账号
  2. 用户密码
  3. 登录豆瓣
  4. 找到滑块
  5. 刷新按钮

分析完成,下面就开始代码实现了

代码实现

url = "https://accounts.douban.com/passport/login"
driver = webdriver.Chrome("./chromedriver/chromedriver.exe")
driver.get(url)
print("当前的title:",driver.title)

driver.find_element_by_xpath('//*[@id="account"]/div[2]/div[2]/div/div[1]/ul[1]/li[2]').click()
driver.find_element_by_xpath('//*[@id="username"]').send_keys("账号")
driver.find_element_by_xpath('//*[@id="password"]').send_keys("密码")
driver.find_element_by_xpath('//*[@id="account"]/div[2]/div[2]/div/div[2]/div[1]/div[4]/a').click()
# 停一下,等待出现
time.sleep(2)

# 切换iframe
driver.switch_to.frame(1)
block = driver.find_element_by_xpath('//*[@id="tcaptcha_drag_button"]')
reload = driver.find_element_by_xpath('//*[@id="reload"]')

# 滑动操作时需要动作链
# 摁下滑块
ActionChains(driver).click_and_hold(block).perform()
# 移动
ActionChains(driver).move_by_offset(180, 0).perform()
# 获取位移
tracks = get_tracks(30)
# 循环
for track in tracks:
    # 移动
    ActionChains(driver).move_by_offset(track, 0).perform()
# 释放
ActionChains(driver).release().perform()
# 判断
if driver.title == "登录豆瓣":
    print("失败...再来一次...")
    # 单击刷新按钮刷新
    reload.click()
    # 停一下
    time.sleep(2)
else:
    print("成功!")

time.sleep(5)
driver.quit()
123456789101112131415161718192021222324252627282930313233343536373839404142

登录过程测试

在这里插入图片描述

完整代码

# encoding: utf-8
'''
  @author python之眼
  @create 2020-11-14 14:41
  Mycsdn:https://buwenbuhuo.blog.csdn.net/
  @contact: 459804692@qq.com
  @software: Pycharm
  @file: 豆瓣登录.py
  @Version:1.0
  
'''
import requests
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains


def get_tracks(distance, rate=0.6, t=0.2, v=0):
    """
    将distance分割成小段的距离
    :param distance: 总距离
    :param rate: 加速减速的临界比例
    :param a1: 加速度
    :param a2: 减速度
    :param t: 单位时间
    :param t: 初始速度
    :return: 小段的距离集合
    """
    tracks = []
    # 加速减速的临界值
    mid = rate * distance
    # 当前位移
    s = 0
    # 循环
    while s < distance:
        # 初始速度
        v0 = v
        if s < mid:
            a = 20
        else:
            a = -3
        # 计算当前t时间段走的距离
        s0 = v0 * t + 0.5 * a * t * t
        # 计算当前速度
        v = v0 + a * t
        # 四舍五入距离,因为像素没有小数
        tracks.append(round(s0))
        # 计算当前距离
        s += s0

    return tracks


def slide(driver):
    """滑动验证码"""
    # 切换iframe
    driver.switch_to.frame(1)
    #找到滑块
    block = driver.find_element_by_xpath('//*[@id="tcaptcha_drag_button"]')
    #找到刷新
    reload = driver.find_element_by_xpath('//*[@id="reload"]')
    while True:
        # 摁下滑块
        ActionChains(driver).click_and_hold(block).perform()
        # 移动
        ActionChains(driver).move_by_offset(180, 0).perform()
        #获取位移
        tracks = get_tracks(30)
        #循环
        for track in tracks:
            #移动
            ActionChains(driver).move_by_offset(track, 0).perform()
        # 释放
        ActionChains(driver).release().perform()
        #停一下
        time.sleep(2)
        #判断
        if driver.title == "登录豆瓣":
            print("失败...再来一次...")
            #单击刷新按钮刷新
            reload.click()
            # 停一下
            time.sleep(2)
        else:
            break

def main():
    """主程序"""
    url = "https://accounts.douban.com/passport/login"
    driver = webdriver.Chrome("./chromedriver/chromedriver.exe")
    driver.get(url)
    driver.find_element_by_xpath('//*[@id="account"]/div[2]/div[2]/div/div[1]/ul[1]/li[2]').click()
    driver.find_element_by_xpath('//*[@id="username"]').send_keys("账号")
    driver.find_element_by_xpath('//*[@id="password"]').send_keys("密码")
    driver.find_element_by_xpath('//*[@id="account"]/div[2]/div[2]/div/div[2]/div[1]/div[4]/a').click()
    # 停一下,等待出现
    time.sleep(2)
    #滑动验证码
    slide(driver)

    print("成功")
    driver.quit()


if __name__ == '__main__':
    main()
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106

在这里插入图片描述

最后多说一句,小编是一名python开发工程师,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注小编,并私信“01”领取。

以上是关于Python大佬手把手带你用爬虫破解——滑动验证码识别的主要内容,如果未能解决你的问题,请参考以下文章

作为一只Python爬虫:如何破解滑动验证码

Selenium实战滑动验证码破解JAVA爬虫

Selenium实战滑动验证码破解JAVA爬虫

大佬带你用 python爬虫获取指定网站所有连接下图片单线程

从零破解一款轻量级滑动验证码

python 爬虫,关于验证码的问题。输入验证码才能搜索。