吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8450|回复: 27
收起左侧

[Python 转载] 利用selenium和ocr破解点击验证码模拟登录52pojie并自动签到

  [复制链接]
frankyxu 发表于 2019-2-22 13:19
本帖最后由 frankyxu 于 2019-2-22 14:41 编辑

利用selenium和ocr破解文字点击验证码

hello,下午好,这次给大家带来的是selenium和ocr破解文字点击验证码,希望大家会喜欢,项目采用的是selenium模拟人进行点击和滑动,通过ocr计算出要点击文字的位置,然后利用selenium完成最后的剪辑,主要难点是计算距离,项目地址

主要用到的技术

  • selenium

项目截图

image

核心源码 :beers:

# -*- coding: utf-8 -*-
# @Time    : 2018/01/23 10:02
# @AuThor  : xuzy
# @Software: PyCharm
# @Function:
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.support.wait import WebDriverWait
import time
import base64
import apiutil
import random

class CrackSlider():
    """
    通过浏览器截图,识别验证码中缺口位置,获取需要滑动距离,并模仿人类行为破解滑动验证码
    """

    def __init__(self):
        super(CrackSlider, self).__init__()
        # 实际地址
        self.url = 'https://www.52pojie.cn/member.php?mod=logging&action=login'
        self.driver = webdriver.Chrome()
        self.wait = WebDriverWait(self.driver, 30)
        self.zoom = 1

    def open(self):
        self.driver.get(self.url)
        self.driver.maximize_window()

    def recognize_image(self):

        #https://ai.qq.com/product/ocr.shtml#identify  优图ocr地址,免费申请
        app_id = 'appid'
        app_key = 'appkey'
        with open('./captcha.jpg', 'rb') as bin_data:
            image_data = bin_data.read()

        ai_obj = apiutil.AiPlat(app_id, app_key)

        print('----------------------SEND REQ----------------------')
        rsp = ai_obj.getOcrGeneralocr(image_data)
        print(rsp)
        return rsp

    def cal_location(self, word, rsp):
        try:
            if rsp['ret'] == 0:
                for i in rsp['data']['item_list']:
                    result = i['itemstring'].find(word)
                    if result == -1:
                        continue
                    else:
                        x = i['itemcoord'][0]['x']
                        y = i['itemcoord'][0]['y']
                        width = i['itemcoord'][0]['width']
                        height = i['itemcoord'][0]['height']

                        location_x = int(x + (width / 4) * (result + 0.5))
                        location_y = int(y + height / 2)

                        return int(location_x * 23 / 20), int(location_y * 23 / 20)

                return 50, 50
        except Exception as e:
            print(e)
            return 100, 100

    def get_tracks(self, distance):
        v = 0
        t = random.uniform(0.2, 0.3)
        forward_tracks = []
        current = 0
        mid = distance * 3 / 5
        while current < distance:
            if current < mid:
                a = 2
            else:
                a = -3
            s = v * t + 0.5 * a * (t ** 2)
            v = v + a * t
            current += s
            forward_tracks.append(round(s))

        return {'forward_tracks': forward_tracks}

    def crack_slider(self):
        try:
            time.sleep(3)
            self.open()
            captcha = 'captcha.jpg'
            time.sleep(1)
            self.driver.find_element_by_xpath('//input[@name="username"]').send_keys('你的用户名')
            time.sleep(1)
            self.driver.find_element_by_xpath('//input[@name="password"]').send_keys('你的密码')

            distance = 260
            tracks = self.get_tracks((distance + 2) * self.zoom)  # 对位移的缩放计算

            time.sleep(2)
            # slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'nc_iconfont btn_slide')))
            slider = self.driver.find_element_by_xpath("//*[@id='nc_1_n1z']")

            time.sleep(1)

            ActionChains(self.driver).click_and_hold(slider).perform()

            for track in tracks['forward_tracks']:
                ActionChains(self.driver).move_by_offset(xoffset=track, yoffset=0).perform()

            time.sleep(0.5)

            while True:

                print('进入while循环')
                print('*' * 50)
                # print(location_x,location_y)
                print('*' * 50)
                time.sleep(0.5)
                # self.driver.find_element_by_xpath('//i[@id="nc_1__btn_2"]').click()
                captcha_image = self.driver.find_element_by_xpath('//div[@class="clickCaptcha_img"]/img')
                captcha = captcha_image.get_attribute('src')
                print(captcha)

                # 下载图片
                fh = open("captcha.jpg", "wb")
                fh.write(base64.b64decode(captcha.split(',')[1]))
                fh.close()

                # 获取要识别的文字

                word_ele = self.driver.find_element_by_xpath('//div[@id="nc_1__scale_text"]/i')
                word = word_ele.text.replace('”', '').replace('“', '').strip()

                print('请点击图中的{}字'.format(word))

                # 识别图中的文字
                rsp = self.recognize_image()

                # 计算要点击的文字在图中的位置

                location_x, location_y = self.cal_location(word, rsp)
                print(location_x, location_y)
                ActionChains(self.driver).move_to_element_with_offset(captcha_image, location_x,
                                                                      location_y).click().perform()
                time.sleep(1)
                if '验证通过' in self.driver.page_source:
                    break
                # try:
                #     menu = self.driver.find_element_by_xpath('//a[@class="showmenu"]')
                # except Exception as e:
                #     menu = None
                # if menu:
                #     break

                # 刷新页面
            self.driver.find_element_by_xpath('//button[@name="loginsubmit"]').click()
            time.sleep(2)
            print('已经跳出while循环')
            self.driver.get('https://www.52pojie.cn/home.php?mod=task&do=apply&id=2')
            # qd = WebDriverWait(self.driver, 10).until(EC.visibility_of(self.find_element(by=By.CLASS_NAME, value='qq_bind')))
            #
            # qd.click()
            time.sleep(5)
            self.driver.quit()
        except Exception as e:
            print(e)
            exit(0)

            c.crack_slider()

