2016-07-03 10 views
-1

が存在するにもかかわらず、リストの要素にアクセスすることはできません。Pythonの:それは私が<strong>Pythonの</strong>とその<em>urllib2の</em>と<em>BeautifulSoup</em>ライブラリを使用して、ウェブサイトからデータを抽出するコードを記述しようとしている

私は、希望のテーブルの行を繰り返して、 "td"で指定された各行のデータをリスト変数row_dataに格納しようとしました。イベント全体を印刷することはできますが、特定のインデックスでリストにアクセスすることはできず、インタプリタは「リストのインデックスが範囲外です」というエラーをスローします。ここに私のコードと出力があります。

import urllib2 
from bs4 import BeautifulSoup 

link = 'http://www.babycenter.in/a25008319/most-popular-indian-baby-names-of-2013' 
page = urllib2.urlopen(link) 
soup = BeautifulSoup(page) 
right_table = soup.find('table', class_= 'contentTable colborders') 
name=[] 
meaning=[] 
alternate=[] 

for row in right_table.find_all("tr"): 
    row_datas = row.find_all("td") 
    print row_datas 
    print row_datas[0] 

出力:

[]Traceback (most recent call last): 
    File "C:\Users\forcehandler\Documents\python\data_scrape.py", line 41, in <module> 

print row_datas[0] 
IndexError: list index out of range 
[Finished in 1.6s] 

私は、任意の明らかなエラーをマークするために、同様のコードを試みたが、無駄に。 コード:

i = [range(y,10) for y in range(5)] 
for j in i: 
    print j 
    print j[0] 

出力:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
0 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 
1 
[2, 3, 4, 5, 6, 7, 8, 9] 
2 
[3, 4, 5, 6, 7, 8, 9] 
3 
[4, 5, 6, 7, 8, 9] 
4 

私はプログラミングに新たなんだとどこにも役立つ見つけることができませんでした。前もって感謝します!

編集:コピー貼り付け中にTracebackの前の '[]'が出力に誤って挿入されている可能性があります。あなたに有益な回答/提案をいただきありがとうございます。

解決方法:使用する前にデータの整合性をチェックしませんでした。最初の行は 'th'値と 'td'値だけで構成されていたため、エラーが発生していました。

レッスン:データを使用する前に、必ずテストしてください。

サイドノート:これはStackOverflowに関する私の最初の質問であり、私はそのようなクイックで質の高い有用な回答に圧倒されています。

+0

は 'どの時点で空のリストを示すrow_datas'印刷しているのですか? –

+1

あなたの 'print row_datas'行はそのトレースバックの直前に' [] 'を表示します(' Traceback'ではなく[[] Traceback'があります。なぜあなたは改行を印刷していないように見えるかもしれません)。リストは空で、インデックス '0'には要素がありません。 –

+0

そのテーブルを見ると、52行のうち50行に 'td'要素があります。代わりに 'th 'ヘッダ要素を持つ2つの行があります。 –

答えて

2

あなたの出力は、行の少なくとも一つがであることを示しています:

CSSSセレクタを経由してslected

select()リターンすべての要素が、それはかなり強力です、あなたのコードは、そのような何かになります

[]Traceback (most recent call last): 
^^ 

その[]は空のリストです。出力はprint row_datas行で生成されました。通常、私はそれとTracebackの間に改行があることを期待しています。おそらく出力を正しくコピーしていないか、ラインバッファリングではなくサイズバッファを使用してstdoutとstderrを混在させるコンソールがあります。それらの行の最初ではなく、それにthヘッダーセルを持っているためだ

>>> rows = soup.select('table.contentTable tr') 
>>> rows[0].find('td') is None 
True 
>>> rows[0].find_all('th') 
[<th width="20%">Name</th>, <th>Meaning</th>, <th>Popular <br/>\nalternate spellings</th>] 

あり一つの他、このような行があるので、あなたは守備コーディングする必要があります:

>>> rows[26] 
<tr><th width="20%">Name</th><th>Meaning</th><th>Popular <br/>\nalternate spellings</th></tr> 

あなたにifステートメントの要素があるかどうかだけをテストできます。

if row_datas: 
    print row_datas[0] 
すべての名前、意味や代替スペルを抽出する

コードと同じくらい簡単です:

for row in soup.select('table.contentTable tr'): 
    cells = row.find_all('td') 
    if not cells: 
     continue 
    name_link = cells[0].find('a') 
    name, link = name_link.get_text(strip=True), name_link.get('href') 
    meaning, alt = (cell.get_text(strip=True) for cell in cells[1:]) 
    print '{}: {} ({})'.format(name, meaning, alt) 
+0

エラーを指摘してくれてありがとう。それを見落としてしまったのは本当に馬鹿だった。そして私が働くためにはるかにクリーンなコードを与えてくれてありがとう! – forcehandler

0

リストに要素がないため、row.find_all("td")が見つからない場合は、html構造を確認するかselectメソッドを使用する必要があります。

row_datas = soup.select("td") #Note that select() is method of a BeautifulSoup Object . 
    print row_datas 
    print row_datas[0] 
+0

'select()'は 'find()'関数よりもはるかに使いやすいようです。ご回答有難うございます! – forcehandler

関連する問題

 関連する問題