2
votes

Python3 - BeautifulSoup - Récupère la valeur entre deux balises, où les valeurs entre

J'ai ci-dessous des blocs HTML, qui sont générés par pdftotext en utilisant l'option -bbox-layout :

areas[0] is between 100 and 200

areas[1] is between 200 and 612

Maintenant, je J'essaie d'analyser dynamiquement la structure ci-dessus et d'obtenir chaque contenu de [... , où les valeurs xMin et xMax est entre deux nombres.

Imaginez que j'ai des nombres ci-dessous:

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)

Le code ci-dessus ne renvoie rien, car il n'y a pas de balises correspondantes . find_all () recherche des correspondances exactes pour les balises block avec les numéros spécifiques - mais j'essaie de rechercher les balises block , où xMin et xMax est:

<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>

Est-ce possible avec BeautifulSoup?


0 commentaires

3 Réponses :


0
votes

Essayez

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

et filtrez le résultat avec les clés "xMin" et "xMax".

Par exemple, si vous voulez obtenir , vous pouvez d'abord obtenir toutes les balises block par

all_blocks = parsed_html.select("block")

Et vous voulez obtenir l'un des bloc dont xMin est 1 et xMax est 2, vous pouvez le faire comme:

parsed_html.select("block")


1 commentaires

Pourriez-vous fournir un peu plus d'informations? Comment cela peut-il résoudre mon problème actuel, où j'ai besoin d'obtenir des balises où xMin et xMax se trouvent entre un ensemble de nombres?



0
votes

Vous pouvez sélectionner avec les attributs xMin et xMax avec le sélecteur CSS block [xMin] [xMax] code>. Ensuite, vous filtrez à travers la compréhension de liste:

<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>

Impressions:

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())


2 commentaires

Merci Andrej! Cependant, cela me donne l'erreur suivante: Sélecteur CSS non pris en charge ou non valide: "block [xMin] [xMax]


@oliverbj Quelle version de BeautifulSoup utilisez-vous? Je suis sur beautifulsoup4 == 4.7.1



1
votes

Remplacez votre code:

block_tags = parsed_html.find_all("block")

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

TO:

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

Si le code html de débogage print (parsed_html) , vous verrez bloc html tous les attributs en minuscule.


1 commentaires

Dans l'instruction if float (... , est-il censé être 2x valeurs xmin que nous vérifions? Pas xMax ?