2012-01-25 24 views
20

Ben aşağıdaki html (\ n ile işaretli satır sonları):Güzel Çorba ile belirli bir metin ile etiket nasıl bulunur?

... 
<tr> 
    <td class="pos">\n 
     "Some text:"\n 
     <br>\n 
     <strong>some value</strong>\n 
    </td> 
</tr> 
<tr> 
    <td class="pos">\n 
     "Fixed text:"\n 
     <br>\n 
     <strong>text I am looking for</strong>\n 
    </td> 
</tr> 
<tr> 
    <td class="pos">\n 
     "Some other text:"\n 
     <br>\n 
     <strong>some other value</strong>\n 
    </td> 
</tr> 
... 

nasıl arıyorum metin bulmak için? Aşağıdaki kod ilk bulunan değeri döndürür, bu yüzden bir şekilde Sabit metin filtrelemem gerekiyor.

result = soup.find('td', {'class' :'pos'}).find('strong').text 

Upd. Aşağıdaki kodu kullanırsanız::

title = soup.find('td', text = re.compile(ur'Fixed text:(.*)', re.DOTALL), attrs = {'class': 'pos'}) 
self.response.out.write(str(title.string).decode('utf8')) 

sonra sadece Sabit metni döndürür.

+0

'findAll' kullanmanız gerekir. – JBernardo

cevap

21

Çok gibi findAll text parametresi için normal bir ifade geçirebilirsiniz:

import BeautifulSoup 
import re 

columns = soup.findAll('td', text = re.compile('your regex here'), attrs = {'class' : 'pos'}) 
+0

Teşekkürler, Peter. Ama bulur ** Sabit metin: ** sonuçta değil ** metni arıyorum **. –

+0

Bu işaretlenmiş cevaptır, ancak sorunu çözmez. Cevap yazıyor olsa da – Nitay

+0

@LA_ Is 'soup.find (...)' 'body' etiketi ile mi yoksa html root ile mi başlıyor? – Sajad

21

Bu mesaj cevabı bu yazı eksik olsa bile benim cevaba beni. Geri vermem gerektiğini hissettim. Buradaki sorun, metin ile ve metin olmadan arama yaparken BeautifulSoup.find'un tutarsız davranışındadır.

Not: BeautifulSoup varsa , sen aracılığıyla yerel olarak test edebilirsiniz:

curl https://gist.githubusercontent.com/RichardBronosky/4060082/raw/test.py | python 

Kodu:https://gist.github.com/4060082

# Taken from https://gist.github.com/4060082 
from BeautifulSoup import BeautifulSoup 
from urllib2 import urlopen 
from pprint import pprint 
import re 

soup = BeautifulSoup(urlopen('https://gist.githubusercontent.com/RichardBronosky/4060082/raw/test.html').read()) 
# I'm going to assume that Peter knew that re.compile is meant to cache a computation result for a performance benefit. However, I'm going to do that explicitly here to be very clear. 
pattern = re.compile('Fixed text') 

# Peter's suggestion here returns a list of what appear to be strings 
columns = soup.findAll('td', text=pattern, attrs={'class' : 'pos'}) 
# ...but it is actually a BeautifulSoup.NavigableString 
print type(columns[0]) 
#>> <class 'BeautifulSoup.NavigableString'> 

# you can reach the tag using one of the convenience attributes seen here 
pprint(columns[0].__dict__) 
#>> {'next': <br />, 
#>> 'nextSibling': <br />, 
#>> 'parent': <td class="pos">\n 
#>>  "Fixed text:"\n 
#>>  <br />\n 
#>>  <strong>text I am looking for</strong>\n 
#>> </td>, 
#>> 'previous': <td class="pos">\n 
#>>  "Fixed text:"\n 
#>>  <br />\n 
#>>  <strong>text I am looking for</strong>\n 
#>> </td>, 
#>> 'previousSibling': None} 

# I feel that 'parent' is safer to use than 'previous' based on http://www.crummy.com/software/BeautifulSoup/bs4/doc/#method-names 
# So, if you want to find the 'text' in the 'strong' element... 
pprint([t.parent.find('strong').text for t in soup.findAll('td', text=pattern, attrs={'class' : 'pos'})]) 
#>> [u'text I am looking for'] 

# Here is what we have learned: 
print soup.find('strong') 
#>> <strong>some value</strong> 
print soup.find('strong', text='some value') 
#>> u'some value' 
print soup.find('strong', text='some value').parent 
#>> <strong>some value</strong> 
print soup.find('strong', text='some value') == soup.find('strong') 
#>> False 
print soup.find('strong', text='some value') == soup.find('strong').text 
#>> True 
print soup.find('strong', text='some value').parent == soup.find('strong') 
#>> True 

o kesinlikle yardım etmek çok geç olmasına rağmen OP, umarım bunu cevap olarak yaparlar, çünkü metinle bulmanın etrafındaki tüm dinamikleri tatmin eder.

+10

@BrunoBronosky, 5 yıl geçti ve hala yaptığınız bu belgelere geri dönüyorsunuz. Bunu yazmak için zaman ayırdığınız için teşekkür ederim. Kendini gerçekten takdir ediyorsun. –

+5

@BrunoBronosky Biliyorum, ama söylediğin için teşekkürler. –

+1

Teşekkürler, bu bana iyi bir gülüş verdi. #Aynı tekne – aneroid

İlgili konular