问答 请问一下 selenium 报错:selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: 'value' must be a string 该怎么解决

花浅言 · 2022年02月21日 · 最后由 花浅言 回复于 2022年02月22日 · 11252 次阅读

这个问题百度了好多,找不到解决的方法

但 value 就是字符串啊

共收到 15 条回复 时间 点赞

没看到你详细的代码,不过看打印的信息,你的 xpath 值,里面单双引号混用了

刚刚改了一下,又出现了这种问题,send_keys 中 value 的值就是字符串

do_cf = ParseConFile()
URL = do_cf.get_locators_or_account('TESTURL', 'URL')
username = do_cf.get_locators_or_account('LoginAccountElements', 'username')
password = do_cf.get_locators_or_account('LoginAccountElements', 'password')
verification = do_cf.get_locators_or_account('LoginAccountElements', 'Verification')
login = do_cf.get_locators_or_account('LoginAccountElements', 'Login')


print(type(username))
print(username)
print(type(password))
print(password)
print(type(verification))
print(verification)
print(type(login))
print(login)


def login_busin(user, passwd):
    img_name = "../img/scr.png"
    br = WebKey(txt="gg")
    # try:
    br.open_url(URL)
    br.sleep(tm=1)
    br.__find_element__(lc='xpath', locator=username).send_keys(user)
    br.__find_element__(lc='xpath', locator=password, ).send_keys(value=passwd)
    read_image.screenshot(img_name)
    text = read_image.ocr(img_name)
    br.__find_element__(lc='xpath', locator=verification).send_keys(value=text)
    br.click(lc='xpath', locator=login)
    br.sleep(tm=1)
    br.sleep(10)
    br.close()

login_busin(user='ctz', passwd='admin123456?')

打印出来的是

<class 'tuple'>
('xpath', '//span[@class = "ant-input-affix-wrapper ant-input-affix-wrapper-lg"]/input[@placeholder=\'请输入帐户名\']')
<class 'tuple'>
('xpath', '//span[@class = "ant-input-affix-wrapper ant-input-affix-wrapper-lg"]/input[@placeholder=\'请输入密码\']')
<class 'tuple'>
('xpath', '//span[@class = "ant-input-affix-wrapper ant-input-affix-wrapper-lg"]/input[@placeholder=\'请输入验证码\']')
<class 'tuple'>
('xpath', "//button[@class='login_btn']")
Traceback (most recent call last):
  File "D:/dingdang_project/DD_changtu/libs/login_business.py", line 44, in <module>
    login_busin(user='ctz', passwd='admin123456?')
  File "D:/dingdang_project/DD_changtu/libs/login_business.py", line 30, in login_busin
    br.__find_element__(lc='xpath', locator=username).send_keys(user)
AttributeError: 'tuple' object has no attribute 'send_keys'
花浅言 回复

1、从两次的堆栈看,都不是执行 sendKeys 报的错(),而是 br.__find_element__。你一直去看 send_keys 方向不对。

2、你提供的代码里没有 __find_element__ 的完整实现,无法继续追查定位。如果需要进一步协助,麻烦把这部分源码以及涉及的其他相关函数源码也一并附上来吧。

PS:从你贴上来的代码里,username 这个传给 __find_element__ 的 locator 的值类型是 tuple 而非 string ,而从错误堆栈看这个 locator 是直接传给 self.driver.findElement(By.XPATH, locator) 的。正常 self.driver.findElement(By.XPATH, locator) 这里面的 locator 应该是 string 类型的,值内容就是 xpath 的具体定位路径,你也可以从这个角度去排查下。

这个把定位的方法写在一块了

