关于#selenium#的问题,请各位专家解答!

写了一个自动登录b站的脚本但是在识别验证码的那个动作链中老是出现错误,动作链老是不执行,报错:selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable: [object HTMLDivElement] has no size and location,求大神解决
代码如下:

from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.options import Options
import requests
from hashlib import md5
from PIL import  Image
from selenium.webdriver import ActionChains

class Chaojiying_Client(object):

    def __init__(self, username, password, soft_id):
        self.username = username
        password = password.encode('utf8')

        self.password = md5(password).hexdigest()
        self.soft_id = soft_id
        self.base_params = {
            'user': self.username,
            'pass2': self.password,
            'softid': self.soft_id,
        }
        self.headers = {
            'Connection': 'Keep-Alive',
            'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
        }

    def PostPic(self, im, codetype):
        """
        im: 图片字节
        codetype: 题目类型 参考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': codetype,
        }
        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', im)}
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files,
                          headers=self.headers)
        return r.json()

    def ReportError(self, im_id):
        """
        im_id:报错题目的图片ID
        """
        params = {
            'id': im_id,
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
        return r.json()

option=Options()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
url='https://www.bilibili.com/'
account='15166772055'
password='xia20030210'
bro=webdriver.Edge(options=option)
bro.get(url)
sleep(1)
btn1=bro.find_element(By.XPATH,'/html/body/div[2]/div[2]/div[1]/div[1]/ul[2]/li[1]').click()
sleep(5)

sleep(5)
account_input=bro.find_element(By.XPATH,'/html/body/div[3]/div/div[4]/div[2]/form/div[1]/input').send_keys(account)
sleep(5)

password_input=bro.find_element(By.XPATH,'/html/body/div[3]/div/div[4]/div[2]/form/div[3]/input').send_keys(password)
sleep(5)
login=bro.find_element(By.XPATH,'/html/body/div[3]/div/div[4]/div[2]/div[2]/div[2]').click()
sleep(5)

#save_screenshot就是将当前页面截图并保存
bro.save_screenshot('bilibili验证码.png')

#确定验证码图片对应的左上角和右下角的坐标(裁剪的区域确定)
code_imgele=bro.find_element(By.CLASS_NAME,'geetest_panelshowclick')
location=code_imgele.location#验证码图片左上角的坐标x y
size=code_imgele.size#验证码对应的长和宽
#左上角和右下角坐标
rangle=(int(location['x']),int(location['y']),int(location['x']+size['width']),int(location['y']+size['height']))
#至此验证码图片区域就确定下来了

i=Image.open('bilibili验证码.png')
code_imge_name='./code.png'
frame=i.crop(rangle)
frame.save(code_imge_name)


chaojiying = Chaojiying_Client('aoldcook', 'xia20030210', '951810')  # 用户中心>>软件ID 生成一个替换 96001
im = open('code.png', 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
# print(chaojiying.PostPic(im, 1902))  # 1902 验证码类型  官方网站>>价格体系 3.4+版 print 后要加()
result=chaojiying.PostPic(im, 9004)['pic_str']
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)
print(all_list)

for l in all_list:
    x=int(l[0])
    y=int(l[1])
    print(x,y)
    action = ActionChains(bro)
    action.move_to_element_with_offset(code_imgele,x,y)
    action.click().perform()
    sleep(2)

# 执行点击操作
sure_name=bro.find_element(By.XPATH,'/html/body/div[4]/div[2]/div[6]/div/div/div[3]/a')
bro.execute_script("arguments[0].click();", sure_name)
sleep(10)
bro.quit()

引用 皆我百晓生 小程序回复内容作答:
根据你提供的代码,报错信息是'selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable: [object HTMLDivElement] has no size and location',这个错误通常是由于元素无法与用户进行交互导致的。

根据代码中的报错信息,错误发生在动作链中的action.move_to_element_with_offset(code_imgele,x,y)这一行。可能的原因是验证码图片元素code_imgele没有正确加载或者没有正确定位到该元素。

你可以尝试以下几种方法来解决这个问题:

  1. 确保验证码图片元素code_imgele已经正确加载。你可以使用WebDriverWait来等待元素的出现,例如:
    ```python
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC

code_imgele = WebDriverWait(bro, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_panelshowclick')))


2. 确保验证码图片元素`code_imgele`已经正确定位到。你可以使用其他定位方式,例如使用`By.CSS_SELECTOR`或者`By.ID`来定位元素。

3. 确保验证码图片元素`code_imgele`在页面上可见。你可以使用`WebDriverWait`来等待元素的可见性,例如:
```python
code_imgele = WebDriverWait(bro, 10).until(EC.visibility_of_element_located((By.CLASS_NAME, 'geetest_panelshowclick')))

尝试以上方法后,如果问题仍然存在,请检查你的代码逻辑是否正确,确保动作链的执行顺序和参数传递正确。另外,你也可以尝试使用其他的验证码识别方法或者工具来解决验证码的识别问题。