在python中正确使用xpath和selenium

在python中正确使用xpath和selenium,python,selenium,xpath,Python,Selenium,Xpath,我将首先描述我想要实现的目标: 我在一个网页上有多个链接,我正在使用以下方法通过wach one进行循环: for link in dom.xpath('//div[@id="right-column"]//a/@href'): FINAL_URL = urlparse.urljoin(url, link) 在每一页上,我都必须按一个特定的链接,该链接始终位于同一位置: my_page = '//div[@class="product_info"]//table//tr[7]//td[

我将首先描述我想要实现的目标:

我在一个网页上有多个链接,我正在使用以下方法通过wach one进行循环:

for link in dom.xpath('//div[@id="right-column"]//a/@href'):
    FINAL_URL = urlparse.urljoin(url, link)
在每一页上,我都必须按一个特定的链接,该链接始终位于同一位置:

my_page = '//div[@class="product_info"]//table//tr[7]//td[2]//a/@href'

    for link1 in dom1.xpath(my_page):
    # more code to go
如果该链接以http开头,我想使用selenium打开它,搜索每个页面上可能有不同选择器的表单,然后按submit按钮:

for link1 in dom1.xpath(my_page):
        if link1[:4] == 'http':
            driver.get(link1)
            inputElement = driver.find_element_by_xpath("//input​[@*[contains(., 'name')]]")
            inputElement.send_keys("somename")
            inputElement1 = driver.find_element_by_xpath("//input​[@*[contains(., 'email')]]")
            inputElement1.send_keys("email@yahoo.com")
            inputElement1.send_keys(Keys.ENTER)
            assert "No results found." not in driver.page_source
现在,当我运行上述代码时,我得到:

line 38, in <module>  
inputElement = driver.find_element(By.XPATH, "//input​[@*[contains(., 'name')]]")
 File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 707, in find_element
{'using': by, 'value': value})['value']
selenium.common.exceptions.InvalidSelectorException
有谁能向我解释一下我做错了什么,以及我如何防止将来错误使用selenium和xpath


我也愿意接受对代码的任何建设性批评和改进。

从您的解释和代码片段中,我想,在您的站点上,实际上只有一个输入元素用于电子邮件,只有一个输入元素用于名称

如果您想通过检查它们是否包含具有相应名称的属性来查找它们,请按照以下方法进行操作:

name = driver.find_element_by_xpath("//input​[@name]")
name.send_keys("cevanume")
email = driver.find_element_by_xpath("//input​[@email]")
email.send_keys("email@yahoo.com")

请注意,有更好的解决方案,但如果您不共享HTML,就很难给出合适的建议…

如果您遇到很多无效选择异常错误,那么阅读一些教程或查找提供使用xpath识别HTML的简单示例的网站是绝对值得的

一般来说,在从头开始编写之前,您应该了解语法以及如何构造非常基本的表达式,就像编写数学方程一样,您需要了解-+/*的含义和运算顺序。这将帮助你在第一次尝试中获得成功,并且知道当你陷入困境时需要问什么问题

有很多教程,所以找一个对你有意义的,并通过它来学习

因为您确实有特定的XPath表达式,所以您现在正试图解决这个问题,主要是要更正语法:

//a/@href
//和/表示标记的节点,@s表示属性。上面的表达式将失败,因为@href不是锚标记内的节点。属性属于节点,您必须始终为它们指定一个值:

//a[@href="http://www.stackoverflow.com"]
您还希望使用尽可能短的表达式来进行精确匹配,这样,如果HTML文档发生轻微更改,那么它就不那么脆弱,也不太可能失败,因此您不必遍历所有//表/td/tr来获取标记

e、 g

如果属性是可能的,您还希望避免使用像//tr[7]这样的索引,因为不太具体的表达式很可能返回您不想要或找不到的元素,除非您的测试确实在验证文档中第七个tr标记是什么,并且应该总是失败,否则这通常不是您想要做的

对于你的主要问题,这是关于部分匹配的,这里有一些关于@*可以做什么和如何做的澄清。可以做什么,以及如何使用包含:

//input​[@*[contains(., 'name')]]
本例中的嵌套括号不是有效的xpath。要使其成为有效的xpath表达式,请这样编写

//input​[contains(@*, "name")]
xpath应该找到任何具有包含名称的值的属性的输入标记,如

<input something="name" somethingelse="anothervalue">
<input something="value" somethingelse="name">

很多人更喜欢使用更简单、更不脆弱的定位器,因为DOM中意外的更改会很容易破坏xpath,而且总是有很多这样的定位器。因此,通过\ id查找\元素\或者通过\类查找\元素\都是非常好的选择,可以更灵活地使用。如果您更好地理解该语法,还可以通过使用CSS定位器来避免xpath。

通过//输入您想要什么​[@*[包含.,'name']]。请分享html好吗?我想在输入标签中找到值名称和电子邮件。如果找到其中一个值,请插入一个值并按enter键。HTML在页面之间是不同的,我必须找到一个共同的元素。所以HTML是多余的。你试过//输入[contains@*,'name']]吗?是的,我试过了。它找不到元素。我面临的问题是,每个输入都可能不同,我必须找到一种编写xpath的方法来处理这个问题,以值“name”为例。这两个元素都是你想要处理的。我说的对吗?我已经建议//输入​[包含@*,名称]。但是帖子所有者说它不起作用。即使我尝试了你的方法,我仍然得到selenium.common.exceptions.InvalidSelectorException。我不知道为什么它不起作用。您需要提供一个HTML示例,然后再回答您的问题。如果不知道文档的外观,通常无法编写复杂的xpath。-如果你不能,我希望关于如何编写有效xpath的解释能对你以后有所帮助。他想处理具有属性值“name”或“email”而不是属性键的标记。
//input​[contains(@*, "name")]
<input something="name" somethingelse="anothervalue">
<input something="value" somethingelse="name">
<input>name</input>
//input​[contains(., "name") or contains(@*, "name")]