Python3 BeautifulSoup获取两个标记之间的值,其中值介于

2024-04-19 07:25:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下HTML块,它们是由pdftotext使用-bbox-layout选项生成的:

<flow>
<block xMin="21.600000" yMin="86.356000" xMax="178.647000" yMax="116.233001">
    <line xMin="21.600000" yMin="86.356000" xMax="178.647000" yMax="101.833000">
        <word xMin="21.600000" yMin="86.356000" xMax="178.647000" yMax="101.833000">
            My text string located here!</word>
    </line>

</block>
</flow>

[...]
<flow>
<block xMin="223.560000" yMin="323.675000" xMax="345.563500" yMax="339.855500">
    <line xMin="223.560000" yMin="323.675000" xMax="345.563500" yMax="339.855500">
        <word xMin="223.560000" yMin="323.675000" xMax="316.836500" yMax="339.855500">Another string
        </word>
        <word xMin="320.022000" yMin="323.675000" xMax="345.563500" yMax="339.855500">And another!</word>
    </line>
</block>
</flow>

现在,我尝试动态解析上述结构,并获取每个<block>[...]</block>内容,其中值xMinxMax介于两个数字之间。你知道吗

假设我有以下数字:

areas[0] = (100, 0, 200, 792)
areas[1] = (200, 0, 612, 792)

with open(path_to_html_document) as html_file:
    parsed_html = BeautifulSoup(html_file)
    for (i, area) in enumerate(areas):

        xMinValue, xMaxValue = areas[i][0], areas[i][2]

        block_tags = parsed_html.find_all(
            "block", attrs={"xMin": xMinValue, "xMax": xMaxValue})

        print(block_tags)

上面的代码没有返回任何内容,因为没有匹配的标记。find_all()搜索具有特定数字的block标记的精确匹配-但我尝试搜索block标记,其中xMin和xMax是:

areas[0] is between 100 and 200

areas[1] is between 200 and 612

这有没有可能和美素一起?你知道吗


Tags: 标记内容stringhtmlline数字flowblock
3条回答

替换代码:

block_tags = parsed_html.find_all(
            "block", attrs={"xMin": xMinValue, "xMax": xMaxValue})
print(block_tags)

收件人:

block_tags = parsed_html.find_all("block")

for block in block_tags:
    if float(block['xmin']) >= xMinValue and  float(block['xmax']) <= xMinValue:
        print(block)

如果调试html代码print(parsed_html),您将看到html blockall属性的小写字母。你知道吗

试试看

parsed_html.select("block")

并用键“xMin”和“xMax”过滤结果。你知道吗

例如,如果要获取<block xMin="1" xMax="2"></block>,可以首先通过以下方式获取所有block标记

all_blocks = parsed_html.select("block")

如果你想得到一个block,它的xMin是1,xMax是2,你可以这样做:

target = filter(lambda x: x["xMin"] == "1" and x["xMax"] == 2, all_blocks)

您可以用属性xMin选择<block>,用CSS选择器block[xMin][xMax]选择xMax。然后通过列表理解进行过滤:

data = '''<flow>
<block xMin="21.600000" yMin="86.356000" xMax="178.647000" yMax="116.233001">
    <line xMin="21.600000" yMin="86.356000" xMax="178.647000" yMax="101.833000">
        <word xMin="21.600000" yMin="86.356000" xMax="178.647000" yMax="101.833000">
            My text string located here!</word>
    </line>

</block>
</flow>

<flow>
<block xMin="223.560000" yMin="323.675000" xMax="345.563500" yMax="339.855500">
    <line xMin="223.560000" yMin="323.675000" xMax="345.563500" yMax="339.855500">
        <word xMin="223.560000" yMin="323.675000" xMax="316.836500" yMax="339.855500">Another string
        </word>
        <word xMin="320.022000" yMin="323.675000" xMax="345.563500" yMax="339.855500">And another!</word>
    </line>
</block>
</flow>'''

from bs4 import BeautifulSoup

soup = BeautifulSoup(data, 'lxml')

def blocks_min_max(soup, x_min, x_max):
    return [b for b in soup.select('block[xMin][xMax]') if float(b['xmin']) >= x_min and float(b['xmax']) <= x_max]

for b in blocks_min_max(soup, 10, 200):
    print(b.prettify())

印刷品:

<block xmax="178.647000" xmin="21.600000" ymax="116.233001" ymin="86.356000">
 <line xmax="178.647000" xmin="21.600000" ymax="101.833000" ymin="86.356000">
  <word xmax="178.647000" xmin="21.600000" ymax="101.833000" ymin="86.356000">
   My text string located here!
  </word>
 </line>
</block>

相关问题 更多 >