web-dev-qa-db-fra.com

Comment obtenir de la valeur de la table td dans BeautifulSoup?

J'ai une page avec quelques tableaux dans sa source:

<table width='100%' cellspacing='0' cellpadding='2' class='an'>
    <tr>
        <td width='35%' align='right'>XXX :</td>
        <td><b>20</b></td>
    </tr>
    <tr><
        td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
</table>

<table width='361' cellspacing='0' cellpadding='2' class='an'>
    <tr>
        <td width='35%' align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XX :</td>
        <td><a href='XXX'><b>XXX</b></a></td>
    </tr>
    <tr>
        <td align='right'>PHONE :</td>
        <td><b>518878943</b></td>
    </tr>
</table>

J'aimerais obtenir de cette page un numéro de téléphone, du deuxième tableau:

<td align='right'>PHONE :</td>
<td><b>518878943</b></td>

Cependant, mon code:

page_src="""<table width='100%' cellspacing='0' cellpadding='2' class='an'>
    <tr>
        <td width='35%' align='right'>XXX :</td>
        <td><b>20</b></td>
    </tr>
    <tr><
        td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
</table>

<table width='361' cellspacing='0' cellpadding='2' class='an'>
    <tr>
        <td width='35%' align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XXX :</td>
        <td><b>XXX</b></td>
    </tr>
    <tr>
        <td align='right'>XX :</td>
        <td><a href='XXX'><b>XXX</b></a></td>
    </tr>
    <tr>
        <td align='right'>PHONE :</td>
        <td><b>518878943</b></td>
    </tr>
</table>
"""

soup = BeautifulSoup(page_src, 'html.parser')
divs = soup.findAll("table", {"class": "an"})
for div in divs:
    row = ''
    rows = [row in div.findAll('tbody').findAll('tr')]

Me donne un tel message d'erreur:

Traceback (most recent call last):
  File "test.py", line 198, in <module>
    rows = [row in div.findAll('tbody').findAll('tr')]
AttributeError: 'ResultSet' object has no attribute 'findAll'

Comment résoudre ce problème et obtenir le numéro de téléphone sur la page? Merci

MODIFIER:

Partiellement résolu. En partie, parce que je pense que ma solution est moche, mais fonctionne. Peut-être que quelqu'un trouvera une solution plus jolie?

tds = []
soup = BeautifulSoup(page_src, 'html.parser')
divs = soup.findAll("table", {"class": "an"})
for div in divs:
    rows = div.findAll('tr')
    for row in rows :
        tds.append(row.findAll('td'))
phone = str(tds[12][1])
phone = phone.replace("<td><b>", "").replace("</b></td>", "").strip()
print phone
9
yak

Recherchez l'élément td contenant PHONE : puis récupérez le élément frère suivant . Une ligne:

soup.find("td", text="PHONE :").find_next_sibling("td").text
12
alecxe

Vous avez quelques problèmes avec votre code.

divs = soup.findAll("table", {"class": "an"})  
for div in divs:
    row = ''
    rows = [row in div.findAll('tbody').findAll('tr')]

Le premier problème est qu'il n'y a pas de balises tbody donc div.findAll('tbody') ne retournera rien.

Le deuxième problème est que div.findAll('tbody') retournerait un tableau, pas une balise, donc vous ne pouvez pas appeler findAll('tr') dessus.

Voici ce que vous voulez obtenir toutes les balises tr dans le tableau:

divs = soup.findAll("table", {"class": "an"})  
for div in divs:
    row = ''
    rows = div.findAll('tr')

Vous pouvez ensuite parcourir toutes les balises tr et appeler .text Pour obtenir le texte à l'intérieur de la ligne, et celles que vous avez "PHONE" sont celles que vous voulez.

soup = BeautifulSoup(page_src, 'html.parser')
divs = soup.findAll("table", {"class": "an"})
for div in divs:
    row = ''
    rows = div.findAll('tr')
    for row in rows:
        if(row.text.find("PHONE") > -1):
            print(row.text)

génère:

PHONE :
518878943
3
dstudeba