我使用Selenium进行网页编写,现在我想查找用户可以点击的所有元素,其中包含单词" download" (在任何大小写中)链接文本,按钮文本,元素id
,元素class
或href
。这可以包括链接,按钮或任何其他元素。
在this answer中,我找到了一个xpath,寻找xpath来搜索基于某个文本的按钮(或非区分大小写和部分匹配):
text = 'download'
driver.find_elements_by_xpath("(//*[contains(text(), 'download')]")
但在this page上没有返回任何结果,即使以下链接在那里:
<a id="downloadTop" class="navlink" href="javascript:__doPostBack('downloadTop','')">Download</a>
有没有人知道如何找到所有以某种方式包含单词的元素&#34; download&#34;在一个网站?
[编辑]
此问题被标记为问题的副本,其中an answer建议将其更改为"//*[text()[contains(.,'download')]]"
。所以我尝试了以下内容:
>>> from selenium import webdriver
>>> d = webdriver.Firefox()
>>> link = 'https://www.yourticketprovider.nl/LiveContent/tickets.aspx?x=492449&y=8687&px=92AD8EAA22C9223FBCA3102EE0AE2899510C03E398A8A08A222AFDACEBFF8BA95D656F01FB04A1437669EC46E93AB5776A33951830BBA97DD94DB1729BF42D76&rand=a17cafc7-26fe-42d9-a61a-894b43a28046&utm_source=PurchaseSuccess&utm_medium=Email&utm_campaign=SystemMails'
>>> d.get(link)
>>> d.find_elements_by_xpath("//*[text()[contains(.,'download')]]")
[] # As you can see it still doesn't get any results..
>>>
有没有人知道如何获取用户可以点击的所有元素以及包含单词&#34; download&#34;在链接文本,按钮文本,元素id
,元素class
还是href
?欢迎所有提示!
答案 0 :(得分:3)
试试这个:
//*[(@id|@class|@href|text())
[contains(translate(.,'DOWNLOAD','download'), 'download')]]
此Xpath 1.0表达式选择:具有id
或class
或href
属性或text-node子元素的所有元素,其字符串值包含字符串“下载:任何大写字母。
这是一个正在运行的证据。下面的XSLT转换用于评估XPath表达式并将所有选定节点复制到输出:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"//*[(@id|@class|@href|text())
[contains(translate(.,'DOWNLOAD','download'), 'download')]]
"/>
</xsl:template>
</xsl:stylesheet>
当我们将转换应用于以下测试文档时:
<html>
<a id="downloadTop" class="navlink"
href="javascript:__doPostBack('downloadTop','')">Download</a>
<b id="y" class="x_downLoad"/>
<p>Nothing to do_wnLoad</p>
<a class="m" href="www.DownLoad.com">Get it!</a>
<b>dOwnlOad</b>
</html>
选择所需元素,然后将其复制到输出:
<a id="downloadTop" class="navlink" href="javascript:__doPostBack('downloadTop','')">Download</a>
<b id="y" class="x_downLoad"/>
<a class="m" href="www.DownLoad.com">Get it!</a>
<b>dOwnlOad</b>
答案 1 :(得分:1)
嗯,你找到的答案已经告诉你如何做你想做的事。我看到的问题是text = 'download'
以小写字母开头,而<a id="downloadTop" class="navlink" href="javascript:__doPostBack('downloadTop','')">Download</a>
中的文字以大写字母开头。
首先将文字更改为text = 'Download'
,然后查看它是否现在找到了您的元素。如果这是问题,那么你可以使用像
text = 'ownload'
driver.find_elements_by_xpath("(//*[contains(text(), '" + text + "')] | //*[@value='" + text + "'])")
忽略第一个字符。
编辑:是的,你可以使它不区分大小写。
driver.find_elements_by_xpath("(//*[contains(translate(text(), 'DOWNLOAD', 'download'), 'download')])")
答案 2 :(得分:0)
如果您仍然希望更多地概括xpath
并且不想使用该translate
函数,则可以使用itertools.product
并生成所有变体字符串download
为node
文字属性,如下所示。
from itertools import product
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("https://www.yourticketprovider.nl/LiveContent/tickets.aspx?x=492449&y=8687&px=92AD8EAA22C9223FBCA3102EE0AE2899510C03E398A8A08A222AFDACEBFF8BA95D656F01FB04A1437669EC46E93AB5776A33951830BBA97DD94DB1729BF42D76&rand=a17cafc7-26fe-42d9-a61a-894b43a28046&utm_source=PurchaseSuccess&utm_medium=Email&utm_campaign=SystemMails")
txt = 'Download' # text to be searched
#Generate variants of that txt
l = [(c, c.lower()) if not c.isdigit() else (c,) for c in txt.upper()] #make tuple of upper and lower of each lettern that string (Download)
variants = ["".join(item) for item in product(*l)] # make all variant of the string Download
anchors = ["text()", "@class", "@id", "@href"] #node attribute to be searched
#Generate xpaths
xpaths_or = " or ".join(["contains(%s,'%s')"%(i,j) for i in anchors for j in variants])
xpaths = "//*[%s]" %xpaths_or
for download_tag in driver.find_elements_by_xpath(xpaths):
print(download_tag.text)
driver.quit()
输出 -
Download
Download
N.B。 isdigit
函数可以避免更改数字的大小写(如果存在)。
答案 3 :(得分:0)
但在此页面上不返回任何结果,即使其中包含以下链接:
它因为有不同的文字。看:
Download
download
一个字母是大写的。 所以你需要使用不区分大小写的xpath:
driver.find_elements_by_xpath("(//*[contains(lower-case(text()), 'download')]")
它必须为你工作好
答案 4 :(得分:-3)
当使用Selenium并查找Web元素时,最好始终首先搜索“ID”或“Class Name”,因为它比使用XPath更可靠和更容易,通常XPath仅在您无法使用前2个找到元素时使用提到的方法。
在这种情况下,您在该网站的下载元素中有一个非常清晰的ID标记。
请尝试使用此代码:
downloadButton = driver.find_element_by_id('downloadTop')
然后你可以用它来点击它:
downloadButton.click()
答案 5 :(得分:-3)
嗯,我不太了解硒,但我可以建议一个解决方案,这个方法有效。您可以使用正则表达式来首先解析整个页面源。例如,如果您只需要包含属性的元素,则包含&#39; download&#39; substring,使用这个regexp:
<\w*([a-zA-Z]+).*\w+([a-zA-Z]+)="(.*?download.*?)"?\/?>
然后使用re.finditer函数查找所有mathes,每个匹配对象将包含标记名称(group(1)),属性名称(group(2)和属性值(group(3))
import re
# wd == webdriver
for m in re.finditer('<\w*([a-zA-Z]+).*\w+([a-zA-Z]+)="(.*?download.*?)"?\/?>', wd.page_source):
tag, attr, val = m.group(1), m.group(2), m.group(3)
然后,您可以使用wd.find_elements_by_css_selector(或其他内容)查找selenium树结构中的所有标记:
wd.find_elements_by_css_selector('{0}[{1}={2}]'.format(tag, attr, val))