if __name__ == '__main__':
    c = CrackSlider()
    c.crack_slider()

如何使用

  • pip install selenium

  • python3 52.py

  • 顺便来点热心值呗

免费评分

参与人数 11吾爱币 +14 热心值 +10 收起 理由
扛煤气罐的爷们 + 1 + 1 谢谢@Thanks!
lsir + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
mobs + 1 + 1 用心讨论,共获提升!
天空宫阙 + 1 + 1 谢谢@Thanks!
hustlzp + 2 + 1 我很赞同!
imqiuge + 1 + 1 谢谢@Thanks!
wanwfy + 1 + 1 用心讨论,共获提升!
wushaominkk + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
白水饮 + 1 + 1 用心讨论,共获提升!
Bds1r + 1 + 1 我很赞同!
左三圈 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| frankyxu 发表于 2019-2-22 15:01
tanghengvip 发表于 2019-2-22 14:42
https://www.freebuf.com/articles/web/194628.html
今天正好看到这篇文章~ 楼主的成品就来了。感谢分享。

哈哈哈,你说的这篇文章我也看过,还有一种思路是利用opencv的模板匹配方法来计算距离,你如果有兴趣的话可以自己尝试一下
 楼主| frankyxu 发表于 2019-2-22 16:21
时空之外 发表于 2019-2-22 16:16
这个优图识别好像不太准确,我换了个百度,依旧不行。还有就是建议self.driver.get(url)和self.maximize_wi ...

这个是基于优图的,返回的数据中有坐标信息,百度的ocr不是太适合,优图的ocr一般三次以内吧
麦迪就是帅 发表于 2019-2-22 13:28
左三圈 发表于 2019-2-22 13:41
前排合影,优秀作品~
 楼主| frankyxu 发表于 2019-2-22 14:11
左三圈 发表于 2019-2-22 13:41
前排合影,优秀作品~

,感谢,还有些地方不够完善
tanghengvip 发表于 2019-2-22 14:42
https://www.freebuf.com/articles/web/194628.html
今天正好看到这篇文章~ 楼主的成品就来了。感谢分享。
yuelass 发表于 2019-2-22 15:50
不错 学习学习               
时空之外 发表于 2019-2-22 16:16
本帖最后由 时空之外 于 2019-2-22 16:18 编辑

这个优图识别好像不太准确,我换了个百度,依旧不行。还有就是建议self.driver.get(url)和self.maximize_window互换位置,不然每次加载会被提示挡住拖动按钮
时空之外 发表于 2019-2-22 17:17
frankyxu 发表于 2019-2-22 16:21
这个是基于优图的,返回的数据中有坐标信息,百度的ocr不是太适合,优图的ocr一般三次以内吧

楼主知道selenium怎么过检测嘛
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 23:42

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表