2012-12-10 5 views
5

Sto utilizzando Beautiful Soup per estrarre tag div specifici e sembra che non sia possibile utilizzare la corrispondenza di stringa semplice .Espressione regolare in Python per Beautiful Soup

La pagina ha alcuni tag sotto forma di

<div class="comment form new"...> 

cui voglio ignorare, e anche alcuni tag sotto forma di

<div class="comment comment-xxxx..."> 

dove le x rappresentano un numero intero di lunghezza arbitraria e le ellissi rappresentano un numero arbitrario di altri valori separati da spazi bianchi (di cui non sono interessato). Non riesco a capire l'espressione regolare di espressioni regolari , specialmente dal momento che non ho mai usato la re classe python.

Utilizzando

soup.find_all(class_="comment") 

trova tutti i tag che iniziano con la parola commento. Ho provato con

soup.find_all(class_=re.compile(r'(comment)()(comment)')) 
soup.find_all(class_=re.compile(r'comment comment.*')) 

e un sacco di altre varianti, ma penso che mi manca qualcosa di ovvio qui su come espressioni o partita regex di lavoro(). Qualcuno mi può aiutare?

+1

In primo luogo, stai utilizzando BS3 o BS4? Uno ha 'findAll', uno ha' find_all', né ha findall' ... – abarnert

+0

Spiacente, BS4 - Non ho incollato direttamente dal mio codice, verrà modificato. – user1890572

+0

Dannazione, perché ho avuto una risposta per BS3 ... ma per BS4, sembra che non gli piacciano gli spazi in classe forse? O forse non conosco abbastanza bene BS4. Posso abbinare "commento", ma non "commento commento". Lo esaminerò. – abarnert

risposta

15

Credo di aver capito:

>>> [div['class'] for div in soup.find_all('div')] 
[['comment', 'form', 'new'], ['comment', 'comment-xxxx...']] 

Si noti che, a differenza l'equivalente in BS3, non è questo:

['comment form new', 'comment comment-xxxx...'] 

E questo è il motivo per cui le vostre espressioni regolari non corrisponderanno.

Ma si può abbinare, per esempio, questo:

>>> soup.find_all('div', class_=re.compile('comment-')) 
[<div class="comment comment-xxxx..."></div>] 

Nota che BS fa l'equivalente di re.search, non re.match, quindi non è necessario 'comment-.*'. Ovviamente, se vuoi corrispondere a 'comment-12345' ma non a 'comment-of-another-kind, ad esempio, 'comment-\d+'.

+0

Ricordo di aver letto qualcosa su questo nella documentazione BS4, ma è ancora controintuitivo. Grazie mille! Ho battuto la testa contro questo per un'ora +. – user1890572

+0

@ user1890572: Non sono sicuro del perché, ma non ho ancora letto i documenti BS4 oltre una rapida guida di "migrazione da BS3" di terze parti, quindi mi sono abituato a confondere problemi come questo nella mia codice. Pensa, se fossi più intelligente, non sarei stato in grado di rispondere. :) – abarnert