测试积点老人 发表于 2022-9-9 15:11:44

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/2)
    small_height = int(code.size/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 = []# 要存储即将被点击的点的坐标[,]
    if '|' in result:
      list_1 = result.split('|')
      count_1 = len(list_1)
      for i in range(count_1):
            xy_list = []
            x = int(list_1.split(','))
            y = int(list_1.split(','))
            xy_list.append(x)
            xy_list.append(y)
            all_list.append(xy_list)
    else:
      x = int(result.split(','))
      y = int(result.split(','))
      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*2*0.666
      y = l*2*0.666
      # 将点击操作的参照物移动到指定的模块,
      # 若用方法二获取的验证码图片,要添加下面代码对code_img_ele赋值
      # code_img_ele = bro.find_element_by_xpath('/html/body/div/div/div/div/div/div/div/div/div/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()







qqq911 发表于 2022-9-13 11:32:46

都是有反爬机制的

kallinr 发表于 2022-9-13 14:59:22

反扒了

jingzizx 发表于 2022-9-13 17:40:57

看看哪里开始出现偏差的
页: [1]
查看完整版本: selenium自动登录B站,验证码坐标点击不对