我是靠谱客的博主 友好台灯,最近开发中收集的这篇文章主要介绍selenium + Chrome 滑动验证码破解三之京东 实现某东登录,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

之前爬取模拟登录B站和模拟春秋官网的注册验证码,问题都不大.所以今天想挑战下某东,对于稍微有些爬虫基础的来说脚本到登录界面应该都没什么问题,这部分就直接上代码了哈

1.最先开始到输入账号密码,点击登录出现验证码的代码

 def __init__(self):
        self.url = 'https://passport.jd.com/new/login.aspx'
        self.chromedriverPath = "C:Program Files (x86)GoogleChromeApplicationchromedriver.exe"
        self.driver = webdriver.Chrome(executable_path=self.chromedriverPath)
        self.wait = WebDriverWait(self.driver, 20)  # 设置等待时间20秒
        self.username = "18516544488"
        self.password = "密码呀密码"

    def agreement_inputPhone(self):
        self.driver.get(self.url)
        self.driver.maximize_window()
        sleep(1)
        #点击账户登录
        self.driver.find_elements_by_xpath('//div[@class="login-tab login-tab-r"]//a')[0].click()
        sleep(3)
        self.inputuser = self.wait.until(EC.presence_of_element_located((By.NAME, "loginname")))
        self.inputuser.send_keys(self.username)
        self.inputpwd = self.wait.until(EC.presence_of_element_located((By.NAME, "nloginpwd")))
        self.inputpwd.send_keys(self.password)
        sleep(1)
        # 点击登录按钮,出现验证码图片
        login_button = self.driver.find_elements_by_xpath(r'//a[@id="loginsubmit"]')[0]
        login_button.click()
        sleep(3)  # 这里必须睡眠,不然可能会获取不到缺口图和缺口

                                          

点击登录,出现验证码,发现每次图片都是重新请求过来,而且不能像之前一样通过JS修改CSS样式获取到完整图了

                             

所以也不能像之前一样采用下面的方式截图了

 gapimg = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME,'geetest_canvas_bg')))
        sleep(2)
        gapimg.screenshot(r'./captcha1.png') #将class为geetest_canvas_bg的区域截屏保存
        # 通过js代码修改标签样式 显示图片2

不然截出来的图会这样

                                                                        

缺口大图和缺口图在一起

2.寻找突破口

也没多想,获取图片URL,先把缺口大图和缺口图下过来再说:抓取缺口图链接并保存图片

url = self.driver.find_element_by_xpath(r'//div/div[@class="JDJRV-bigimg"]/img').get_attribute("src")[0]
with open("backimg.png","wb",error="ignore") as f:
    f.write(requests.get(url).content)

直接报错,URL不合法.

查看url,发现格式为

data:image/png;base64,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

这个格式的URL说实话我是第一次见,不懂就百度,原来是利用base64编码把图片数据翻译成标准ASCII字符,等同于<img src="images/image.png"/> ,具体参考https://www.cnblogs.com/zwshi/p/9251244.html

百度到可以保存图片的方法代码:

    def get_image(self):
        backimgUrl = self.driver.find_element_by_xpath(r'//div/div[@class="JDJRV-bigimg"]/img').get_attribute("src")  # 背景缺口图链接
        gapUrl = self.driver.find_element_by_xpath(r'//div/div[@class="JDJRV-smallimg"]/img').get_attribute("src")  # 块状缺口链接

        request.urlretrieve(backimgUrl, "backing.png")
        request.urlretrieve(gapUrl, "gap.png")

 

那么和之前模拟其他网站一样,最关键的点是获取移动的距离,如何获取?

思路:若是能够寻找缺口在大缺口图中的位置,不就行了嘛,仔细查看缺口图和缺口大图,发现在彩色图片下是不好寻找的,太多干扰,所以决定将图片灰度化,再查找缺口在大缺口中的位置,返回是一个矩阵,是每个点的匹配结果,而我们要的只是X轴上的偏移量即可,这里需要用的cv2和numpy模块,自行安装

代码:

    def get_diff_location(self):
        # 获取图片并灰度化
        block = cv2.imread("gap.png", 0)
        template = cv2.imread("backing.png", 0)
        # 二值化后的图片名称
        blockName = "block.jpg"
        templateName = "template.jpg"
        # 将二值化后的图片进行保存
        cv2.imwrite(blockName, block)
        cv2.imwrite(templateName, template)
        block = cv2.imread(blockName)
        block = cv2.cvtColor(block, cv2.COLOR_RGB2GRAY)
        block = abs(255 - block)
        cv2.imwrite(blockName, block)
        block = cv2.imread(blockName)
        template = cv2.imread(templateName)
        # 获取偏移量
        result = cv2.matchTemplate(block, template,
                                   cv2.TM_CCOEFF_NORMED)  # 查找block在template中的位置,返回result是一个矩阵,是每个点的匹配结果
        x, y = np.unravel_index(result.argmax(), result.shape)
        return y

原图和灰度化后的图片如图:

                                           

3.获取到移动距离,那么和之前一样了,设置移动轨迹,再移动滑块就行了,具体代码和之前差不多,代码如下

    def get_move_track(self, gap):
        track = []  # 移动轨迹
        current = 0  # 当前位移
        # 减速阈值
        mid = gap * 4 / 5  # 前4/5段加速 后1/5段减速
        t = 0.2  # 计算间隔
        v = 0  # 初速度
        while current < gap:
            if current < mid:
                a = random.uniform(2, 5)  # 加速度随机
            else:
                a = -(random.uniform(12.5, 13.5))  # 加速度随机,负数
            v0 = v  # 初速度v0
            v = v0 + a * t  # 当前速度
            move = v0 * t + 1 / 2 * a * t * t  # 移动距离
            current += move  # 当前位移
            track.append(round(move))  # 加入轨迹
        return track

    def move_slider(self, track):
        slider = self.driver.find_elements_by_xpath(r'//div[@class="JDJRV-slide-inner JDJRV-slide-btn"]')[0]
        ActionChains(self.driver).click_and_hold(slider).perform()
        for x in track:  # 只有水平方向有运动 按轨迹移动
            ActionChains(self.driver).move_by_offset(xoffset=x, yoffset=0).perform()
        sleep(1)
        ActionChains(self.driver).release().perform()  # 松开鼠标

 

