23

テーブル データを 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 スクリプトなので、助けていただければ幸いです。他の質問の回答を見てきましたが、ここで何が間違っているのかわかりません。

4

2 に答える 2

56

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
于 2012-04-25T05:08:39.093 に答える
10

問題は、検索を絞り込もうとするたびに (この tr で最初の td を取得するなど)、代わりにスープにコールバックしていることです。Soup は最上位のオブジェクトで、ドキュメント全体を表します。スープを 1 回呼び出すだけで、次のステップでスープの代わりにその結果を使用できます。

たとえば (変数名がより明確になるように変更されています)、

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 で新しくなったのかもしれません。

于 2012-04-25T05:09:41.110 に答える