在元素和属性中搜索字符串
Search both elements and attributes for string
我正在尝试查询一些 HTML 以查找以某种方式包含单词 "download" 的链接。所以可以在
id
class
href
- 正文
a
标签内的任何 html。
所以使用 Python lxml library 它应该找到测试中的所有 7 个链接-html:
html = """
<html>
<head></head>
<body>
1 <a href="/test1" id="download">test 1</a>
2 <a href="/test2" class="download">test 2</a>
3 <a href="/download">test 3</a>
4 <a href="/test4">DoWnLoAd</a>
5 <a href="/test5">ascascDoWnLoAdsacsa</a>
6 <a href="/test6"><div id="test6">download</div></a>
7 <a href="/test7"><div id="download">test7</div></a>
</body>
</html>
"""
from lxml import etree
tree = etree.fromstring(html, etree.HTMLParser())
downloadElementConditions = "//a[(@id|@class|@href|text())[contains(translate(.,'DOWNLOAD','download'), 'download')]]"
elements = tree.xpath(downloadElementConditions)
print 'FOUND ELEMENTS:', len(elements)
for i in elements:
print i.get('href'), i.text
但是,如果这是 运行,它只会找到前五个元素。这意味着如果文本不包含进一步的 html,则 xpath 只能在文本中找到 "download"。
有没有办法将 a
标记的内容视为常规字符串,并查看其中是否包含 "download"?欢迎所有提示!
[编辑]
使用下面 heinst 的回答中的提示,我编辑了下面的代码。这现在有效,但不是很优雅。有人知道纯 xpath 的解决方案吗?
from lxml import etree
tree = etree.fromstring(html, etree.HTMLParser())
downloadElementConditions = "//*[(@id|@class|@href|text())[contains(translate(.,'DOWNLOAD','download'), 'download')]]"
elements = tree.xpath(downloadElementConditions)
print 'FOUND ELEMENTS:', len(elements)
for el in elements:
href = el.get('href')
if href:
print el.get('href'), el.text
else:
elparent = el
for _ in range(10): # loop over 10 parents
elparent = elparent.getparent()
href = elparent.get('href')
if href:
print elparent.get('href'), elparent.text
break
将 Xpath
select 从严格匹配 a
标签更改为通配符应该可以解决问题:
"//*[(@id|@class|@href|text())[contains(translate(.,'DOWNLOAD','download'), 'download')]]"
纯 XPath 解决方案
将 text()
更改为 .
并在 descendent-or-self
轴上搜索属性:
//a[(.|.//@id|.//@class|.//@href)[contains(translate(.,'DOWNLOAD','download'),'download')]]
解释:
text()
vs .
:这里 text()
将匹配 a
的直接文本节点子节点; .
将匹配 a
元素的字符串值。在
为了捕获 a
的子元素的情况
包含目标文本,你想匹配的字符串值
a
.
- descendant-or-self:为了匹配
a
及其任何后代的属性,descendant-or-self
轴(.//
) 被使用。
有关 XPath 中字符串值的更多详细信息,请参阅
我正在尝试查询一些 HTML 以查找以某种方式包含单词 "download" 的链接。所以可以在
id
class
href
- 正文
a
标签内的任何 html。
所以使用 Python lxml library 它应该找到测试中的所有 7 个链接-html:
html = """
<html>
<head></head>
<body>
1 <a href="/test1" id="download">test 1</a>
2 <a href="/test2" class="download">test 2</a>
3 <a href="/download">test 3</a>
4 <a href="/test4">DoWnLoAd</a>
5 <a href="/test5">ascascDoWnLoAdsacsa</a>
6 <a href="/test6"><div id="test6">download</div></a>
7 <a href="/test7"><div id="download">test7</div></a>
</body>
</html>
"""
from lxml import etree
tree = etree.fromstring(html, etree.HTMLParser())
downloadElementConditions = "//a[(@id|@class|@href|text())[contains(translate(.,'DOWNLOAD','download'), 'download')]]"
elements = tree.xpath(downloadElementConditions)
print 'FOUND ELEMENTS:', len(elements)
for i in elements:
print i.get('href'), i.text
但是,如果这是 运行,它只会找到前五个元素。这意味着如果文本不包含进一步的 html,则 xpath 只能在文本中找到 "download"。
有没有办法将 a
标记的内容视为常规字符串,并查看其中是否包含 "download"?欢迎所有提示!
[编辑]
使用下面 heinst 的回答中的提示,我编辑了下面的代码。这现在有效,但不是很优雅。有人知道纯 xpath 的解决方案吗?
from lxml import etree
tree = etree.fromstring(html, etree.HTMLParser())
downloadElementConditions = "//*[(@id|@class|@href|text())[contains(translate(.,'DOWNLOAD','download'), 'download')]]"
elements = tree.xpath(downloadElementConditions)
print 'FOUND ELEMENTS:', len(elements)
for el in elements:
href = el.get('href')
if href:
print el.get('href'), el.text
else:
elparent = el
for _ in range(10): # loop over 10 parents
elparent = elparent.getparent()
href = elparent.get('href')
if href:
print elparent.get('href'), elparent.text
break
将 Xpath
select 从严格匹配 a
标签更改为通配符应该可以解决问题:
"//*[(@id|@class|@href|text())[contains(translate(.,'DOWNLOAD','download'), 'download')]]"
纯 XPath 解决方案
将 text()
更改为 .
并在 descendent-or-self
轴上搜索属性:
//a[(.|.//@id|.//@class|.//@href)[contains(translate(.,'DOWNLOAD','download'),'download')]]
解释:
text()
vs.
:这里text()
将匹配a
的直接文本节点子节点;.
将匹配a
元素的字符串值。在 为了捕获a
的子元素的情况 包含目标文本,你想匹配的字符串值a
.- descendant-or-self:为了匹配
a
及其任何后代的属性,descendant-or-self
轴(.//
) 被使用。
有关 XPath 中字符串值的更多详细信息,请参阅