深度学习,深度睡眠 2022-08-26 18:34 采纳率: 68.8%
浏览 53
已结题

selenium自动登录B站,验证码坐标点击不对

我电脑缩放比例为150%,所以图片坐标都乘以1.5,然后把图片缩小一半,提交超级鹰,返回坐标,坐标再乘以2(因为之前缩小一半),再乘以2/3(电脑缩放比例为150%,还原为100%),整个代码跑得通,就是到点击验证码坐标时不对,不知道是我代码错了还是超级鹰返回的坐标有问题。

思路:截图➡图片处理➡提交超级鹰➡返回坐标


import time,random
from posixpath import split
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from lib2to3.pgen2 import driver
from selenium import webdriver
from PIL import Image
from chaojiying import Chaojiying_Client

 #隐藏 WebDriver 提示条和自动化扩展信息
option = webdriver.ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])

#进入开发者模式,去除滑块验证
option.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=option)
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})' })
#登录
def login():
    #访问某宝,窗口最大化
    driver.get('https://www.bilibili.com')
    driver.maximize_window()

    if driver.find_element(by=By.CLASS_NAME,value='header-login-entry'):
        driver.find_element(by=By.CLASS_NAME,value='header-login-entry').click()

    time.sleep(3)

    driver.find_element(by=By.XPATH,value='//*[@class="bili-mini-account"]/input').send_keys('账号')
    driver.find_element(by=By.XPATH,value='//*[@class="left"]/input').send_keys('密码')
    driver.find_element(by=By.XPATH,value='//*[@class="universal-btn login-btn"]').click()
    time.sleep(3)
#验证码截图
def save_img():
    #对当前页面截图保存
    driver.save_screenshot(r'selenium案例\B站\page.png')
    #定位验证码图片的位置
    code_img_ele = driver.find_element(by=By.XPATH,value='//*[@class="geetest_panel_box geetest_no_logo geetest_panelshowclick"]')
    #获取验证码左上角的坐标x,y
    location = code_img_ele.location
    #获取验证码图片的长宽
    size = code_img_ele.size
    print(location)
    print(size)
    #左上角和右下角的坐标
    rangle = (
        int(location['x']*1.5), #乘以1.5为电脑系统缩放比例,否则定位不准
        int(location['y']*1.5),
        int((location['x']+size['width'])*1.5),
        int((location['y']+size['height'])*1.5)   
    )
    print(rangle)
    i = Image.open(r'selenium案例\B站\page.png')
    #crop根据rangle元组内的坐标进行裁剪
    frame = i.crop(rangle)
    frame.save(r'selenium案例\B站\code.png')
    return code_img_ele
#图片缩小一半
def narrow_img():
    #缩小图片
    code = Image.open(r'selenium案例\B站\code.png')
    #图片尺寸缩小一半提交超级鹰
    small_width = int(code.size[0]/2)
    small_height = int(code.size[1]/2)
    print(small_width,small_height)
    small_img = code.resize((small_width,small_height))  
    small_img.save(r'selenium案例\B站\small_img.png')
    print(code.size,'\n',small_img.size)
#缩小后的图片提交超级鹰
def submit_img():
    #将验证码提交给超级鹰识别
    chaojiying = Chaojiying_Client('账号','密码','938224')# 用户中心>>软件ID 生成一个替换 96001
    im = open(r'selenium案例\B站\small_img.png','rb').read()# 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    print(chaojiying.PostPic(im,9004)['pic_str'])# 9004是验证码类型
    result = chaojiying.PostPic(im,9004)['pic_str']
    print(type(result))
    return result
#对返回坐标进行处理
def parse_data(result):
    all_list = []# 要存储即将被点击的点的坐标  [[x1,y1],[x2,y2]]
    if '|' in result:
        list_1 = result.split('|')
        count_1 = len(list_1)
        for i in range(count_1):
            xy_list = []
            x = int(list_1[i].split(',')[0])
            y = int(list_1[i].split(',')[1])
            xy_list.append(x)
            xy_list.append(y)
            all_list.append(xy_list)
    else:
        x = int(result.split(',')[0])
        y = int(result.split(',')[1])
        xy_list = []
        xy_list.append(x)
        xy_list.append(y)
        all_list.append(xy_list)
    return all_list
#网页自动点击
def click_codeimg(all_list,code_img_ele):
    # 遍历列表,使用动作链对每一个列表元素对应的x,y指定的位置进行点击操作
    # x,y坐标乘2和2/3,是由于之前图片缩放过,所以*2,2/3是因为本人电脑桌面缩放比例为150%,需要还原成1
    for l in all_list:
        x = l[0]*2*0.666
        y = l[1]*2*0.666
        # 将点击操作的参照物移动到指定的模块,
        # 若用方法二获取的验证码图片,要添加下面代码对code_img_ele赋值
        # code_img_ele = bro.find_element_by_xpath('/html/body/div[2]/div[2]/div[6]/div/div/div[2]/div[1]/div/div[2]/img')
        ActionChains(driver).move_to_element_with_offset(code_img_ele,x,y).click().perform()
        print('点击已完成')
        time.sleep(random.random())

    time.sleep(random.random())
    #完成动作链点击操作后,定位确认按钮并点击
    driver.find_element(by=By.XPATH,value='//*[@class="geetest_commit_tip"]').click()
    print('登录成功')
def main():
    #进入登录界面,输入账号密码
    login()
    #保存页面截图,并根据坐标裁剪获取验证码图片
    code_img_ele = save_img()
    #缩小图片
    narrow_img()
    #将图片提交给超级鹰,获取返回值
    result = submit_img()
    #解析返回值,将数据格式化
    all_list = parse_data(result)
    #在页面验证码上完成点击操作
    click_codeimg(all_list,code_img_ele)

if __name__=='__main__':
    main()






  • 写回答

1条回答 默认 最新

  • honestman_ 2022-08-26 18:39
    关注

    建议把超级鹰的账号密码以及id马赛克
    超级鹰的坐标返回是以图片左上角为坐标原点的,用定位图片的左上角坐标加上返回的坐标应该就行了

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 9月7日
  • 修改了问题 8月26日
  • 创建了问题 8月26日

悬赏问题

  • ¥200 csgo2的viewmatrix值是否还有别的获取方式
  • ¥15 Stable Diffusion,用Ebsynth utility在视频选帧图重绘,第一步报错,蒙版和帧图没法生成,怎么处理啊
  • ¥15 请把下列每一行代码完整地读懂并注释出来
  • ¥15 pycharm运行main文件,显示没有conda环境
  • ¥15 寻找公式识别开发,自动识别整页文档、图像公式的软件
  • ¥15 为什么eclipse不能再下载了?
  • ¥15 编辑cmake lists 明明写了project项目名,但是还是报错怎么回事
  • ¥15 关于#计算机视觉#的问题:求一份高质量桥梁多病害数据集
  • ¥15 特定网页无法访问,已排除网页问题
  • ¥50 如何将脑的图像投影到颅骨上