selenium 带有Chrome驱动程序的Python Selple“Send_Key”丢弃字符

vwkv1x7d  于 2022-11-10  发布在  Python
关注(0)|答案(4)|浏览(156)

当我尝试登录我的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丢失了密码的第一个字符(我通过直接将密码字符发送到电子邮件字段发现了这一点。
到底怎么回事?为什么Selify不能做一些简单的事情,比如将键发送到输入域?这是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是如何...Firefox驱动程序缺少Y、Z(将browser = webdriver.Chrome()替换为browser = webdriver.Firefox()我得到:ABCDEFGHIJKLMNOPQRSTUVWXYZ

sgtfey8w

sgtfey8w1#

看起来Chrome Web驱动程序中有一些错误:https://code.google.com/p/chromedriver/issues/detail?id=435
问题的核心看起来是当键盘被配置为非英语语言时,或者如果网络驱动程序进程和Chrome显示器在不同的语言/环境中运行(例如,当通过从一个主机到另一个主机的远程显示器时,等等)。

ctehm74n

ctehm74n2#

我已经使用Send_Key的定制方法解决了问题,该方法的运行速度稍低,但速度足够快。

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)
nhaq1z21

nhaq1z213#

我遇到了和OP类似的问题,我对这里写的答案都不满意,也不满意我在这个网站上找到的任何其他地方的答案。因为我在研究过程中读到这个问题在某个时间点上得到了解决,我不得不假设它现在再次出现。
正如P.T.所提到的,如果您遇到类似的问题,ChromeDrivers/FirefoxDrivers很有可能再次出现故障。
因为我发现的解决方案都不能帮助缓解这个问题,所以我选择了完全绕过Selify及其驱动程序。因此,我使用了Java脚本首先找到元素(通过它的绝对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

moiiocjp

moiiocjp4#

在PYTHON中使用Selify 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()

相关问题