ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python,LXML-访问文本

2019-12-01 02:09:29  阅读:310  来源: 互联网

标签:text lxml html-parsing python


我目前有点想法,我真的希望您能给我一个提示:
最好用一小段示例代码来解释我的问题:

from lxml import etree
from io import StringIO

testStr = "<b>text0<i>text1</i><ul><li>item1</li><li>item2</li></ul>text2<b/><b>sib</b>"
parser = etree.HTMLParser()
# generate html tree
htmlTree   = etree.parse(StringIO(testStr), parser)
print(etree.tostring(htmlTree, pretty_print=True).decode("utf-8"))
bElem = htmlTree.getroot().find("body/b") 
print(".text only contains the first part: "+bElem.text+ " (which makes sense in some way)")
for text in bElem.itertext():
    print(text)

输出:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
  <body>
    <b>text0<i>text1</i><ul><li>item1</li><li>item2</li></ul>text2<b/><b>sib</b></b>
  </body>
</html>

.text only contains the first part: text0 (which makes sense in some way)
text0
text1
item1
item2
text2
sib

我的问题:

我想直接访问“ text2”,或获取所有文本部分的列表,仅包括可以在父标记中找到的部分.
到目前为止,我只找到了itertext(),它确实显示“ text2”.

还有什么其他方法可以检索“ text2”?

现在您可能会问为什么我需要这个:
基本上itertext()已经在做我想要的了:

>创建一个列表,其中包含在元素的子级中找到的所有文本
>但是,我想处理遇到的表和列表
一个不同的函数(随后创建一个列表结构
像这样:[“ text0 text1”,[“ item1”,“ item2”],“ text2”]或用于表格(1. 1列的行,2.
具有2列的行):[“ 1. row,1 col”,[“ 2.row,1. col”,“ 2.row,2.
col“]])

也许我采用了完全错误的方法?

解决方法:

您可以重新实现itertext()函数,并在必要时为ul,table插入特殊处理程序:

from lxml import html

def itertext(root, handlers=dict(ul=lambda el: (list(el.itertext()),
                                                el.tail))):
    if root.text:
        yield root.text
    for el in root:
        yield from handlers.get(el.tag, itertext)(el)
    if root.tail:
        yield root.tail

print(list(itertext(html.fromstring(
                "<b>text0<i>text1</i><ul><li>item1</li>"
                "<li>item2</li></ul>text2<b/><b>sib</b>"))))

输出量

['text0', 'text1', ['item1', 'item2'], 'text2', 'sib']

注意:X中的yield可以用X中的x代替:比Python 3.3版本旧的yield x.

连接相邻的字符串:

def joinadj(iterable, join=' '.join):
    adj = []
    for item in iterable:
        if isinstance(item, str):
            adj.append(item) # save for later
        else:
            if adj: # yield items accumulated so far
                yield join(adj)
                del adj[:] # remove yielded items
            yield item # not a string, yield as is

    if adj: # yield the rest
        yield join(adj)

print(list(joinadj(itertext(html.fromstring(
                "<b>text0<i>text1</i><ul><li>item1</li>"
                "<li>item2</li></ul>text2<b/><b>sib</b>")))))

输出量

['text0 text1', ['item1', 'item2'], 'text2 sib']

为了允许表格,在< ul>中嵌套列表.处理程序应递归调用itertext():

def ul_handler(el):
    yield list(itertext(el, with_tail=False))
    if el.tail:
        yield el.tail

def itertext(root, handlers=dict(ul=ul_handler), with_tail=True):
    if root.text:
        yield root.text
    for el in root:
        yield from handlers.get(el.tag, itertext)(el)
    if with_tail and root.tail:
        yield root.tail

print(list(joinadj(itertext(html.fromstring(
                    "<b>text0<i>text1</i><ul><li>item1</li>"
                    "<li>item2<ul><li>sub1<li>sub2</li></ul></ul>"
                    "text2<b/><b>sib</b>")))))

输出量

['text0 text1', ['item1', 'item2', ['sub1', 'sub2']], 'text2 sib']

标签:text,lxml,html-parsing,python
来源: https://codeday.me/bug/20191201/2077499.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有