51Testing软件测试论坛

标题: selenium自动登录B站,验证码坐标点击不对 [打印本页]

作者: 测试积点老人    时间: 2022-9-9 15:11
标题: selenium自动登录B站,验证码坐标点击不对

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

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


  1. import time,random
  2. from posixpath import split
  3. from selenium.webdriver.common.by import By
  4. from selenium.webdriver.common.action_chains import ActionChains
  5. from lib2to3.pgen2 import driver
  6. from selenium import webdriver
  7. from PIL import Image
  8. from chaojiying import Chaojiying_Client

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

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

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

  23.     time.sleep(3)

  24.     driver.find_element(by=By.XPATH,value='//*[@class="bili-mini-account"]/input').send_keys('账号')
  25.     driver.find_element(by=By.XPATH,value='//*[@class="left"]/input').send_keys('密码')
  26.     driver.find_element(by=By.XPATH,value='//*[@class="universal-btn login-btn"]').click()
  27.     time.sleep(3)
  28. #验证码截图
  29. def save_img():
  30.     #对当前页面截图保存
  31.     driver.save_screenshot(r'selenium案例\B站\page.png')
  32.     #定位验证码图片的位置
  33.     code_img_ele = driver.find_element(by=By.XPATH,value='//*[@class="geetest_panel_box geetest_no_logo geetest_panelshowclick"]')
  34.     #获取验证码左上角的坐标x,y
  35.     location = code_img_ele.location
  36.     #获取验证码图片的长宽
  37.     size = code_img_ele.size
  38.     print(location)
  39.     print(size)
  40.     #左上角和右下角的坐标
  41.     rangle = (
  42.         int(location['x']*1.5), #乘以1.5为电脑系统缩放比例,否则定位不准
  43.         int(location['y']*1.5),
  44.         int((location['x']+size['width'])*1.5),
  45.         int((location['y']+size['height'])*1.5)   
  46.     )
  47.     print(rangle)
  48.     i = Image.open(r'selenium案例\B站\page.png')
  49.     #crop根据rangle元组内的坐标进行裁剪
  50.     frame = i.crop(rangle)
  51.     frame.save(r'selenium案例\B站\code.png')
  52.     return code_img_ele
  53. #图片缩小一半
  54. def narrow_img():
  55.     #缩小图片
  56.     code = Image.open(r'selenium案例\B站\code.png')
  57.     #图片尺寸缩小一半提交超级鹰
  58.     small_width = int(code.size[0]/2)
  59.     small_height = int(code.size[1]/2)
  60.     print(small_width,small_height)
  61.     small_img = code.resize((small_width,small_height))  
  62.     small_img.save(r'selenium案例\B站\small_img.png')
  63.     print(code.size,'\n',small_img.size)
  64. #缩小后的图片提交超级鹰
  65. def submit_img():
  66.     #将验证码提交给超级鹰识别
  67.     chaojiying = Chaojiying_Client('账号','密码','938224')# 用户中心>>软件ID 生成一个替换 96001
  68.     im = open(r'selenium案例\B站\small_img.png','rb').read()# 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
  69.     print(chaojiying.PostPic(im,9004)['pic_str'])# 9004是验证码类型
  70.     result = chaojiying.PostPic(im,9004)['pic_str']
  71.     print(type(result))
  72.     return result
  73. #对返回坐标进行处理
  74. def parse_data(result):
  75.     all_list = []# 要存储即将被点击的点的坐标  [[x1,y1],[x2,y2]]
  76.     if '|' in result:
  77.         list_1 = result.split('|')
  78.         count_1 = len(list_1)
  79.         for i in range(count_1):
  80.             xy_list = []
  81.             x = int(list_1[i].split(',')[0])
  82.             y = int(list_1[i].split(',')[1])
  83.             xy_list.append(x)
  84.             xy_list.append(y)
  85.             all_list.append(xy_list)
  86.     else:
  87.         x = int(result.split(',')[0])
  88.         y = int(result.split(',')[1])
  89.         xy_list = []
  90.         xy_list.append(x)
  91.         xy_list.append(y)
  92.         all_list.append(xy_list)
  93.     return all_list
  94. #网页自动点击
  95. def click_codeimg(all_list,code_img_ele):
  96.     # 遍历列表,使用动作链对每一个列表元素对应的x,y指定的位置进行点击操作
  97.     # x,y坐标乘2和2/3,是由于之前图片缩放过,所以*2,2/3是因为本人电脑桌面缩放比例为150%,需要还原成1
  98.     for l in all_list:
  99.         x = l[0]*2*0.666
  100.         y = l[1]*2*0.666
  101.         # 将点击操作的参照物移动到指定的模块,
  102.         # 若用方法二获取的验证码图片,要添加下面代码对code_img_ele赋值
  103.         # 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')
  104.         ActionChains(driver).move_to_element_with_offset(code_img_ele,x,y).click().perform()
  105.         print('点击已完成')
  106.         time.sleep(random.random())

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

  124. if __name__=='__main__':
  125.     main()





复制代码



作者: qqq911    时间: 2022-9-13 11:32
都是有反爬机制的
作者: kallinr    时间: 2022-9-13 14:59
反扒了
作者: jingzizx    时间: 2022-9-13 17:40
看看哪里开始出现偏差的




欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2