在Python Selenium中通过正则表达式点击链接
我一直在寻找一种方法,想要在Selenium中点击一个符合正则表达式的链接。
这里是可以工作的代码:
from selenium import selenium
sel = selenium("localhost", 4444, "*chrome", "http://www.ncbi.nlm.nih.gov/")
sel.start()
sel.open('/pubmed')
sel.type("search_term", "20032207[uid]")
sel.click("search")
sel.click("linkout-icon-unknown-vir_full")
不过,如果我在不同的ID中搜索,链接的文本会不同,但它总是符合这个正则表达式 linkout-icon[\w-_]*
。
但是我找不到正确的命令来点击一个符合正则表达式的链接……我试过:
sel.click('link=regex:linkout-icon[\w-_]*')
sel.click('regex:linkout-icon[\w-_]*')
sel.click('link=regexp:linkout-icon[\w-_]*')
sel.click('regexp:linkout-icon[\w-_]*')
但这些都完全不管用。有什么建议吗?
补充:
根据下面回答中的评论:被点击的项目实际上是一个ID为linkout-icon-unknown-viro_full的图片。完整的代码如下:
<a href="http://vir.sgmjournals.org/cgi/pmidlookup?view=long&pmid=20032207" ref="PrId=3051&itool=Abstract-def&uid=20032207&nlmid=0077340&db=pubmed&log$=linkouticon" target="_blank"><img alt="Click here to read" id="linkout-icon-unknown-vir_full" border="0" src="http://www.ncbi.nlm.nih.gov/corehtml/query/egifs/http:--highwire.stanford.edu-icons-externalservices-pubmed-standard-vir_full.gif" /></a> </div>
如果你想知道,我是从Selenium IDE录制器那里得到这段代码的。
3 个回答
我觉得你已经很接近答案了。首先,regexp:
是用来表示你想使用正则表达式的正确方式。
另外,可能不太对的是说 link=
,因为这指的是链接的 文本,也就是:
<a href="path/to/mylink">Text of the link, this is what will be searched</a>
那么你想在锚点的哪个部分使用正则表达式呢,是 href 吗?
一个可能指向正确答案的线索是这个链接:selenium: 在 selenium 定位器中使用正则表达式是否可能
也许那个 get 函数可以重新利用,去搜索所有的 a.href
属性,找到符合你正则表达式的,然后返回它们的 XPath,接着可以用来调用 click()
。
经过一番折腾,我想出了一个可能非常笨的方法来解决这个问题,但它能用,直到有人给我提供更好的答案:
import re
val = re.findall('linkout-icon-unknown[\w-]*', sel.get_html_source())[0]
sel.click(val)
这个方法需要我搜索整个HTML代码,如果设计有变动,可能会出现问题。
我很想看到一个更可靠的方法。
sel.click
可以接受一个 XPath 作为参数。我使用 Firebug 找到了我认为是 "linkout-icon-unknown-vir_full" 链接的 XPath:
sel.click("//*[@id='linkout-icon-unknown-vir_full']")
使用上面的命令可以让我访问 这个页面。
我没有成功让 matches
工作——我也不太确定为什么——但使用 contains 似乎可以正常工作:
sel = selenium.selenium("localhost", 4444, "*firefox", "http://www.ncbi.nlm.nih.gov/")
sel.start()
sel.open('/pubmed')
sel.type("search_term", "20032207[uid]")
sel.click("search")
sel.wait_for_page_to_load(30000)
sel.click("//*[contains(@id,'linkout')]")