我正在尝试将表格数据写入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脚本,所以任何帮助将不胜感激!我已经查看了其他问题的答案,但无法弄清楚我在这里做错了什么。
答案 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中的新功能。