潭州课堂25班:Ph201805201 爬虫基础 第十二课 点触验证码二 (课堂笔记)

为上次代码添加 模拟人操作 的鼠标的移动轨迹

# -*- coding:utf-8 -*-
# 斌彬电脑
# @Time :   2018/9/14 0014    上午 8:08


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 import ActionChains     # 动作链
from selenium.webdriver.common.by import By
import requests,re
from PIL import Image
from io import BytesIO      # 不写入磁盘,显示图片文件
import time

from chao_ji_yin import Chaojiying_Client          # 超级鹰

class WanYy():
    def __init__(self, user, pas):
        # 浏览器参数
        self.user = user
        self.pas = pas
        options = Options()
        options.add_argument('--window-size=1366,768')
        self.dri = webdriver.Chrome(chrome_options=options)
        self.wait = WebDriverWait(self.dri, 10)

    def get_start(self):
        # 请求网页
        self.dri.get('http://dun.163.com/trial/picture-click')
        # 下拉页面
        self.dri.execute_script('window.scrollTo(0, 500)')

    def get_image(self):
        #  点击按键,显示验证码
        #  获取验证码 图片
        self.wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/main/div/div/div[2]/div[2]/div[2]/div/div[2]/div[3]/div/div/div[2]/div[3]/span[2]'))).click()
        #  等待加载完成 截图
        # time.sleep(2)
        # 验证码位置
        im = self.wait.until(EC.visibility_of_element_located((
            By.XPATH, '/html/body/main/div/div/div[2]/div[2]/div[2]/div/div[2]/div[3]/div/div/div[1]/div/div[1]/img[1]'
        )))  # 异步  比 time.sleep 好
        im1 = BytesIO(self.dri.get_screenshot_as_png())
        # Image.open(im).show()
        im2 = Image.open(im1)
        #                     浏览器的左上角坐标     -500 因为下滑了500,
        window_im = im2.crop((im.location['x'], im.location['y']-500,im.location['x']+310, im.location['y']+210-500))
        # window_im.show()
        im_data = BytesIO()
        window_im.save(im_data, format('png'))
        # 返回图片 二进制 数据
        return im_data.getvalue()

    # 调用超级鹰 识别验证码
    def post_validation_participation(self,im_data ):
        # 实例化 超级鹰
        chao = Chaojiying_Client(self.user, self.pas, '897271')
        data = chao.PostPic(im_data, '9103')      # 超级鹰反回的 json 数据
        data = data.get('pic_str')
        data_list = [i.split(',') for i in data.split('|')]   #  验证码图片上第个字的坐标
        # print(data_list)
        return data_list

      # 得到位置信息,进行点击
    def click_word(self, data_list):
        # 验证码位置 ,节点
        im = self.wait.until(EC.visibility_of_element_located((
            By.XPATH, '/html/body/main/div/div/div[2]/div[2]/div[2]/div/div[2]/div[3]/div/div/div[1]/div/div[1]/img[1]'
        )))
        #  根据节点移动鼠标
        # 移到第一个字位置
        ActionChains(self.dri).move_to_element_with_offset(im, int(data_list[0][0]), int(data_list[0][1])).perform()
        #  点击
        ActionChains(self.dri).click().perform()
        time.sleep(1)

        #       传入第一个位置 和 第二个字位置
        for i in self.track(data_list[0], data_list[1]):
        # 移到第二个字位置
            ActionChains(self.dri).move_to_element_with_offset(im, int(i[0]), int(i[1])).perform()
            # ActionChains(self.dri).move_to_element_with_offset(im, int(data_list[1][0]), int(data_list[1][1])).perform()
            #  点击
        ActionChains(self.dri).click().perform()
        time.sleep(1)

        # for i in self.track(data_list[1], data_list[2]):
        for i in self.track(data_list[1], data_list[2]):
            # 移到第三个字位置
            ActionChains(self.dri).move_to_element_with_offset(im, int(i[0]), int(i[1])).perform()
            # ActionChains(self.dri).move_to_element_with_offset(im, int(data_list[2][0]), int(data_list[2][1])).perform()
            #  点击
        ActionChains(self.dri).click().perform()

    # #  鼠标移动轨迹 模拟人操作点击
    def track(self, last_p, next_p):
        # 接收上个字的位置和下个字的位置
        # 鼠标移动轨迹列表
        position_list=[]
        #  字间的距离分成 20 分
        x = (int(next_p[0]) - int(last_p[0])) / 20
        y = (int(next_p[1]) - int(last_p[1])) / 20
        for i in range(1,21):
            # 走 20 步小步
            position = [round(x*i) + int(last_p[0]), round(y*i) + int(last_p[1])]
            position_list.append(position)

        return position_list


    #  像函数一样调用
    def __call__(self, *args, **kwargs):
        self.get_start()
        imdata = self.get_image()
        da_list = self.post_validation_participation(imdata)
        print(da_list)
        self.click_word(da_list)
        # time.sleep(5)
        # self.dri.close()