def __find_element__(self, lc, locator):
    """元素定位"""
    if lc == "id":
        ele = self.driver.find_element(By.ID, locator)
        wdw(self.driver, 10).until(ec.visibility_of_element_located(ele))
    elif lc == "name":
        ele = self.driver.find_element(By.NAME, locator)
        wdw(self.driver, 10).until(ec.visibility_of_element_located(ele))
    elif lc == "xpath":
        ele = (By.XPATH, locator)
        wdw(self.driver, 10).until(ec.visibility_of_element_located(ele))
    elif lc == "tag_name":
        ele = self.driver.find_element(By.TAG_NAME, locator)
        wdw(self.driver, 10).until(ec.visibility_of_element_located(ele))
    elif lc == "link_text":
        ele = self.driver.find_element(By.LINK_TEXT, locator)
        wdw(self.driver, 10).until(ec.visibility_of_element_located(ele))
    elif lc == "partial_link_text":
        ele = self.driver.find_element(By.PARTIAL_LINK_TEXT, locator)
        wdw(self.driver, 10).until(ec.visibility_of_element_located(ele))
    elif lc == "css_selector":
        ele = self.driver.find_element(By.CSS_SELECTOR, locator)
        wdw(self.driver, 10).until(ec.visibility_of_element_located(ele))
    elif lc == "class_name":
        ele = self.driver.find_element(By.CLASS_NAME, locator)
        wdw(self.driver, 10).until(ec.visibility_of_element_located(ele))
    else:
        ele = self.driver.find_element(By.XPATH, locator)
        wdw(self.driver, 10).until(ec.visibility_of_element_located(ele))
    return ele

def send_key(self, lc, locator, value):
    """
    找到元素,并完成输入
    :param lc: 定位器,默认xpath定位
    :param locator:
    :param value:需要输入的字符串
    :return:
    """
    send = self.__find_element__(lc, locator)
    send.send_keys(value)

账号

username = xpath->//span[@class = "ant-input-affix-wrapper ant-input-affix-wrapper-lg"]/input[@placeholder='请输入帐户名']

密码

password = xpath->//span[@class = "ant-input-affix-wrapper ant-input-affix-wrapper-lg"]/input[@placeholder='请输入密码']

验证码图片

Verification_Code = xpath->//*[@class = "user-layout-login ant-form ant-form-horizontal"]/div[3]/div[2]/img

验证码输入框

Verification = xpath->//span[@class = "ant-input-affix-wrapper ant-input-affix-wrapper-lg"]/input[@placeholder='请输入验证码']

登录按钮

Login = xpath->//button[@class='login_btn']

def get_locators_or_account(self, section, option):
    """获取指定section, 指定option对应的数据, 返回元祖和字符串"""
    try:
        locator = self.conf.get(section, option)
        if ('->' in locator):
            locator = tuple(locator.split('->'))
        return locator[1]
    except configparser.NoOptionError as e:
        print('error:', e)
    return 'error: No option "{}" in section: "{}"'.format(option, section)

使用这个方法获取这个 xpath 地址信息,查了一下 type,也是 str 类型

花浅言 回复

有点奇怪,你上面贴的打印日志里,get_locators_or_account 返回的值类型是 tuple 哦?你看下是不是你那时候的代码有问题导致返回的是 tuple 类型?

就是 str 也会报这个错误

<class 'str'>
//span[@class = "ant-input-affix-wrapper ant-input-affix-wrapper-lg"]/input[@placeholder='请输入帐户名']
<class 'str'>
//span[@class = "ant-input-affix-wrapper ant-input-affix-wrapper-lg"]/input[@placeholder='请输入密码']
<class 'str'>
//span[@class = "ant-input-affix-wrapper ant-input-affix-wrapper-lg"]/input[@placeholder='请输入验证码']
<class 'str'>
//button[@class='login_btn']
Traceback (most recent call last):
  File "D:/dingdang_project/DD_changtu/libs/login_business.py", line 45, in <module>
    login_busin(user='ctz', passwd='admin123456?')
  File "D:/dingdang_project/DD_changtu/libs/login_business.py", line 31, in login_busin
    br.__find_element__(lc='xpath', locator=username).send_keys(user)
AttributeError: 'tuple' object has no attribute 'send_keys'

Process finished with exit code 1

现在就是不知道这个 tuple 格式数据哪里来的,找不到这个数据


是不是在这里?

花浅言 回复

elif lc == "xpath":
ele = (By.XPATH, locator)

是不是这里写错了啊,没有 find_element

那个补充之后,运行又提示 find_element() argument after * must be an iterable, not WebElement

😂 加油,Seldom,你值得拥有!

又运行了一下,莫名其妙的好了😂 ,谢谢各位的帮忙了 😀

debug 看一下就知道了。。

题外话:find_element 是不是可以优化下
1.wdw(self.driver, 10).until(ec.visibility_of_element_located(ele)) 可以提出来,而不是重复地放在每个 case 里面,
2.等待的时间,是不是可以设置个默认参数接受传入, 而不是写死

lazyBoy 回复

好的,我修改一下,谢谢😀

花浅言 关闭了讨论 02月24日 19:08
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册