Bella zuppa ed estrarre un div e il suo contenuto per ID


147
soup.find("tagName", { "id" : "articlebody" })

Perché questo NON restituisce i <div id="articlebody"> ... </div>tag e le cose in mezzo? Non restituisce nulla. E so per certo che esiste perché lo sto fissando da

soup.prettify()

soup.find("div", { "id" : "articlebody" }) inoltre non funziona.

( EDIT: ho scoperto che BeautifulSoup non stava analizzando correttamente la mia pagina, il che probabilmente significa che la pagina che stavo cercando di analizzare non è formattata correttamente in SGML o altro)


(Per la tua EDIT, questa domanda ha ancora valore come risorsa riutilizzabile per gli altri, anche se il parser non funziona sulla tua pagina specifica)
smci

Risposte:


202

Dovresti pubblicare il tuo documento di esempio, perché il codice funziona bene:

>>> import BeautifulSoup
>>> soup = BeautifulSoup.BeautifulSoup('<html><body><div id="articlebody"> ... </div></body></html')
>>> soup.find("div", {"id": "articlebody"})
<div id="articlebody"> ... </div>

Alla ricerca di <div>s all'interno <div>s funziona pure:

>>> soup = BeautifulSoup.BeautifulSoup('<html><body><div><div id="articlebody"> ... </div></div></body></html')
>>> soup.find("div", {"id": "articlebody"})
<div id="articlebody"> ... </div>

2
il mio documento di esempio è enorme. sto rintracciando il problema - penso che questo non funzioni su div di div. Ho contato il numero di div nel documento con print len ​​(soup ('div')) che ha prodotto 10, e posso vedere chiaramente più di 10 div con firebug. quindi penso che non riesca a trovare div all'interno di div, quindi ho bisogno di restringere le cose wrapper by wrapper.
Tony Stark,

8
Bene, allora è impossibile rispondere alla tua domanda, le sfere di cristallo non sono un modo affidabile di debug. :)
Lukáš Lalinský

1
Ho provato questo codice. il div ha <embed> e non riesco a stampare l'incorporamento al suo interno.
Vincent,

13
o più semplicementediv = soup.find(id="articlebody")
jfs

4
oppuresoup.find('div', id='articlebody')
Trevor Boyd Smith l'

71

Per trovare un elemento dal suo id:

div = soup.find(id="articlebody")

15

Beautiful Soup 4 supporta la maggior parte dei selettori CSS con il .select()metodo , quindi è possibile utilizzare un idselettore come:

soup.select('#articlebody')

Se è necessario specificare il tipo di elemento, è possibile aggiungere un selettore del tipo prima del idselettore:

soup.select('div#articlebody')

Il .select()metodo restituirà una raccolta di elementi, il che significa che restituirà gli stessi risultati del seguente esempio di .find_all()metodo :

soup.find_all('div', id="articlebody")
# or
soup.find_all(id="articlebody")

Se vuoi solo selezionare un singolo elemento, puoi semplicemente usare il .find()metodo :

soup.find('div', id="articlebody")
# or
soup.find(id="articlebody")

13

Penso che ci sia un problema quando i tag 'div' sono troppo nidificati. Sto cercando di analizzare alcuni contatti da un file html di Facebook e Beautifulsoup non è in grado di trovare i tag "div" con la classe "fcontent".

Questo succede anche con altre classi. Quando cerco div in generale, trasforma solo quelli che non sono così nidificati.

Il codice sorgente html può essere qualsiasi pagina di Facebook dell'elenco di amici di un tuo amico (non quello dei tuoi amici). Se qualcuno può provarlo e dare qualche consiglio, lo apprezzerei davvero.

Questo è il mio codice, dove provo solo a stampare il numero di tag "div" con la classe "fcontent":

from BeautifulSoup import BeautifulSoup 
f = open('/Users/myUserName/Desktop/contacts.html')
soup = BeautifulSoup(f) 
list = soup.findAll('div', attrs={'class':'fcontent'})
print len(list)

9

Molto probabilmente a causa del bellissimo parser predefinitososo ha un problema. Cambia un altro parser, come "lxml" e riprova.


Questo ha funzionato per me, grazie! Ho usatosoup = BeautifulSoup(data, parser="html.parser")
will-hart il

8

Nella fonte beautifulsoup questa linea consente di annidare i div all'interno dei div; quindi la tua preoccupazione nel commento di lukas non sarebbe valida.

NESTABLE_BLOCK_TAGS = ['blockquote', 'div', 'fieldset', 'ins', 'del']

Quello che penso che devi fare è specificare gli attr che desideri come

source.find('div', attrs={'id':'articlebody'})

5

hai provato soup.findAll("div", {"id": "articlebody"})?

sembra folle, ma se stai raschiando roba selvaggia, non puoi escludere più div ...


4

Ero solito:

soup.findAll('tag', attrs={'attrname':"attrvalue"})

Come mia sintassi per find / findall; detto questo, a meno che non ci siano altri parametri opzionali tra il tag e l'elenco degli attributi, questo non dovrebbe essere diverso.


4

Mi è successo anche mentre cercavo di grattare Google.
Ho finito per usare il pyquery.
Installare:

pip install pyquery

Uso:

from pyquery import PyQuery    
pq = PyQuery('<html><body><div id="articlebody"> ... </div></body></html')
tag = pq('div#articlebody')

3

Ecco un frammento di codice

soup = BeautifulSoup(:"index.html")
titleList = soup.findAll('title')
divList = soup.findAll('div', attrs={ "class" : "article story"})

Come puoi vedere, trovo tutti i tag e quindi trovo tutti i tag con class = "article" all'interno


0

La Idproprietà è sempre identificata in modo univoco. Ciò significa che puoi usarlo direttamente senza nemmeno specificare l'elemento. Pertanto, è un punto in più se i tuoi elementi devono analizzare il contenuto.

divEle = soup.find(id = "articlebody")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.