首页 > 解决方案 > 如何使用美丽的汤提取具有指定属性值的两个标签之间的xml文本

问题描述

再会,

我在学习python的同时也在学习xml:因此,请原谅我的无知。

我有一个带有文本的 xml 文档,我试图将其提取到一行中:最终我想要创建一个 csv 文件,其中包含从属性(作为列)中提取的信息以及文本和每个“块”将在数据框中创建新行。

这是 xml 文件的示例:

<div type="majorSection">
<p>
<tagname ID="xxx.1.1" sID="xxx.1.1.seID.00002" n="1" />
<w lemma="ref:H75">text I want</w>
<w lemma="ref:H40"> more text I want</w>
<w lemma="ref:H83">and</w>   
punctuation is on this line without any associated tag.
<tagname eID="xxx.1.1.seID.00002" />
<tagname ID="xxx.1.2" sID="xxx.1.2.seID.00003" n="2" />
<w lemma="ref:H75">second line of text I want</w>
and punctuation is on this line without any associated tag ":"    
<w lemma="ref:H8 ref:H14">and again wanted text</w>
with final punctuation line here.
<tagname eID="xxx.1.2.seID.00003" /> 

如果我对完整标签“p”(段落)感兴趣,我想我明白如何做到这一点,但我对标签“tagname”之间的文本特别感兴趣,其中 sID 开始块,eID 结束块相同的欲望串。

所以对于上面的例子,我希望最终结果看起来像

-- 对于第一行文本 -- “文本我想要更多我想要的文本,标点符号在这一行上,没有任何关联的标签。” (这是来自 sID = xxx.1.1.seID.00002)

-- 对于第二行文本 -- “我想要的第二行文本和标点符号在这一行上,没有任何关联的标签:再次想要带有最终标点符号行的文本。” (这是来自 sID = xxx.1.2.seID.00003)

最终,我希望在结束数据帧中有一个列来标识源,在这种情况下,第一行条目将具有“xxx”、“1”、“1”,第二行条目将具有“xxx”、“ 1”、“2”。

所以最后会有四列:book, chapterNum, textNum, textChar

这是我到目前为止所拥有的,但不确定如何在没有换行符的情况下将 textChar 存储到单行中,也不确定如何从我想要的 sID 属性值中获取其他信息并将其全部放入数据框中。

for i in soup.find_all('div'):
if i.get('type')=='majorSection':
    for j in i.find_all('p'):
        for tag in j.find_all('w'):
            textChar = tag.text + tag.next_sibling
            print(textChar)

我看过这个解决方案无济于事: How to get all text between just two specified tags using BeautifulSoup?

谢谢你对我的耐心。我在使用 python 进行文本挖掘方面有很多东西要学习,我很高兴能做到这一点,但在这最后两天之后,我陷入了死胡同。

标签: xmlpython-3.xtextbeautifulsoup

解决方案


经过大量的辛勤工作,这是我设法组合在一起的解决方案。我敢肯定有更有效的方法来做到这一点,但我不知道其中任何一种:可悲的是。

 verseID = tagvalue
            node = soup.find('tagname', {'sID': tagvalue})
            s = []
            while True:
                if node is None:
                    break
                node = node.next_sibling
                if hasattr(node, "eID") and node.get('eID') == tagvalue:
                    break
                else:
                    if node is not None and hasattr(node, 'text'):
                        if hasattr(node, 'type') and node.get('type') == 'value i do not want':
                            break
                        else:
                            s.append(node.text)
                    else:
                        if hasattr(node, 'type') and node.get('type') == 'value i do not want':
                            break
                        else:
                            s.append(node)
            textChar = ''.join(s)
            textChar = textChar.replace("\n", " ")

为了完整性,以防其他人看到这个:我设法从这个线程的答案中把它放在一起:BeautifulSoup - 如何获取两个不同标签之间的所有文本?

谢谢你。


推荐阅读