Ricerca…


Trova un testo dopo un elemento in BeautifulSoup

Immagina di avere il seguente codice HTML:

<div>
    <label>Name:</label>
    John Smith
</div>

E devi localizzare il testo "John Smith" dopo l'elemento label .

In questo caso, è possibile individuare l'elemento label base al testo e quindi utilizzare la proprietà .next_sibling :

from bs4 import BeautifulSoup

data = """
<div>
    <label>Name:</label>
    John Smith
</div>
"""

soup = BeautifulSoup(data, "html.parser")

label = soup.find("label", text="Name:")
print(label.next_sibling.strip())

Stampa John Smith .

Utilizzare i selettori CSS per individuare gli elementi in BeautifulSoup

BeautifulSoup ha un supporto limitato per i selettori CSS , ma copre quelli più comunemente usati. Usa il metodo select() per trovare più elementi e select_one() per trovare un singolo elemento.

Esempio di base:

from bs4 import BeautifulSoup

data = """
<ul>
    <li class="item">item1</li>
    <li class="item">item2</li>
    <li class="item">item3</li>
</ul>
"""

soup = BeautifulSoup(data, "html.parser")

for item in soup.select("li.item"):
    print(item.get_text())

stampe:

item1
item2
item3

Individuazione dei commenti

Per individuare i commenti in BeautifulSoup , utilizzare l'argomento text (o string nelle versioni recenti) verificando il tipo da Comment :

from bs4 import BeautifulSoup
from bs4 import Comment

data = """
<html>
    <body>
        <div>
        <!-- desired text -->
        </div>
    </body>
</html>
"""

soup = BeautifulSoup(data, "html.parser")
comment = soup.find(text=lambda text: isinstance(text, Comment))
print(comment)

Stampa il desired text .

Funzioni filtro

BeautifulSoup consente di filtrare i risultati fornendo una funzione per find_all e funzioni simili. Questo può essere utile per i filtri complessi e uno strumento per il riutilizzo del codice.

Utilizzo di base

Definisci una funzione che accetta un elemento come unico argomento. La funzione dovrebbe restituire True se l'argomento corrisponde.

def has_href(tag):
    '''Returns True for tags with a href attribute'''
    return  bool(tag.get("href"))

soup.find_all(has_href) #find all elements with a href attribute
#equivilent using lambda:
soup.find_all(lambda tag: bool(tag.get("href")))

Un altro esempio che trova tag con un valore href che non iniziano con

Fornire ulteriori argomenti per filtrare le funzioni

Poiché la funzione passata a find_all può prendere solo un argomento, a volte è utile creare "fabbriche di funzioni" che producano funzioni utilizzabili in find_all . Questo è utile per rendere le tue funzioni di ricerca dei tag più flessibili.

def present_in_href(check_string):
    return lambda tag: tag.get("href") and check_string in tag.get("href")

soup.find_all(present_in_href("/partial/path"))

Accesso ai tag interni e ai loro attributi del tag inizialmente selezionato

Supponiamo che tu abbia un html dopo aver selezionato con soup.find('div', class_='base class') :

from bs4 import BeautifulSoup

soup = BeautifulSoup(SomePage, 'lxml')
html = soup.find('div', class_='base class')
print(html)

<div class="base class">
  <div>Sample text 1</div>
  <div>Sample text 2</div>
  <div>
    <a class="ordinary link" href="https://example.com">URL text</a>
  </div>
</div>

<div class="Confusing class"></div>
'''

E se vuoi accedere a <a> tag href , puoi farlo in questo modo:

a_tag = html.a
link = a_tag['href']
print(link)

https://example.com

Ciò è utile quando non puoi selezionare direttamente il tag <a> perché gli attrs non ti danno un'identificazione univoca, ci sono altri tag <a> "gemelli" nella pagina analizzata. Ma puoi selezionare in modo univoco un tag principale che contiene <a> necessari.

Raccolta di elementi opzionali e / o dei loro attributi da serie di pagine

Consideriamo la situazione quando analizzi il numero di pagine e desideri raccogliere il valore dall'elemento facoltativo (che può essere presentato in una pagina e può essere assente in un'altra) per una pagina paticolare.

Inoltre, l'elemento stesso, ad esempio, è l' elemento più comune della pagina, in altre parole nessun attributo specifico può individuarlo in modo univoco. Ma vedi che puoi selezionare correttamente il suo elemento genitore e conosci il numero dell'ordine dell'elemento desiderato nel rispettivo livello di nidificazione.

from bs4 import BeautifulSoup

soup = BeautifulSoup(SomePage, 'lxml')
html = soup.find('div', class_='base class') # Below it refers to html_1 and html_2

L'elemento ricercato è facoltativo, quindi potrebbero esserci 2 situazioni per l' html :

html_1 = '''
<div class="base class">    # №0
  <div>Sample text 1</div>  # №1
  <div>Sample text 2</div>  # №2  
  <div>!Needed text!</div>  # №3
</div>

<div>Confusing div text</div>  # №4
'''
        
html_2 = '''
<div class="base class">    # №0
  <div>Sample text 1</div>  # №1
  <div>Sample text 2</div>  # №2  
</div>

<div>Confusing div text</div>  # №4
'''

Se hai html_1 puoi raccogliere !Needed text! dal tag №3 in questo modo:

wanted tag = html_1.div.find_next_sibling().find_next_sibling() # this gives you whole tag №3

Inizialmente ottiene №1 div , quindi 2 volte passa al div successivo allo stesso livello di nidificazione per arrivare a №3.

wanted_text = wanted_tag.text # extracting !Needed text!

L'utilità di questo approccio arriva quando ottieni html_2 - l'approccio non ti darà errore, darà None :

print(html_2.div.find_next_sibling().find_next_sibling())
None

L'uso di find_next_sibling() qui è cruciale perché limita la ricerca degli elementi in base al rispettivo livello di nidificazione. Se utilizzi find_next() tag №4 verrà raccolto e non lo vuoi:

print(html_2.div.find_next().find_next())
<div>Confusing div text</div>

Puoi anche esplorare find_previous_sibling() e find_previous() che funzionano in modo opposto.

Tutte le funzioni descritte hanno le loro diverse varianti per catturare tutti i tag, non solo il primo:

find_next_siblings()
find_previous_siblings()
find_all_next()
find_all_previous()


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow