web-dev-qa-db-fra.com

Comment trouver un tag avec un texte particulier avec Beautiful Soup?

J'ai le code HTML suivant (les sauts de ligne marqués d'un\n):

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

Comment trouver le texte que je cherche ? Le code ci-dessous renvoie la première valeur trouvée, je dois donc filtrer par Texte fixe en quelque sorte.

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

Upd . Si j'utilise le code suivant:

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

alors il retourne juste Texte fixe: .

22
LA_

Vous pouvez transmettre une expression régulière au paramètre text de findAll, comme suit:

import BeautifulSoup
import re

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

Ce post m'a amené à ma réponse même si la réponse est manquante de ce post. Je sentais que je devais redonner.

La difficulté réside dans le comportement incohérent de BeautifulSoup.find lors de recherches avec et sans texte.

Remarque: Si vous avez BeautifulSoup, vous pouvez le tester localement via:

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

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

Bien qu'il soit certainement trop tard pour aider le PO, j'espère qu'il saura y remédier, car cela résout tous les dilemmes entourant la recherche par texte.

23
Bruno Bronosky

à partir de bs4 import BeautifulSoup

de urllib.request import urlopen, Demande

depuis urllib.parse import urljoin, urlparse

rawLinks=soup.findAll('a',href=True)
for link in rawLinks:

    innercontent=link.text

    if keyword.lower() in innercontent.lower():

       print(link)
0
Prasad Giri