我有一个单选按钮,其值为HTML,如下所示:
<div class='result'>
<span>
<input type='radio'/>
option1
</span>
<span>
<input type='radio'/>
option2
</span>
<span>
<input type='radio'/>
option3
</span>
</div>
我尝试了以下XPath,但这不起作用:
//span[contains(text(),'option1')]/input[@type='radio']
请帮我写XPath。
答案 0 :(得分:1)
目标span
中实际上有两个文本节点:第一个是<input>
之前的空字符串,第二个是<input>
之后的空字符串(包含"option1"
的文本节点})
您的XPath
//span[contains(text(),'option1')]
表示返回包含&#34; option1&#34;在第一个文本节点。
您可以使用以下表达式之一来匹配所需的input
:
//span[normalize-space()="option1"]/input[@type="radio"]
//span[contains(text()[2],'option1')]/input[@type='radio']
答案 1 :(得分:0)
我猜你不能在这里使用text()
。因为此函数返回当前span
元素的子文本节点序列。您的示例中有两个文本节点:
<span>
<input type='radio'/>
option1
</span>
第一个文字节点位于仅包含换行符的<span>
和<input type='radio'/>
之间。
第二个文字节点位于<input type='radio'/>
和</span>
之间,包含option1
文字加上2个换行符(在开头和结尾处)。
contains
函数需要字符串参数而不是序列。我认为它只需要序列中的第一个文本节点,它只包含一个换行符。
如果您需要选择input
后跟某个text
节点,则可以使用以下表达式:
//input[@type='radio'][contains(following-sibling::text(), 'option1')]
如果您需要选择span
包含文字option1
和input
@type='radio'
,则可以尝试以下表达式:
//span[contains(., 'option1') and input/@type='radio']
如果您需要选择input
而不是span
,请使用以下表达式:
//span[contains(., 'option1')]/input[@type='radio']
我可以建议您使用以下资源来获取有关XPath的一些信息。 W3C recomendations包含XPath的完整描述。如果您使用XPath 2.0,那么您可以查看:
对于XPath 3.0,请查看:
这些建议很大,很难阅读。但您可以在这些文档中找到a list of all available axes,包括following-sibling::
,a description of text()
,a description of contains()
等。
还有很多简短的XPath教程。例如,您可以查看this one。
答案 2 :(得分:0)
每个span
有两个文本元素。一个在input
元素之前,一个跟随它,但第一个基本上是空的。
在此代码中,我找到input
元素,然后是父母,然后是span
父母的第二个文本元素。
>>> from scrapy.selector import Selector
>>> selector = Selector(text=open('temp.html').read())
>>> for item in selector.xpath('.//input[@type="radio"]/../text()[2]'):
... item.extract()
...
'\noption1\n'
'\noption2\n'
'\noption3\n'
答案 3 :(得分:0)
尝试此选择选项1
//input[@type='radio']/preceding::span[1][contains(.,'option1')]