《封号码罗》python爬虫之文字点选型验证码破解一次仅需2分5厘人民币(十)

本文介绍使用Python结合selenium和第三方打码平台,以2.5厘人民币的低成本解决文字点选型验证码的反爬问题。强调在实际工作中,选择高效方法比破解方法更重要。

在这里插入图片描述
不管图片上是两个字,三个字,还是四个字,统统2分5厘
环境的配置自行百度解决
在实际开发环境中,这类验证码反爬通常都是比较难处理的,你要是说自己搞一个CNN卷积神经网络,那我只能说:大佬,带我飞。
对于普通码农来说,能借助第三方平台起飞,也是不错的选择,毕竟公司要的是爬下来的数据,不是你用了什么方法在那儿破解登陆验证什么的,总之还是看效率的吧,个人理解,不喜勿喷!
知识付费的时代,所以本文要求VIP用户才可以看,全程注释,小白也能秒懂

# 点选文字验证码

import time
from io import BytesIO
from PIL import Image
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from chaojiying import Chaojiying

USERNAME = "admin"
PASSWORD = "admin"
CHAOJIYING_USERNAME = "超级鹰用户名"
CHAOJIYING_PASSWORD = "超级鹰密码"
CHAOJIYING_SOFT_ID = 9****6
CHAOJIYING_KIND = 9004

if not CHAOJIYING_USERNAME or not CHAOJIYING_PASSWORD:
    print("请设置用户名和密码")
    exit(0)


class CrackCaptcha():
    captcha_result_json = ""

    def __init__(self):
        self.url = "https://captcha3.scrape.center/"
        self.browser = webdriver.Chrome()
        self.wait = WebDriverWait(self.browser, 20)
        self.username = USERNAME
        self.password = PASSWORD
        self.chaojiying = Chaojiying(CHAOJIYING_USERNAME, CHAOJIYING_PASSWORD, CHAOJIYING_KIND)

    # 第一步 打开网页输入用户名和密码
    def open(self):
        self.browser.get(self.url)
        username = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='text']")))
        password = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='password']")))
        username.send_keys(self.username)
        password.send_keys(self.password)
        return print("已输入用户名和密码")

    # 第二步 获取登录按钮,点击该按钮之后会弹出验证码图
    def get_captcha_button(self):
        time.sleep(2)
        button = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "button[type='button']")))
        return button

    # 第三步 获取验证码图片的位置和大小,从网页截图里截取相应的验证码图片即可获取到
    def get_captcha_element(self):
        time.sleep(2)
        # 验证码图片加载出来
        print("准备获取验证码节点")
        self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "img.geetest_item_img")))
        # 验证码完整节点
        element = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, "geetest_panel_box")))
        print("成功获取验证码节点")
        return element  # 返回验证码图片的完整节点对象

    # 第四步 通过图片对象获取验证码位置,返回位置元组数据
    def get_captcha_position(self):
        element = self.get_captcha_element()  # 调用第三步返回的完整图片对象节点
        time.sleep(2)
        # location属性可以返回该图片对象(既这张图片)在浏览器中的位置,以字典的形式返回,{‘x’:30,‘y’:30}
        # 坐标轴是以屏幕左上角为原点,x轴向右递增,y轴像下递增
        location = element.location
        print("返回图片对象在浏览器中的相对位置location", location)  # {'x': 304, 'y': 288}
        # size属性是图片对象的高度,宽度{‘height’:30,‘width’:30}
        size = element.size
        print("返回图片对象的宽度和高度size", size)  # {'height': 311, 'width': 320}
        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):
        screenshot = self.browser.get_screenshot_as_png()
        screenshot = Image.open(BytesIO(screenshot))
        screenshot.save("screenshot.png")
        print("获取到整个网页的截图对象")
        return screenshot

    # 第六步 获取验证码图片(从网页截图中获取)
    def get_captcha_image(self, name="captcha.png"):
        top, bottom, left, right = self.get_captcha_position()
        print("验证码位置", top, bottom, left, right)
        screenshot = self.get_screenshot()
        #                           238   650     304   626
        # captcha = screenshot.crop((top, bottom, left, right))  # 顺序错误,就不会切图成功,有报错提示
        captcha = screenshot.crop((left, top, right, bottom))
        captcha.save(name)
        print("将验证码从这个网页中截取出来的图片对象")
        return captcha

    # 第七步 把图片发送给打码平台
    def get_chaojiying_json(self):
        image = self.get_captcha_image()
        bytes_array = BytesIO()
        image.save(bytes_array, format="PNG")
        # 识别验证码
        captcha_result = self.chaojiying.post_pic(bytes_array.getvalue(), CHAOJIYING_KIND)
        # captcha_result = {'err_no': 0, 'err_str': 'OK', 'pic_id': '9134714115830400002', 'pic_str': '12,14|2,6',
        #                   'md5': '64137ffa420c328888c3cc53ca82bf8e'}
        self.captcha_result_json = captcha_result
        print("超级鹰返回json", captcha_result)
        return captcha_result

    # 第八步 解析超级鹰返回的数据
    def get_points(self, captcha_result):
        groups = captcha_result.get("pic_str").split("|")
        locations = [[int(number) for number in group.split(",")] for group in groups]
        return locations  # [[12, 14], [2, 6]]

    # 单独退还题分的操作
    def get_report_error(self):
        im_id = self.captcha_result_json.get("pic_id")
        result = self.chaojiying.report_error(im_id)
        return print("已请求退还题分", result)

    # 第九步 点击验证码图片进行验证
    def touch_click_words(self, locations):
        print("-----------------准备点击图片上面的验证码")
        for location in locations:
            try:
                ActionChains(self.browser).move_to_element_with_offset(self.get_captcha_element(), location[0],
                                                                       location[1]).click().perform()
            except Exception as e:
                self.get_report_error()
                raise {"error_message": "点选坐标返回错误,已执行退分程序"}
            time.sleep(5)
        print("图片点击验证操作完成,准备点击确认按钮")
        commint = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, "geetest_commit_tip")))
        commint.click()
        return print("已点击确认按钮")

    # 第十步 判定是否成功
    def get_success(self):
        try:
            time.sleep(2)
            self.wait.until(EC.text_to_be_present_in_element((By.TAG_NAME, "h2"), "登陆成功"))
            return print("登陆成功")
        except Exception as e:
            print("登陆失败,调用接口返回题分", e)
            self.get_report_error()


if __name__ == '__main__':
    cc = CrackCaptcha()
    cc.open()
    botton = cc.get_captcha_button()
    botton.click()
    captcha_result = cc.get_chaojiying_json()
    locations = cc.get_points(captcha_result)
    cc.touch_click_words(locations)
    cc.get_success()

# 学习登陆的链接 https://captcha3.scrape.center/

超级鹰的SDK,不需要修改,两个文件放在放同一个文件夹下面就ok

import requests

from hashlib import md5


class Chaojiying(object):

    def __init__(self, username, password, soft_id):
        self.username = username
        self.password = md5(password.encode('utf-8')).hexdigest()
        self.soft_id = soft_id
        self.base_params = {
            'user': self.username,
            'pass2': self.password,
            'softid': self.soft_id,
        }
        self.headers = {
            'Connection': 'Keep-Alive',
            'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
        }

    def post_pic(self, im, codetype):
        """
        im: 图片字节
        codetype: 题目类型 参考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': codetype,
        }

        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', im)}
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files,
                          headers=self.headers)
        return r.json()

    def report_error(self, im_id):
        """
        im_id:报错题目的图片ID
        """
        params = {
            'id': im_id,
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
        return r.json()

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值