2013-04-27 11 views
7

come posso trovare tutte lasso di con una classe di 'blue' che contengono il testo nel formato:Come trovare gli span con una classe specifica contenente testo specifico usando una bella zuppa e re?

04/18/13 7:29pm 

che potrebbero pertanto essere:

04/18/13 7:29pm 

o:

Posted on 04/18/13 7:29pm 

in termini di costruire la logica per fare questo, questo è quello che ho ottenuto finora:

new_content = original_content.find_all('span', {'class' : 'blue'}) # using beautiful soup's find_all 
pattern = re.compile('<span class=\"blue\">[data in the format 04/18/13 7:29pm]</span>') # using re 
for _ in new_content: 
    result = re.findall(pattern, _) 
    print result 

Mi riferivo a https://stackoverflow.com/a/7732827 e https://stackoverflow.com/a/12229134 per cercare di capire un modo per farlo, ma quanto sopra è tutto quello che ho ottenuto finora.

edit:

per chiarire lo scenario, ci sono lasso di con:

<span class="blue">here is a lot of text that i don't need</span> 

e

<span class="blue">this is the span i need because it contains 04/18/13 7:29pm</span> 

e nota che ho solo bisogno di non 04/18/13 7:29pm il resto del contenuto.

Edit 2:

Ho anche provato:

pattern = re.compile('<span class="blue">.*?(\d\d/\d\d/\d\d \d\d?:\d\d\w\w)</span>') 
for _ in new_content: 
    result = re.findall(pattern, _) 
    print result 

e ottenuto l'errore:

'TypeError: expected string or buffer' 

risposta

13
import re 
from bs4 import BeautifulSoup 

html_doc = """ 
<html> 
<body> 
<span class="blue">here is a lot of text that i don't need</span> 
<span class="blue">this is the span i need because it contains 04/18/13 7:29pm</span> 
<span class="blue">04/19/13 7:30pm</span> 
<span class="blue">Posted on 04/20/13 10:31pm</span> 
</body> 
</html> 
""" 

# parse the html 
soup = BeautifulSoup(html_doc) 

# find a list of all span elements 
spans = soup.find_all('span', {'class' : 'blue'}) 

# create a list of lines corresponding to element texts 
lines = [span.get_text() for span in spans] 

# collect the dates from the list of lines using regex matching groups 
found_dates = [] 
for line in lines: 
    m = re.search(r'(\d{2}/\d{2}/\d{2} \d+:\d+[a|p]m)', line) 
    if m: 
     found_dates.append(m.group(1)) 

# print the dates we collected 
for date in found_dates: 
    print(date) 

uscita:

04/18/13 7:29pm 
04/19/13 7:30pm 
04/20/13 10:31pm 
+0

Potrei eseguire correttamente il codice esatto sopra, ma non funzionava nella mia implementazione. Ho pensato che potrebbe essere perché c'è un ' ' tra la data e l'ora nel codice sorgente originale, ad esempio '04/18/13   7:29 pm'. come riferimento, ho aggiunto '.replace ("   "," ")' all'originale ''urlopen read object'' e ha funzionato. grazie mille (a tutti i soccorritori!). – user1063287

1

Questo modello sembra soddisfare quello che stai cercando:

>>> pattern = re.compile('<span class="blue">.*?(\d\d/\d\d/\d\d \d\d?:\d\d\w\w)</span>') 
>>> pattern.match('<span class="blue">here is a lot of text that i dont need</span>') 
>>> pattern.match('<span class="blue">this is the span i need because it contains 04/18/13 7:29pm</span>').groups() 
('04/18/13 7:29pm',) 
+0

non so come implementare questo, ho pubblicato il codice che ho tentato in base al tuo suggerimento in origina l post (vedi modifica 2). – user1063287

+1

@ user1063287 prova a cambiare la terza riga in 'result = pattern.match (_). Groups()'. 're.findall' si aspetta una stringa (come la stringa che si usa in precedenza quando si chiama' re.compile' e invece si sta dando una regex già compilata. Essenzialmente si sta tentando di compilare il pattern due volte. –

+0

''TypeError: expected string o buffer'' – user1063287

2

Questa è un'espressione regolare flessibile che è possibile utilizzare:

"(\d\d?/\d\d?/\d\d\d?\d?\s*\d\d?:\d\d[a|p|A|P][m|M])" 

Esempio:

>>> import re 
>>> from bs4 import BeautifulSoup 
>>> html = """ 
<html> 
<body> 
<span class="blue">here is a lot of text that i don't need</span> 
<span class="blue">this is the span i need because it contains 04/18/13 7:29pm</span> 
<span class="blue">04/19/13 7:30pm</span> 
<span class="blue">04/18/13 7:29pm</span> 
<span class="blue">Posted on 15/18/2013 10:00AM</span> 
<span class="blue">Posted on 04/20/13 10:31pm</span> 
<span class="blue">Posted on 4/1/2013 17:09aM</span> 
</body> 
</html> 
""" 
>>> soup = BeautifulSoup(html) 
>>> lines = [i.get_text() for i in soup.find_all('span', {'class' : 'blue'})] 
>>> ok = [m.group(1) 
     for line in lines 
     for m in (re.search(r'(\d\d?/\d\d?/\d\d\d?\d?\s*\d\d?:\d\d[a|p|A|P][m|M])', line),) 
      if m] 
>>> ok 
[u'04/18/13 7:29pm', u'04/19/13 7:30pm', u'04/18/13 7:29pm', u'15/18/2013 10:00AM', u'04/20/13 10:31pm', u'4/1/2013 17:09aM'] 
>>> for i in ok: 
    print i 

04/18/13 7:29pm 
04/19/13 7:30pm 
04/18/13 7:29pm 
15/18/2013 10:00AM 
04/20/13 10:31pm 
4/1/2013 17:09aM 
Problemi correlati