selenium+crop+chaojiying之登录超级鹰

前言

        目前在学习网络爬虫中的验证码识别,今天做了个有趣的项目,用超级鹰来模拟登陆超级鹰。

        超级鹰:验证码服务平台,提供验证码识别服务。

        selenium:最广泛使用的开源 Web UI(用户界面)自动化测试套件之一,利用它可以驱动浏览器执行特定的动作,如点击、下拉等操作,同时还可以获取浏览器当前呈现的页面的源代码,做到所谓的“可见及爬”,是网络爬虫中的一把利器。

        crop()函数: 用于裁剪图片,使用Image中的open(file)方法可返回一个打开的图片,使用crop([x1,y1,x2,y2])可进行裁剪。

基本思路

初始化信息
输入用户信息
获取验证码图片对象
获取验证码位置
获取网页截图
获取验证码图片
登录按钮获取
模拟点击登录
验证积分

        模拟登陆的难点之一在于对验证码的识别,识别部分这里交给超级鹰平台来处理,超级鹰的使用方法可以参考:超级鹰:selenium专门用来破解各种验证码_Shaun_X-CSDN博客,这里我们主要进行的是对验证码的定位及截取保存

代码分析

        presence_of_element_located:节点加载出来,传入定位元组,如(By.ID, 'p')

定位验证码元素

element = self.wait.until(EC.presence_of_element_located((By.XPATH,
             '//body/div[3]/div[1]/div[3]/div[1]/form[1]/div[1]/img[1]')))

获取验证码位置

    def captcha_position(self):
        element = self.captcha_element()
        time.sleep(2)
        # 获取对象位置
        location = element.location
        # 获取图片大小
        size = element.size
        # 291, 291+50, 668, 668+180
        top, bottom, left, right = location['y'], location['y'] + size[
            'height'], 
                                   location['x'], location['x'] + size['width']
        return top, bottom, left, right

截取此时网页,以便于获取验证码

    def browser_screenshot(self):
        screenshot = self.browser.get_screenshot_as_png()
        screenshot = Image.open(BytesIO(screenshot))
        return screenshot

        get_screenshot_as_png():以PNG格式保存截图

        BytesIO:类文件对象(file-like object),这种对象在内存中创建,可以像文件一样被操作。StringIO只能存储字符串,遇到从网络下载的图片视频等Bytes类型的内容就不行了,需要用到专门存储Bytes类型的BytesIO对象

获取验证码图片

 def captcha_img(self, name='captcha.png'):
        top, bottom, left, right = self.captcha_position()
        print("验证码的位置是:", top, bottom, left, right)
        screenshot = self.browser_screenshot()
        captcha = screenshot.crop(
            (left * 1.25, top * 1.25, right * 1.25, bottom * 1.25))
        captcha.save(name)
        return captcha

        crop()函数: 用于裁剪图片,使用Image中的open(file)方法可返回一个打开的图片,使用crop([x1,y1,x2,y2])可进行裁剪。

        我在做这个项目时发现截取到的不是真正的验证码图片,研究测试了半天,发现这里的坐标应该全部乘1.25因为电脑缩放与布局用的125%为推荐设置,设置→显示,可以将其调为100%或者我这种处理方式。

 源码

         最后是整个项目的源代码,欢迎交流指正

# @Author : YJL
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
from PIL import Image
from io import BytesIO
from chaojiying import Chaojiying_Client

# 这里输入注册超级鹰后的用户名、密码
USER_NAME = ''
PASSWORD = ''
# 这里是要识别的验证码类型
cjy_id = '1902'


class ChaojiyingLogin(object):
    # 1.初始化信息
    def __init__(self):
        self.url = 'https://www.chaojiying.com/user/login/'
        self.user = USER_NAME
        self.pwd = PASSWORD
        self.browser = webdriver.Chrome()
        self.wait = WebDriverWait(self.browser, 10)
        self.chaojiying = Chaojiying_Client(USER_NAME, PASSWORD, cjy_id)

    # 2.输入用户信息
    def input_info(self):
        self.browser.get(self.url)
        username = self.wait.until(EC.presence_of_element_located(
            (By.XPATH, '//div[@class="login_form"]/form/p[1]/input')))
        password = self.wait.until(EC.presence_of_element_located(
            (By.XPATH, '//div[@class="login_form"]/form/p[2]/input')))
        username.send_keys(self.user)
        password.send_keys(self.pwd)

    # 3.获取验证码图像对象
    def captcha_element(self):
        element = self.wait.until(EC.presence_of_element_located(
            (By.XPATH,
             '//body/div[3]/div[1]/div[3]/div[1]/form[1]/div[1]/img[1]')))
        return element

    # 4.获取验证码位置
    def captcha_position(self):
        element = self.captcha_element()
        time.sleep(2)
        location = element.location
        size = element.size
        # 291, 291+50, 668, 668+180
        top, bottom, left, right = location['y'], location['y'] + size[
            'height'], 
                                   location['x'], location['x'] + size['width']
        return top, bottom, left, right

    # 5.获取网页截图
    def browser_screenshot(self):
        screenshot = self.browser.get_screenshot_as_png()
        screenshot = Image.open(BytesIO(screenshot))
        return screenshot

    # 6.获取验证码图片
    def captcha_img(self, name='captcha.png'):
        top, bottom, left, right = self.captcha_position()
        print("验证码的位置是:", top, bottom, left, right)
        screenshot = self.browser_screenshot()
        captcha = screenshot.crop(
            (left * 1.25, top * 1.25, right * 1.25, bottom * 1.25))
        captcha.save(name)
        return captcha

    # 7.登录按钮获取
    def click_button(self):
        submit = self.wait.until(EC.element_to_be_clickable(
            (By.XPATH,
             '//body/div[3]/div[1]/div[3]/div[1]/form[1]/p[4]/input[1]')))
        submit.click()
        time.sleep(5)
        print('登录成功')

    # 8.登录
    def login(self):
        self.input_info()
        # 获取验证码图片
        image = self.captcha_img()
        bytes_arr = BytesIO()
        image.save(bytes_arr, format='PNG')
        # 识别验证码
        result = self.chaojiying.PostPic(bytes_arr.getvalue(), cjy_id)
        print(result)
        # pic_str是识别出的验证码内容
        code = result['pic_str']
        inputcode = self.wait.until(EC.presence_of_element_located(
            (By.XPATH,
             '//body/div[3]/div[1]/div[3]/div[1]/form[1]/p[3]/input[1]')))
        inputcode.send_keys(code)
        time.sleep(1)
        self.click_button()
        # 判断是否成功
        # 打印当前剩余积分
        jifen = self.wait.until(EC.presence_of_element_located((By.XPATH,
                                                                '//div[@class="index_box mat8"]/div/span')))
        print('当前剩余积分为:', jifen.text)


if __name__ == '__main__':
    button = ChaojiyingLogin()
    button.login()

        运行结果

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>