从简单 html 中提取文本和(hlStart 和 hlEnd)标记

Extract text and (hlStart and hlEnd) tags from simple html

提问人:Konrad Juszczyk 提问时间:5/10/2020 最后编辑:Andrej KeselyKonrad Juszczyk 更新时间:5/10/2020 访问量:47

问:

我有以下部分的html / xml文件:

<p><hlstart ana="#ann224094"></<hlstart>Przed<hlend ana="#ann224094"></hlend> <hlstart ana="#ann224160"></hlstart>nami <hlend ana="#ann224160"></hlend>jeszcze trzy <hlstart ana="#ann224159"></hlstart>dni,<hlend ana="#ann224159"></hlend></p>

我想提取文本和标签以将它们排列在表格中,例如:

text, nonana
text, ana

其中 ana 表示标签,例如 #ann224094 来自

<hlstart ana="#ann224094"></<hlstart>Przed<hlend ana="#ann224094"></hlend> 

nonana 表示文本没有 ana 标签。

przed, #ann224094
nami, #ann224160
jeszcze trzy, nonana

我已经尝试了 bs4 和 htmlparser 与我的 xml 数据的其他部分,但我不明白那部分。我可以使用 .text 方法导出整个文本、所有字符串,但我需要知道哪些单词有 ana 标签。此外,所有带有 ana 标签的单词在我的文件中都有特定的标签。

python r xml html 解析 tei

评论


答:

2赞 Andrej Kesely 5/10/2020 #1
from bs4 import BeautifulSoup

txt = '''<p><hlstart ana="#ann224094"></hlstart>Przed<hlend ana="#ann224094"></hlend> <hlstart ana="#ann224160"></hlstart>nami <hlend ana="#ann224160"></hlend>jeszcze trzy <hlstart ana="#ann224159"></hlstart>dni,<hlend ana="#ann224159"></hlend></p>'''

soup = BeautifulSoup(txt, 'html.parser')

out = []
for t in soup.find_all(text=True):
    if t.strip() == '':
        continue

    prev = t.find_previous_sibling()
    if prev.name == 'hlstart':
        out.append( (t, prev['ana']) )
    else:
        out.append( (t, 'noana') )

# print it to screen:
from pprint import pprint
pprint(out)

指纹:

[('Przed', '#ann224094'),
 ('nami ', '#ann224160'),
 ('jeszcze trzy ', 'noana'),
 ('dni,', '#ann224159')]
2赞 Jack Fleeting 5/10/2020 #2

另一种方法,使用 lxml:

    ana = """your html above"""
    import lxml.html as lh

    doc = lh.fromstring(ana)
    targets = doc.xpath('//hlstart[@ana]')
    nont = doc.xpath('//*[name() != "hlstart"]')

    for target in targets:
        if target.tail is not None:
            print(target.attrib['ana'],target.tail.strip())

    for n in nont:
        if n.tail is not None and len(n.tail.strip())>0:
           print('noanna ',n.tail.strip())

输出:

#ann224094 Przed
#ann224160 nami
#ann224159 dni,
noanna  jeszcze trzy
1赞 dabingsou 5/10/2020 #3

另一种方法,使用 SimplifiedDoc :)

from simplified_scrapy import SimplifiedDoc,utils
html = '''
<p>
<hlstart ana="#ann224094"></hlstart>Przed<hlend ana="#ann224094"></hlend> 
<hlstart ana="#ann224160"></hlstart>nami <hlend ana="#ann224160"></hlend>
jeszcze trzy 
<hlstart ana="#ann224159"></hlstart>dni,<hlend ana="#ann224159"></hlend></p>'''

doc = SimplifiedDoc(html)
for h in doc.p.hlstarts:
    text = h.nextText()
    if text: print(h.ana,text)
for h in doc.p.hlends:
    text = h.nextText()
    if text: print('noana',text)

结果:

#ann224094 Przed
#ann224160 nami
#ann224159 dni,
noana jeszcze trzy