![](/img/trans.png)
[英]what is most pythonic way to find a element in a list that is different with other elements?
[英]Most Pythonic way to find the sibling of an element in XML
問題:我有以下 XML 片段:
...snip...
<p class="p_cat_heading">DEFINITION</p>
<p class="p_numberedbullet"><span class="calibre10">This</span>, <span class="calibre10">these</span>. </p>
<p class="p_cat_heading">PRONUNCIATION </p>
..snip...
我需要搜索 XML 的全部內容,找到具有文本DEFINITION
的標題,並打印相關的定義。 定義的格式不一致並且可以更改屬性/元素,因此捕獲所有內容的唯一可靠方法是讀取具有屬性p_cat_heading
的下一個元素。
現在我正在使用以下代碼來查找所有標題:
for heading in root.findall(".//*[@class='p_cat_heading']"):
if heading.text == "DEFINITION":
<WE FOUND THE CORRECT HEADER - TAKE ACTION HERE>
我嘗試過的事情:
我的解決方案:
我還沒有完成,但是因為我的 XML 很短,所以我只想獲取所有元素的列表,迭代直到具有 DEFINITION 屬性的元素,然后迭代直到具有 p_cat_heading 屬性的下一個元素。 這個解決方案既可怕又丑陋,但我似乎找不到干凈的替代方案。
我在找什么:
在我們的例子中,一種更 Pythonic 的打印定義的方式是“這個,這些”。 解決方案可以使用 xpath 或其他替代方法。 首選 Python 原生解決方案,但任何事情都可以。
您可以將 BeatifulSoup 與 CSS 選擇器一起用於此任務。 選擇器.p_cat_heading:contains("DEFINITION") ~ .p_cat_heading
將選擇所有帶有類p_cat_heading
元素,這些元素前面是帶有包含字符串“DEFINITION”的類p_cat_heading
的元素:
data = '''
<p class="p_cat_heading">THIS YOU DONT WANT</p>
<p class="p_numberedbullet"><span class="calibre10">This</span>, <span class="calibre10">these</span>. </p>
<p class="p_cat_heading">DEFINITION</p>
<p class="p_numberedbullet"><span class="calibre10">This</span>, <span class="calibre10">these</span>. </p>
<p class="p_cat_heading">PRONUNCIATION </p>'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(data, 'lxml')
for heading in soup.select('.p_cat_heading:contains("DEFINITION") ~ .p_cat_heading'):
print(heading.text)
印刷:
PRONUNCIATION
進一步閱讀
編輯:
在定義之后選擇直接兄弟:
data = '''
<p class="p_cat_heading">THIS YOU DONT WANT</p>
<p class="p_numberedbullet"><span class="calibre10">This</span>, <span class="calibre10">these</span>. </p>
<p class="p_cat_heading">DEFINITION</p>
<p class="p_numberedbullet"><span class="calibre10">This is after DEFINITION</span>, <span class="calibre10">these</span>. </p>
<p class="p_cat_heading">PRONUNCIATION </p>
<p class="p_numberedbullet"><span class="calibre10">This is after PRONUNCIATION</span>, <span class="calibre10">these</span>. </p>'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(data, 'lxml')
s = soup.select_one('.p_cat_heading:contains("DEFINITION") + :not(.p_cat_heading)')
print(s.text)
印刷:
This is after DEFINITION, these.
有幾種方法可以做到這一點,但是通過依賴 xpath 來完成大部分工作,這個表達式
//*[@class='p_cat_heading'][contains(text(),'DEFINITION')]/following-sibling::*[1]
應該管用。
使用 lxml:
from lxml import html
data = [your snippet above]
exp = "//*[@class='p_cat_heading'][contains(text(),'DEFINITION')]/following-sibling::*[1]"
tree = html.fromstring(data)
target = tree.xpath(exp)
for i in target:
print(i.text_content())
輸出:
這,這些。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.