netkeiba.com様より、競馬情報をpython,beautifulsoupでスクレイピングしていますが、
IndexError: list index out of range に対応したのに、うまく動かず、困っています!
# -*- coding:utf-8 -*- import urllib2 import codecs import time def tounicode(data): f = lambda d, enc: d.decode(enc); codecs = ['shift-jis','utf-8','euc-jp','cp932', 'euc-jis_2004','euc-jisx0213','iso2022-jp','iso2022-jp-1', 'iso2022-jp-2','iso2022-jp-2004','iso2022-jp-3','iso2022-jp-ext', 'shift-jis-2004','shift-jisx0213','utf-16','utf-16-be', 'utf-16-le','utf-7','utf-8-sig']; for codec in codecs: try: return f(data, codec); except: continue; return None; def toeuc(data): data1 = tounicode(data); # 上で紹介したUnicode変換メソッド data2 = []; for char in data1[:]: # スライスで一文字ずつ調べる try: data2.append(char.encode('euc-jp')); except: pass; return ''.join(data2); import random from bs4 import BeautifulSoup f = codecs.open('h2007_1.csv', 'w', 'utf_8') f.write('horse_name,jockey_name,nobori'+u"\n") horse_name = "" start_url = 'http://db.netkeiba.com/horse/2007100{0}/' for i in xrange(1,1000): url = start_url.format(i) soup = BeautifulSoup(urllib2.urlopen(url).read(), "lxml") time.sleep(random.uniform(5,10)) horse_name_tag = soup.find('div', {'class': 'horse_title'}) if horse_name_tag is not None: if horse_name_tag.find('h1') != None: horse_name = horse_name_tag.find('h1').text horse_name = "".join( [x for x in horse_name_tag.text if not x == u'\xa0' and not x == u'\n']) tr_arr = soup.select("table.db_h_race_results > tbody > tr") for tr in tr_arr: tds=tr.findAll("td") if len( tds ) > 0: jockey_name=tds[12].a.text #騎手名 nobori=tds[22].text #上り print horse_name.strip(),jockey_name.strip(),nobori.strip() cols = [horse_name,jockey_name,nobori] f.write(",".join(cols) + "\n") else: continue f.close()
当サイトの先輩から、netkeiba.comはeuc-jpの漢字コードであると御指摘をいただきましたので、4行目から25行目付近はその対策のために、他のサイト等で調べて貼り付けたものでございます。その目的のために作用しているかは不明ではございますが、上記スクリプトは、途中までは快適に動きます。
以下が、プリント画面でございます。
Microsoft Windows [Version 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved. C:\Users\satoru\horse\horse\2007>t_horse_scan_2007_1.py カントリースノー 2.75抹消 セ 黒鹿毛 草野太郎 13.2 カントリースノー 2.75抹消 セ 黒鹿毛 草野太郎 13.4 カントリースノー 2.75抹消 セ 黒鹿毛 原田和真 カントリースノー 2.75抹消 セ 黒鹿毛 高野和馬 途中、省略 □地スイセンキョウ 0.00 牝 鹿毛 永森大智 40.0 □地スイセンキョウ 0.00 牝 鹿毛 上田将司 43.1 □地スイセンキョウ 0.00 牝 鹿毛 石本純也 41.6 □地スイセンキョウ 0.00 牝 鹿毛 石本純也 42.2 □地スイセンキョウ 0.00 牝 鹿毛 岡村卓弥 40.8 □地スイセンキョウ 0.00 牝 鹿毛 上田将司 44.8 □地スイセンキョウ 0.00 牝 鹿毛 上田将司 42.6 Traceback (most recent call last): File "C:\Users\satoru\horse\horse\2007\t_horse_scan_2007_1.py", line 64, in <module> nobori=tds[22].text #荳翫j IndexError: list index out of range C:\Users\satoru\horse\horse\2007>
IndexError: list index out of range とエラーメッセージが出ましたが、
tr_arr = soup.select("table.db_h_race_results > tbody > tr") for tr in tr_arr: tds=tr.findAll("td") if len( tds ) > 0: jockey_name=tds[12].a.text #騎手名 nobori=tds[22].text #上り
上記のように、if文を用いて、対策を講じているつもりです。
しかし、IndexError: list index out of range が出てきます。
すごく、不思議に思って、その箇所のソースコードを調べてみました。
http://db.netkeiba.com/horse/2007100135/ のページのソースコードにおける、
小生のスクリプトのエラー箇所
□地スイセンキョウ 0.00 牝 鹿毛 上田将司 44.8
□地スイセンキョウ 0.00 牝 鹿毛 上田将司 42.6 付近のソースコードの抜粋です。
</td> <td>5-4-4-9</td> <td> </td> <td class="bml">44.8</td> <td>387(-5)</td> <td class="bml" align="center" nowrap> </td> <td class="bml" nowrap> </td> <td><a href="/horse/2008100733/">サクライーグル</a></td> <td> </td> </tr><tr> <td><a href="/race/list/20120227/">2012/02/27</a></td> <td><a href="/race/sum/54/20120227/">高知</a></td> <td>晴</td> <td class="txt_right">8</td> <td class=""><a href="/race/201254022708/" title="C2ロ">C2ロ</a></td> <td> </td> <td class="txt_right">12</td> <td class="txt_right">2</td> <td class="txt_right">2</td> <td class="txt_right">101.4</td> <td class=" txt_right">8</td> <td class="bml txt_right">7</td> <td> <a href="/jockey/a01ad/" title="上田将司">上田将司</a> </td> <td>54</td> <td>ダ1300</td> <td>重</td> <td class="bml txt_right"> </td> <td class="txt_right">1:31.1</td> <td class="txt_right">3.6</td> <td class="bml txt_right"> </td> <td>7-7-5-7</td> <td> </td> <td class="bml">42.6</td> <td>392(+4)</td> <td class="bml" align="center" nowrap>
小生の見る限りでは、
<td class="bml">44.8</td>
も
<td class="bml">42.6</td>
に、ついても、 真っ当な数値でありまして、空欄でもなく、if len( tds ) > 0: のエラー対策で十分ではと考えています。
しかし、エラーが出てまいります。
**他の nobori=tds[22].text は うまく数字を出してくれるのに、同じソースコードで
なぜ、この部分だけに、エラーが発生する理由が、分からず苦慮しております。
**
先輩方の御教示、よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。