Xpath:html 中两个元素之间的所有内容
Xpath: Everything between two elements in html
我正在尝试执行 xpath 以获取两个节点之间每个节点的文本,但这有点棘手。结构看起来有点像这样:
<table class="infobox biography vcard">
<p>
<b>Mark Hamill</b>
<span> was born in ...</span>
<i> in the early 1980s he...</i>
<a href="/some/place">Luke Skywalker</a>
</p>
<div class="toc">
我需要该段落中恰好在 table 和 div 之间的所有文本,这是我目前的查询 xpath:
//table[@class="infobox biography vcard"]/following-sibling::node()[following-sibling::div[@class="toc"]]/text()
它不会从某些标签中获取所有文本,我该如何实现?
注意:p 标签没有任何道具,但该文档中还有一些其他 p 标签
已编辑:
wiki-page 在 table 和 div 之间有 2 个 p 元素,像这样:
<table class="infobox biography vcard">
<!-- Content of table -->
</table>
<p>Here all kinds of mixed content</p>
<p>Here other kinds of mixed content</p>
<div class="toc">
<!-- Content of toc -->
</div>
要获取 table 和 div 之间 p 中的所有文本,请使用此 XPath:
normalize-space(//p[preceding-sibling::table[@class='infobox biography vcard'] and following-sibling::div[@class='toc']])
规范化 space 只是为了满足您的“预期输出将是 P 标签之间的所有文本”,但根据您的需要也可以使用
//p[preceding-sibling::table[@class='infobox biography vcard'] and following-sibling::*div[@class='toc']]//text()
如果您想完全控制使用那些 p 的内容,您可以从像这样获取 p 开始:
//p[preceding-sibling::table[@class='infobox biography vcard'] and following-sibling::*div[@class='toc']]
循环遍历那些 p 的混合内容,也可能使用 XPath,以获得您需要的内容。
如果你想要传记,你可以使用相邻的同级组合器使用 bs4 获得 table 旁边的 2 个段落。它比 xpath 更快。
import requests
from bs4 import BeautifulSoup as bs
r = requests.get('https://en.wikipedia.org/wiki/Mark_Hamill')
soup = bs(r.content, 'lxml')
print(' '.join([i.text.strip() for i in soup.select('.biography + p, .biography + p + p')]))
我正在尝试执行 xpath 以获取两个节点之间每个节点的文本,但这有点棘手。结构看起来有点像这样:
<table class="infobox biography vcard">
<p>
<b>Mark Hamill</b>
<span> was born in ...</span>
<i> in the early 1980s he...</i>
<a href="/some/place">Luke Skywalker</a>
</p>
<div class="toc">
我需要该段落中恰好在 table 和 div 之间的所有文本,这是我目前的查询 xpath:
//table[@class="infobox biography vcard"]/following-sibling::node()[following-sibling::div[@class="toc"]]/text()
它不会从某些标签中获取所有文本,我该如何实现?
注意:p 标签没有任何道具,但该文档中还有一些其他 p 标签
已编辑:
wiki-page 在 table 和 div 之间有 2 个 p 元素,像这样:
<table class="infobox biography vcard">
<!-- Content of table -->
</table>
<p>Here all kinds of mixed content</p>
<p>Here other kinds of mixed content</p>
<div class="toc">
<!-- Content of toc -->
</div>
要获取 table 和 div 之间 p 中的所有文本,请使用此 XPath:
normalize-space(//p[preceding-sibling::table[@class='infobox biography vcard'] and following-sibling::div[@class='toc']])
规范化 space 只是为了满足您的“预期输出将是 P 标签之间的所有文本”,但根据您的需要也可以使用
//p[preceding-sibling::table[@class='infobox biography vcard'] and following-sibling::*div[@class='toc']]//text()
如果您想完全控制使用那些 p 的内容,您可以从像这样获取 p 开始:
//p[preceding-sibling::table[@class='infobox biography vcard'] and following-sibling::*div[@class='toc']]
循环遍历那些 p 的混合内容,也可能使用 XPath,以获得您需要的内容。
如果你想要传记,你可以使用相邻的同级组合器使用 bs4 获得 table 旁边的 2 个段落。它比 xpath 更快。
import requests
from bs4 import BeautifulSoup as bs
r = requests.get('https://en.wikipedia.org/wiki/Mark_Hamill')
soup = bs(r.content, 'lxml')
print(' '.join([i.text.strip() for i in soup.select('.biography + p, .biography + p + p')]))