Python beautifulsoup迭代在桌子上

时间:2012-04-25 04:57:47

标签: python beautifulsoup

我正在尝试将表格数据写入CSV文件。不幸的是,我遇到了一个障碍,下面的代码只是从第一个TR重复了所有后续TR的TD。

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)

这是我的第一个Python脚本,所以任何帮助将不胜感激!我已经查看了其他问题的答案,但无法弄清楚我在这里做错了什么。

2 个答案:

答案 0 :(得分:36)

每次使用find()find_all()时,您都会从文档的顶层开始,所以当您要求提供所有“td”标签时文档中的所有“td”标记不仅仅是您搜索的表和行中的那些标记。你也可以不搜索它们,因为它们没有按照你的代码编写方式使用。

我想你想做这样的事情:

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

或者,你知道,更像这样的东西,有更多描述性的变量名称可以启动:

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

答案 1 :(得分:7)

问题在于,每次你试图缩小你的搜索范围(获得这个tr中的第一个td等)时,你只需要回电话。汤是顶级对象 - 它代表整个文档。你只需要打一次汤,然后用它的结果代替汤来进行下一步。

例如(变量​​名称变得更清楚),

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)

我不确定print语句是你在这里尝试做什么的最佳方式(至少,你应该使用字符串格式而不是添加),但我将它保留原样,因为这不是核心问题。

此外,完成后:soup.unicode将不会执行任何操作。你没有在那里调用一个方法,也没有任何作业。我不记得BeautifulSoup首先有一个名为unicode的方法,但我已经习惯了BS 3.0,所以它可能是4中的新功能。