Pregunta sobre beautifulsoup, python – Python beautifulsoup iterar sobre la mesa

12

Estoy tratando de raspar los datos de la tabla en un archivo CSV. Desafortunadamente, he llegado a un bloqueo de carretera y el siguiente código simplemente repite el TD desde la primera TR para todas las TR posteriores.

<code>import urllib.request
from bs4 import BeautifulSoup

f = open('out.txt','w')

url = "http://www.international.gc.ca/about-a_propos/atip-aiprp/reports-rapports/2012/02-atip_aiprp.aspx"
page = urllib.request.urlopen(url)

soup = BeautifulSoup(page)

soup.unicode

table1 = soup.find("table", border=1)
table2 = soup.find('tbody')
table3 = soup.find_all('tr')

for td in table3:
    rn = soup.find_all("td")[0].get_text()
    sr = soup.find_all("td")[1].get_text()
    d = soup.find_all("td")[2].get_text()
    n = soup.find_all("td")[3].get_text()

    print(rn + "," + sr + "," + d + ",", file=f)
</code>

Este es mi primer script en Python, por lo que cualquier ayuda sería apreciada. He revisado otras respuestas a las preguntas pero no puedo entender qué estoy haciendo mal aquí.

Tu respuesta

2   la respuesta
6

El problema es que cada vez que intentas restringir tu búsqueda (obtén el primer td en este tr, etc.), simplemente estás llamando a la sopa. La sopa es el objeto de nivel superior: representa todo el documento. Solo necesita llamar a la sopa una vez, y luego usar el resultado de esa sopa en lugar de la sopa para el siguiente paso.

Por ejemplo (con nombres de variables cambiados para ser más claros),

<code>table = soup.find('table', border=1)
rows = table.find_all('tr')

for row in rows:
    data = row.find_all("td")
    rn = data[0].get_text()
    sr = data[1].get_text()
    d = data[2].get_text()
    n = data[3].get_text()

    print(rn + "," + sr + "," + d + ",", file=f)
</code>

No estoy seguro de que la declaración impresa sea la mejor manera de hacer lo que intentas hacer aquí (como mínimo, debes usar el formato de cadena en lugar de la adición), pero lo dejo como está porque no es el Problema del núcleo.

Además, para completar:soup.unicode no hare nada No estás llamando a un método allí, y no hay asignación. No recuerdo que BeautifulSoup tuviera un método llamado Unicode en primer lugar, pero estoy acostumbrado a BS 3.0, por lo que puede ser nuevo en 4.

35

Estás comenzando en el nivel superior de tu documento cada vez que lo usas.find() ofind_all(), así que cuando solicitas, por ejemplo, todas las etiquetas "td" `obtienes todas las etiquetas" td "en el documento, no solo los de la tabla y fila que has buscado. También podrías no buscarlos porque no se están utilizando de la forma en que se escribe tu código.

Creo que quieres hacer algo como esto:

<code>table1 = soup.find("table", border=1)
table2 = table1.find('tbody')
table3 = table2.find_all('tr')
</code>

O, ya sabes, algo más como esto, con nombres de variables más descriptivos para arrancar:

<code>rows = soup.find("table", border=1).find("tbody").find_all("tr")

for row in rows:
    cells = row.find_all("td")
    rn = cells[0].get_text()
    # and so on
</code>

Preguntas relacionadas