2013-04-27 8 views
7

Jak mogę znaleźć wszystkie rozpiętość jest z klasą 'blue' które zawierają tekst w formacie:Jak znaleźć przęsła z konkretną klasą zawierającą określony tekst za pomocą pięknej zupy i re?

04/18/13 7:29pm 

które mogłyby zatem być:

04/18/13 7:29pm 

lub:

Posted on 04/18/13 7:29pm 

w kategoriach budowy logiki, aby to zrobić, to jest to, co mam do tej pory:

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 

Odnoszę się do https://stackoverflow.com/a/7732827 i https://stackoverflow.com/a/12229134, aby spróbować wymyślić sposób, aby to zrobić, ale powyższe jest wszystkim, co mam do tej pory.

edit:

wyjaśnić scenariusz, istnieje rozpiętość jest z:

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

i

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

i pamiętać tylko trzeba 04/18/13 7:29pm nie reszta zawartości.

edit 2:

Próbowałem również:

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 

i dostaje błąd:

'TypeError: expected string or buffer' 

Odpowiedz

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) 

wyjściowa:

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

Mogłem pomyślnie uruchomić powyższy kod, ale nie działał on w mojej implementacji. Myślałem, że to możliwe, ponieważ istnieje " " pomiędzy datą i czasem w oryginalnym kodzie źródłowym, np. '04/18/13   19:29 '. dla odniesienia, dodałem '.replace ("   "," ")' do oryginalnego ''obiektu czytającego urlop'' i zadziałało. dziękuję bardzo (do wszystkich respondentów!). – user1063287

1

Ten wzór wydaje się spełniać to, czego szukasz:

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

nie wiem jak zaimplementować to, napisałem kod, który próbowałem na podstawie twojej sugestii do oryginału l post (patrz edycja 2). – user1063287

+1

@ user1063287 spróbuj zmienić trzecią linię na 'result = pattern.match (_). Groups()'. 're.findall' spodziewa się ciągu (jak ciąg, którego używasz wcześniej, gdy wywołujesz' re.compile' i zamiast tego podajesz już skompilowane wyrażenie.Zasadniczo próbujesz skompilować swój wzorzec dwa razy.) –

+0

''TypeError: oczekiwany ciąg lub bufor'' – user1063287

2

Jest to elastyczna regex, które można użyć:

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

Przykład:

>>> 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 
Powiązane problemy