全部代码,一开始用在注册那边正确率和识别率很高,后面用在登录识别率降低了,后面再优化

# -*- coding: UTF-8 -*-
'''
@Author :Jason
'''
import random

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from urllib import request
from time import sleep
import cv2
import numpy as np
from selenium.webdriver import ActionChains
from lxml.html import etree
from PIL import Image

import re, requests
from urllib.request import urlretrieve
from bs4 import BeautifulSoup
# 设置无界面模式
from selenium.webdriver.chrome.options import Options


class JD_Login(object):
    def __init__(self):
        self.left = 40 #定义一个左边的起点 缺口一般离图片左侧有一定的距离 有一个滑块
        self.url = 'https://passport.jd.com/new/login.aspx'
        self.chromedriverPath = "C:Program Files (x86)GoogleChromeApplicationchromedriver.exe"
        self.driver = webdriver.Chrome(executable_path=self.chromedriverPath)
        self.wait = WebDriverWait(self.driver, 20)  # 设置等待时间20秒
        self.username = "账号"
        self.password = "账号密码"

    def agreement_inputPhone(self):
        self.driver.get(self.url)
        self.driver.maximize_window()
        sleep(1)
        #点击账户登录
        self.driver.find_elements_by_xpath('//div[@class="login-tab login-tab-r"]//a')[0].click()
        sleep(3)
        self.inputuser = self.wait.until(EC.presence_of_element_located((By.NAME, "loginname")))
        self.inputuser.send_keys(self.username)
        self.inputpwd = self.wait.until(EC.presence_of_element_located((By.NAME, "nloginpwd")))
        self.inputpwd.send_keys(self.password)
        sleep(1)
        # 点击登录按钮,出现验证码图片
        login_button = self.driver.find_elements_by_xpath(r'//a[@id="loginsubmit"]')[0]
        login_button.click()
        sleep(3)  # 这里必须睡眠,不然会获取不到缺口图和缺口

    def get_image(self):
        backimgUrl = self.driver.find_element_by_xpath(r'//div/div[@class="JDJRV-bigimg"]/img').get_attribute("src")  # 背景缺口图链接
        gapUrl = self.driver.find_element_by_xpath(r'//div/div[@class="JDJRV-smallimg"]/img').get_attribute("src")  # 块状缺口链接

        request.urlretrieve(backimgUrl, "backing.png")
        request.urlretrieve(gapUrl, "gap.png")

    def get_diff_location(self):
        # 获取图片并灰度化
        block = cv2.imread("gap.png", 0)
        template = cv2.imread("backing.png", 0)
        # 二值化后的图片名称
        blockName = "block.jpg"
        templateName = "template.jpg"
        # 将二值化后的图片进行保存
        cv2.imwrite(blockName, block)
        cv2.imwrite(templateName, template)
        block = cv2.imread(blockName)
        block = cv2.cvtColor(block, cv2.COLOR_RGB2GRAY)
        block = abs(255 - block)
        cv2.imwrite(blockName, block)
        block = cv2.imread(blockName)
        template = cv2.imread(templateName)
        # 获取偏移量
        result = cv2.matchTemplate(block, template,cv2.TM_CCOEFF_NORMED)  # 查找block在template中的位置,返回result是一个矩阵,是每个点的匹配结果
        x, y = np.unravel_index(result.argmax(), result.shape)
        print("x方向的偏移", int(y * 0.4 + 18), 'x:', x, 'y:', y)
        return y

    def get_move_track(self, gap):
        print("需要移动的距离",gap)
        track = []  # 移动轨迹
        current = 0  # 当前位移
        # 减速阈值
        mid = gap * 4 / 5  # 前4/5段加速 后1/5段减速
        t = 0.2  # 计算间隔
        v = 0  # 初速度
        while current < gap:
            if current < mid:
                a = 3  # 加速度为+3
            else:
                a = -3  # 加速度为-3
            v0 = v  # 初速度v0
            v = v0 + a * t  # 当前速度
            move = v0 * t + 1 / 2 * a * t * t  # 移动距离
            current += move  # 当前位移
            track.append(round(move))  # 加入轨迹
        return track

    def move_slider(self, track):
        slider = self.driver.find_elements_by_xpath(r'//div[@class="JDJRV-slide-inner JDJRV-slide-btn"]')[0]
        ActionChains(self.driver).click_and_hold(slider).perform()
        for x in track:  # 只有水平方向有运动 按轨迹移动
            ActionChains(self.driver).move_by_offset(xoffset=x, yoffset=0).perform()
        sleep(1)
        ActionChains(self.driver).release().perform()  # 松开鼠标

    def main(self):
        self.agreement_inputPhone()
        self.get_image()
        gap = self.get_diff_location()
        track = self.get_move_track(gap)
        # print("移动轨迹",track)
        self.move_slider(track)


if __name__ == "__main__":
    jd = JD_Login()
    jd.main()
          

 

最后

以上就是友好台灯为你收集整理的selenium + Chrome 滑动验证码破解三之京东 实现某东登录的全部内容,希望文章能够帮你解决selenium + Chrome 滑动验证码破解三之京东 实现某东登录所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部