带有 chrome 驱动程序的 python 硒“send_keys”会丢弃字符

Posted

技术标签:

【中文标题】带有 chrome 驱动程序的 python 硒“send_keys”会丢弃字符【英文标题】:python's selenium "send_keys" with chrome driver drops characters 【发布时间】:2013-08-03 13:01:35 【问题描述】:

我在 Windows 7 中使用带有 Python (https://pypi.python.org/pypi/selenium) 的 selenium 包。 当我尝试登录我的 Facebook 帐户时,我使用 send_keys 命令,例如

elem = browser.find_element_by_name("email")
elem.send_keys(email);
elem = browser.find_element_by_name("pass")
elem.send_keys(password);

登录失败显然是因为第二个send_keys 丢失了密码的第一个字符(我通过直接将密码字符发送到电子邮件字段来发现这一点。

发生了什么事?为什么 selenium 不能做一些简单的事情,比如将键发送到输入字段? 这是 Facebook 为拒绝自动脚本编写的某种保护措施吗?

尝试发送整个字母表并得到了这个:

abcdefghijklmnopqrstuvwxyzBCDFGIKLNOQSTWX

注意缺少多少字符...

更新

显然问题与 facebook 无关,而与 chrome 驱动程序有关。

如果我发送以下简单代码

browser = webdriver.Chrome()
browser.get("https://www.google.com") # Load page
elem = browser.find_element_by_name("q") # Find the query box
query= "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
elem.send_keys(query)

使用 chrome 驱动程序,我得到 BCDFGIKLNOQSTWX 注意 A、E、H ... Y、Z 是如何丢失的 使用 Firefox 驱动程序(将 browser = webdriver.Chrome() 替换为 browser = webdriver.Firefox() 我得到: ABCDEFGHIJKLMNOPQRSTUVWXYZ

【问题讨论】:

就个人而言,我从未在任何网站(包括 Facebook)上遇到过此问题。您是否尝试过在密码字段中输入文本之前对implicit-wait 进行排序? 嗯,我在 PhantomJS 驱动程序中也观察到了这一点。 见***.com/questions/18483419/… 有迹象表明使用非英语键盘布局或使用远程显示器可能是罪魁祸首。 【参考方案1】:

Chrome 网络驱动程序中似乎存在一些错误:https://code.google.com/p/chromedriver/issues/detail?id=435

问题的核心似乎是当键盘配置为非英语语言,或者 webdriver 进程和 chrome 显示器在不同的语言/环境中运行时(例如,当从一个主机到另一个主机,等等)

【讨论】:

【参考方案2】:

我已经解决了使用 send_keys 的自定义方法,它的工作有点低但足够快。

from selenium.webdriver.remote.webelement import WebElement

def send_keys(el: WebElement, keys: str):
    for i in range(len(keys)):
        el.send_keys(keys[i])

send_keys(el, keys)

【讨论】:

【参考方案3】:

我遇到了与 OP 类似的问题,并且对这里写的任何答案都不满意,也没有在本网站上我能找到的任何其他地方找到答案。 由于我在研究期间读到该问题已在某个时间点得到解决,因此我不得不假设它现在再次出现。

作为 P.T.提到过,如果您遇到类似的问题,chromedrivers/firefoxdrivers 很可能再次出现错误。

由于我找到的解决方案都没有帮助缓解这个问题,因此我选择完全绕过 selenium 及其驱动程序。所以我使用javascript首先找到元素(通过它的绝对Xpath),然后写入/设置它。

from selenium import webdriver

def write_to_element(driver, element_xpath, input_string), 
        js_command = f'document.evaluate(\'xpath\', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.value = \'input_string\';'
        driver.execute_script(js_command)

driver = webdriver.Chrome()
driver.get('WebPage/With/Element/You/Want/To/Write/To')
xpath = 'Xpath/Of/Element/You/Want/To/Write/To'
write_to_element(driver, xpath, 'SomeRandomInput')

document.evaluate(\'xpath\', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null) 评估元素的 xpath,因此基本上可以在网页上找到您的元素。

.singleNodeValue.value = \'input_string\';'将该元素的值设置为input_string

【讨论】:

【参考方案4】:

在python中使用selenium Ide并导出测试用例

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
import unittest, time, re

class Test1(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url = "https://www.facebook.com/"
        self.verificationErrors = []
        self.accept_next_alert = True

    def test_1(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_id("email").clear()
        driver.find_element_by_id("email").send_keys("username")
        driver.find_element_by_id("pass").clear()
        driver.find_element_by_id("pass").send_keys("password")
        driver.find_element_by_id("u_0_b").click()
        driver.find_element_by_xpath("//div[@id='u_ps_0_1_5']/div/div").click()
        driver.find_element_by_link_text("1 Requests").click()
        driver.find_element_by_id("globalContainer").click()

    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException, e: return False
        return True

    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException, e: return False
        return True

    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True

    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
    unittest.main()

【讨论】:

嗨,Smita - 这应该有什么帮助?生成的代码包含与 OP 自己的代码相同的两个 send_keys() 调用。

以上是关于带有 chrome 驱动程序的 python 硒“send_keys”会丢弃字符的主要内容,如果未能解决你的问题,请参考以下文章

不能使用带有硒的镀铬按钮

带有硒测试容器的junit5无法正常工作

如何使用硒网络驱动程序中的ruby脚本在chrome中打开新标签[重复]

单击带有硒和python的href按钮?

像带有硒 python 的 instagram 照片

使用硒加载铬延伸