if __name__ == '__main__':
    yedun = WanYy('超级鹰账号', '密码')
    yedun()

  

第一个字位置直接给位置,执行点击,

之后 第二,第三个字调用  track 方法

在 track  方法中算出第一个字与第二个字的距离 ,之后分成 20 步执行,到达下个字的位置,进行点击 

在此之上的基础上,记录鼠标移动轨迹,存放在图片 a.png 中

# -*- coding:utf-8 -*-
# 斌彬电脑
# @Time :   2018/9/15 0015    上午 10:52


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 import ActionChains     # 动作链
from selenium.webdriver.common.by import By
import requests,re
from PIL import Image
from io import BytesIO      # 不写入磁盘,显示图片文件
import time

from chao_ji_yin import Chaojiying_Client          # 超级鹰

class WanYy():
    def __init__(self, user, pas):
        # 浏览器参数
        self.user = user
        self.pas = pas
        options = Options()
        options.add_argument('--window-size=1366,768')
        self.dri = webdriver.Chrome(chrome_options=options)
        self.wait = WebDriverWait(self.dri, 10)
        self.window_im = None


    def get_start(self):
        # 请求网页
        self.dri.get('http://dun.163.com/trial/picture-click')
        # 下拉页面
        self.dri.execute_script('window.scrollTo(0, 500)')

    def get_image(self):
        #  点击按键,显示验证码
        #  获取验证码 图片
        self.wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/main/div/div/div[2]/div[2]/div[2]/div/div[2]/div[3]/div/div/div[2]/div[3]/span[2]'))).click()
        #  等待加载完成 截图
        # time.sleep(2)
        # 验证码位置
        im = self.wait.until(EC.visibility_of_element_located((
            By.XPATH, '/html/body/main/div/div/div[2]/div[2]/div[2]/div/div[2]/div[3]/div/div/div[1]/div/div[1]/img[1]'
        )))  # 异步  比 time.sleep 好
        im1 = BytesIO(self.dri.get_screenshot_as_png())
        # Image.open(im1).show()
        im2 = Image.open(im1)


        #                     浏览器的左上角坐标     -500 因为下滑了500,
        self.window_im = im2.crop((im.location['x'], im.location['y']-500,im.location['x']+310, im.location['y']+210-500))
        # window_im.show()
        im_data = BytesIO()
        self.window_im.save(im_data, format('png'))
        # 返回图片 二进制 数据
        return im_data.getvalue()

    # 调用超级鹰 识别验证码
    def post_validation_participation(self,im_data ):
        # 实例化 超级鹰
        chao = Chaojiying_Client(self.user, self.pas, '897271')
        data = chao.PostPic(im_data, '9103')      # 超级鹰反回的 json 数据
        data = data.get('pic_str')
        data_list = [i.split(',') for i in data.split('|')]   #  验证码图片上第个字的坐标
        # print(data_list)
        return data_list

      # 得到位置信息,进行点击
    def click_word(self, data_list):
        # 验证码位置 ,节点
        img = self.window_im.convert('L')
        datami = img.load()  # 图片数据重构

        im = self.wait.until(EC.visibility_of_element_located((
            By.XPATH, '/html/body/main/div/div/div[2]/div[2]/div[2]/div/div[2]/div[3]/div/div/div[1]/div/div[1]/img[1]'
        )))
        #  根据节点移动鼠标
        # 移到第一个字位置
        ActionChains(self.dri).move_to_element_with_offset(im, int(data_list[0][0]), int(data_list[0][1])).perform()
        #  点击
        ActionChains(self.dri).click().perform()
        time.sleep(1)

        #       传入第一个位置 和 第二个字位置
        for i in self.track(data_list[0], data_list[1]):
        # 移到第二个字位置
        #     print(datami[int(i[0]), int(i[1])])
            if datami[int(i[0]), int(i[1])] > 125:
                datami[int(i[0]), int(i[1])] = 0
                datami[int(i[0])-1, int(i[1])-1] = 0
                datami[int(i[0])-2, int(i[1])-2] = 0
                datami[int(i[0])+1, int(i[1])+1] = 0
                datami[int(i[0])+2, int(i[1])+2] = 0
            else:
                datami[int(i[0]), int(i[1])] = 255
                datami[int(i[0])-1, int(i[1])-1] = 255
                datami[int(i[0])-2, int(i[1])-2] = 255
                datami[int(i[0])+1, int(i[1])+1] = 255
                datami[int(i[0])+2, int(i[1])+2] = 255
            ActionChains(self.dri).move_to_element_with_offset(im, int(i[0]), int(i[1])).perform()
            # ActionChains(self.dri).move_to_element_with_offset(im, int(data_list[1][0]), int(data_list[1][1])).perform()
            #  点击
        ActionChains(self.dri).click().perform()

        time.sleep(1)

        for i in self.track(data_list[1], data_list[2]):
            if datami[int(i[0]), int(i[1])] > 125:
                datami[int(i[0]), int(i[1])] = 0
                datami[int(i[0])-1, int(i[1])-1] = 0
                datami[int(i[0])-2, int(i[1])-2] = 0
                datami[int(i[0])+1, int(i[1])+1] = 0
                datami[int(i[0])+2, int(i[1])+2] = 0
            else:
                datami[int(i[0]), int(i[1])] = 255
                datami[int(i[0])-1, int(i[1])-1] = 255
                datami[int(i[0])-2, int(i[1])-2] = 255
                datami[int(i[0])+1, int(i[1])+1] = 255
                datami[int(i[0])+2, int(i[1])+2] = 255
            # 移到第三个字位置
            ActionChains(self.dri).move_to_element_with_offset(im, int(i[0]), int(i[1])).perform()
            # ActionChains(self.dri).move_to_element_with_offset(im, int(data_list[2][0]), int(data_list[2][1])).perform()
            #  点击
        ActionChains(self.dri).click().perform()

        img.save('a.png')

    # #  鼠标移动轨迹 模拟人操作点击
    def track(self, last_p, next_p):
        # 接收上个字的位置和下个字的位置
        # 鼠标移动轨迹列表
        position_list=[]
        #  字间的距离分成 20 分
        x = (int(next_p[0]) - int(last_p[0])) / 20
        y = (int(next_p[1]) - int(last_p[1])) / 20
        for i in range(1,21):
            # 走 20 步小步
            position = [round(x*i) + int(last_p[0]), round(y*i) + int(last_p[1])]
            position_list.append(position)

        return position_list


    #  像函数一样调用
    def __call__(self, *args, **kwargs):
        self.get_start()
        imdata = self.get_image()
        da_list = self.post_validation_participation(imdata)
        print(da_list)
        self.click_word(da_list)
        # time.sleep(5)
        # self.dri.close()


if __name__ == '__main__':
    yedun = WanYy('账号', '密码')
    yedun()

  

原文地址:https://www.cnblogs.com/gdwz922/p/9644391.html