• 潭州课堂25班:Ph201805201 爬虫基础 第十课 图像处理- 极验验证码 (课堂笔记)


    用 python 的  selenium  访问  https://www.huxiu.com/

    自动通过验证码

    # -*- coding: utf-8 -*-
    # 斌彬电脑
    # @Time : 2018/9/11 0011 4:38
    '''
    滑动验证码之  极验 验证码
    https://www.huxiu.com/
    '''
    
    from selenium import webdriver
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    from selenium.webdriver import ActionChains     # 动作链
    import requests,re
    from PIL import Image
    from io import BytesIO      # 不写入磁盘,显示图片文件
    import time, random
    
    class JiYan():
        def __init__(self):
            # 浏览器参数
            options = Options()
            options.add_argument('--window-size=1366,768')
            self.dri = webdriver.Chrome(chrome_options=options)
            self.btn = WebDriverWait(self.dri, 10)
    
        # 访问页面
        def to_request(self):
            self.dri.get('https://www.huxiu.com/')
            # 找到登录按钮
            self.btn.until(EC.presence_of_element_located((By.XPATH, '//a[@class="js-login"]'))).click()
            # 找到输入框
            f = self.btn.until(EC.presence_of_element_located((By.XPATH, '//input[@id="sms_username"]')))
            # 输入内容
            f.send_keys('13605838837')
    
        # 获取验证码图片
        def get_img(self):
            #
            # 没有缺陷的图片
            g_img = self.dri.find_elements_by_xpath( '//div[@class="gt_cut_fullbg gt_show"]/div')
            # print(len(g_img))
            # 拿到图片的 url 和 偏移量
            style_list = [i.get_attribute('style') for i in g_img]
            # print(style_list)
            # 匹配到连接 因为每个连接是一样的,所以只要匹配到一个就行
            # 验证码的图片连接
            img_url = re.search(r'url("(.*?)");',style_list[0]).group(1)
            # print(img_url)
            # 图片二进制的值
            img_con = requests.get(img_url).content
            #  得到完整的验证码
            get_po = self.get_img2(style_list, img_con)
            # get_po.show()                   #   显示出来
    
    
            # 有缺陷的图片
            bg_g_img = self.dri.find_elements_by_xpath( '//div[@class="gt_cut_bg gt_show"]/div')
            # 拿到图片的 url 和 偏移量
            style_list = [i.get_attribute('style') for i in bg_g_img]
            # 匹配到连接 因为每个连接是一样的,所以只要匹配到一个就行
            # 验证码的图片连接
            img_url2 = re.search(r'url("(.*?)");',style_list[0]).group(1)
            # print(img_url)
            # 图片二进制的值
            img_con = requests.get(img_url2).content
            #  得到完整的验证码
            bg_get_po = self.get_img2(style_list, img_con)
            # bg_get_po.show()
            # 调用比较函数
            return self.contrast(get_po, bg_get_po)
    
        # 拼接验证码
        def get_img2(self,style_list,image):
            #  拿到偏移量
            #                                          ?可能有的时候没有
            po_list = [re.findall(r'background-position: -(.*?)px -?(.*?)px;', i) for i in style_list]
            # print(po_list)
            # 新建图片
            im_new = Image.new('RGB',(260,116))
            im = Image.open(BytesIO(image))
            up = 0
            dn = 0
            for i in po_list[:26]:      #  前26个,上半部分
                # print(i)
                #     左上角x,   y   右上角 x,   y
                cro = im.crop((int(i[0][0]),58, int(i[0][0])+10,116))           # 拿到偏移量,进行裁剪
                #   up 为粘贴位置
                im_new.paste(cro,(up,0))                          #  把裁剪下的图片粘贴到新建空白图片上,得到张新图
                up += 10                        # 每张小图的宽度是10px,
    
            for i in po_list[26:]:      #  后26个,下半部分
                # print(i)
                #     左上角x,   y   右上角 x,   y
                cro = im.crop((int(i[0][0]),0, int(i[0][0])+10,58))           # 拿到偏移量,进行裁剪
                #   up 为粘贴位置
                im_new.paste(cro,(dn,58))                          #  把裁剪下的图片粘贴到新建空白图片上,得到张新图
                dn += 10                        # 每张小图的宽度是10px,
    
            return im_new
    
        #   有缺陷的图片与无缺陷的图片对比,得到距离值
        def  contrast(self,cut,no_cut):
            def contrast_pi(px1,px2):
                for i in range(3):      #  像素点的差达到指定值(RGB),
                    if abs(px1[i] - px2[i]) > 50:
                        return False
    
            for i in range(260):        # 宽度像素点
                for j in range(116):    # 高度像素点
                    px1 = cut.getpixel((i,j))   # 取得第一张每个像素点的值
                    px2 = no_cut.getpixel((i,j))   # 取得第二张每个像素点的值
                    if contrast_pi(px1,px2) is False :    #   比较两张图片同一位置的像素点的值
                        # 如果找到两张图片的像素差值达到要求,就返回 i ,得到滑动的距离
                        return  i
    
        # 控制浏览器滑动
        def slide(self, distance):
            # 可见滑动
            dis = self.btn.until(EC.visibility_of_element_located((By.XPATH, '//div[@class="gt_slider_knob gt_show"]')))
            # 点出不放
            ActionChains(self.dri).click_and_hold(dis).perform()
            time.sleep(0.5)
            # 移动     传入距离的值,X,Y
            # ActionChains(self.dri).move_by_offset(distance-5, 0).perform()
            for i in self.track(distance-5):
                ActionChains(self.dri).move_by_offset(i, 0).perform()
            time.sleep(0.6)
            # 释放-
            ActionChains(self.dri).release(dis).perform()
    
        # 模拟人拖动
        def track(self,distance):
            t = 0.2                   # 时间
            current = 0                 # 当前
            mid = distance * 3/5
            speed = 0                   # 速度
            move_distance_list = []
            while current < distance:   #  当前小于距离时,
                if current < mid:       # 如果当前小于中间距离
                    a = 2               #  加速度
                else:a = -5
                move_distance = speed*t+0.5*a*t*t
                move_distance_list.append(round( move_distance ))       #  整数添加进列表
                speed += (a*t)
                current += move_distance
    
            offset = sum(move_distance_list) - distance
            if offset > 0:
                move_distance_list.extend([-1]*offset)
            elif offset < 0:
                move_distance_list.extend( [1]*abs(offset) )
            #                         - 左移,          0 停止       右移
            move_distance_list.extend([-1,-1,-1,-1,-1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,-1.-1.-1.])
            return move_distance_list
    
    
        # 让类可以像函数一样调用 h() 执行类
        #def __call__(self, *args, **kwargs):
    
    h = JiYan()
    h.to_request()
    time.sleep(2)
    distance = h.get_img()
    h.slide(distance)
    

      

     在 linux 下

    python 的文字识别库(视觉系统)

    进行安装 

    (视觉系统)要与 pyghon 交互,所以还要安装pytesseract

    d

  • 相关阅读:
    错误解决记录-------------验证启动HDFS时遇到的错误
    Spark环境搭建(一)-----------HDFS分布式文件系统搭建
    Synergy简单使用小记
    python基础一 ------排序和查找算法
    Scrapy基础(十四)————Scrapy实现知乎模拟登陆
    Scrapy基础(十四)————知乎模拟登陆
    Scrapy基础(十三)————ItemLoader的简单使用
    Scrapy基础(十二)————异步导出Item数据到Mysql中
    简单python爬虫练习 E站本爬取
    7-4 jmu-Java&Python-统计文字中的单词数量并按出现次数排序 (25分)
  • 原文地址:https://www.cnblogs.com/gdwz922/p/9627588.html
Copyright © 2020-2023  润新知