• 滑动验证


    虎x网

    import time
    import re
    import requests
    from io import BytesIO
    from PIL import Image
    import random
    from selenium import webdriver
    from selenium.common.exceptions import TimeoutException
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.action_chains import ActionChains
    
    
    class Geek_Huxiu(object):
    
        def __init__(self):
            self.driver = webdriver.Chrome(r'F:Python视屏10爬虫包chromedriver_win32chromedriver.exe')
            self.driver.set_window_size(1366, 768)
    
        def run(self):
            self.driver.get("https://www.huxiu.com/")  # 打开浏览器
    
            WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@class="js-register"]')))
            login_btn = self.driver.find_element_by_xpath('//*[@class="js-register"]')
            login_btn.click()
    
            WebDriverWait(self.driver, 10).until(
                EC.element_to_be_clickable((By.XPATH, '//div[@class="gt_slider_knob gt_show"]')))
    
            # 模拟拖动
            self.analog_drag()
    
        def analog_drag(self):
            # 鼠标移动到拖动按钮,显示出拖动图片
            element = self.driver.find_element_by_xpath('//div[@class="gt_slider_knob gt_show"]')
            ActionChains(self.driver).move_to_element(element).perform()
            time.sleep(3)
    
            # 刷新一下极验证图片
            element = self.driver.find_element_by_xpath('//a[@class="gt_refresh_button"]')
            element.click()
            time.sleep(1)
    
            # 获取图片地址和位置坐标列表
            cut_image_url, cut_location = self.get_image_url('//div[@class="gt_cut_bg_slice"]')
            full_image_url, full_location = self.get_image_url('//div[@class="gt_cut_fullbg_slice"]')
            # print(cut_image_url)
            # print(cut_location)
    
            # 根据坐标拼接图片
            cut_image = self.splicing_image(cut_image_url, cut_location)
            full_image = self.splicing_image(full_image_url, full_location)
    
            # 将图片存储到本地
            cut_image.save("cut.jpg")
            full_image.save("full.jpg")
    
            # 根据两个图片计算距离
            distance = self.get_distance(cut_image, full_image)
    
            # 开始移动
            self.start_move(distance)
    
            # 如果出现error
            try:
                WebDriverWait(self.driver, 5, 0.5).until(
                    EC.element_to_be_clickable((By.XPATH, '//div[@class="gt_ajax_tip gt_error"]')))
                print("验证失败")
                return
            except TimeoutException as e:
                pass
    
            # 判断是否验证成功
            try:
                WebDriverWait(self.driver, 10, 0.5).until(
                    EC.element_to_be_clickable((By.XPATH, '//div[@class="gt_ajax_tip gt_success"]')))
            except TimeoutException:
                print("again times")
                time.sleep(3)
                # 失败后递归执行拖动
                self.analog_drag()
            else:
                print("验证成功")
    
        def get_image_url(self, xpath):
            link = re.compile('background-image: url("(.*?)"); background-position: (.*?)px (.*?)px;')  # 为了获取url  x坐标  y坐标
            elements = self.driver.find_elements_by_xpath(xpath)  # 获取所有图片的标签
            image_url = None
    
            location = list()  # 创建空列表
    
            for element in elements:
                style = element.get_attribute('style')
                groups = link.search(style)  # 正则匹配  style中内容
    
                url = groups[1]    # 获取url
                x_pos = groups[2]  # 获取x
                y_pos = groups[3]  # 获取y
                location.append((int(x_pos), int(y_pos)))  # (x,y) 坐标  t添加到列表
                if not image_url:  # 不存在 image_url时候
                    image_url = url  # image_url = url
            return image_url, location  # 返回一个图片url   坐标列表
    
        def splicing_image(self, image_url, location):
            res = requests.get(image_url)
            file = BytesIO(res.content)
            img = Image.open(file)
            image_upper = []
            image_down = []
            for pos in location:
                if pos[1] == 0:
                    # y值为0的坐标  属于图片上半部分,高度58
                    image_upper.append(img.crop((abs(pos[0]), 0, abs(pos[0]) + 10, 58)))
                else:
                    # y值为58的坐标 属于图片下半部分,高度58
                    image_down.append(img.crop((abs(pos[0]), 58, abs(pos[0]) + 10, img.height)))
            # 画布的x轴偏移量
            x_offset = 0
            # 创建一张画布
            # print(image_upper)
            # print('- -' * 30)
            # print(image_down)
            new_img = Image.new("RGB", (260, img.height))
            for img in image_upper:
                new_img.paste(img, (x_offset, 58))
                print(img)
                x_offset += img.width
    
            x_offset = 0
            for img in image_down:
                new_img.paste(img, (x_offset, 0))
                x_offset += img.width
    
            return new_img
    
        def get_distance(self, cut_image, full_image):
    
            # print(cut_image.size)
            threshold = 50
            for i in range(0, cut_image.size[0]):
                for j in range(0, cut_image.size[1]):
                    pixel1 = cut_image.getpixel((i, j))
                    pixel2 = full_image.getpixel((i, j))
                    res_R = abs(pixel1[0] - pixel2[0])  # 计算RGB差
                    res_G = abs(pixel1[1] - pixel2[1])  # 计算RGB差
                    res_B = abs(pixel1[2] - pixel2[2])  # 计算RGB差
    
                    if res_R > threshold and res_G > threshold and res_B > threshold:
                        return i  # 需要移动的距离
    
        # 移动滑块
        def start_move(self, distance):
            element = self.driver.find_element_by_xpath('//div[@class="gt_slider_knob gt_show"]')
    
            # 使用滑块的一半进行偏移设置
            distance -= element.size.get('width') / 2
            distance += 15
    
            # 按下鼠标左键
            ActionChains(self.driver).click_and_hold(element).perform()
            time.sleep(0.5)
            while distance > 0:
                if distance > 20:
                    # 如果距离大于20,就让他移动快一点
                    span = random.randint(5, 8)
                else:
                    # 快到缺口了,就移动慢一点
                    span = random.randint(2, 3)
                ActionChains(self.driver).move_by_offset(span, 0).perform()
                distance -= span
                time.sleep(random.randint(10, 60) / 100)
    
            ActionChains(self.driver).move_by_offset(distance, 1).perform()
            ActionChains(self.driver).release(on_element=element).perform()
    
    
    if __name__ == '__main__':
        h = Geek_Huxiu()
        h.run()
  • 相关阅读:
    MyEclipse2014安装插件的几种方式(适用于Eclipse或MyEclipse其他版本)
    淘淘商城 本地仓库配置和仓库jar包下载
    淘淘商城的第一天
    Oracle12c 性能优化攻略:攻略1-1:创建具有最优性能的数据库
    Eclipse开发环境配置
    Oracle12c 性能优化攻略:攻略目录表
    将日期或数据转换为char数据类型 TO_CHAR(x[[,c2],C3])
    根据条件返回相应值 decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)
    【功能】返回数据类型、字节长度和在内部的存储位置.DUMP(w[,x[,y[,z]]])
    alter table的用法
  • 原文地址:https://www.cnblogs.com/clbao/p/10845818.html
Copyright © 2020-2023  润新知