質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

3128閲覧

python2.7,beautifulsoupを用いて、規則性のある20行24列の競馬のデータ表をCSVに書き込むことが出来ずに困っています!!!

akakage13

総合スコア89

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2016/08/10 11:05

編集2016/08/10 11:53

###前提・実現したいこと
****お世話になります、python初心者です**python2.7,beautifulsoupを用いて、競馬データをスクレイピングしておりますが、どうにも困っております。
1行だけはprintすることが出来るのですが、20行をスクレイピングするスクリプトと、併せて、CSVに出力させるスクリプトが分かりません。
**

###発生している問題・エラーメッセージ
**csvに保存が出来ないこと

20行をまとめてスクレイピングすることが出来ないこと` ** ###該当のソースコード ```python2.7 ```ここに言語を入力 # -*- coding:utf-8 -*- import urllib2 import codecs from bs4 import BeautifulSoup f = codecs.open('horse.csv', 'w', 'utf-8') f.write('race_date,kaisai,weather,race_number,race_name,tousuu,frame_number,horse_number,single_win_ratio,popularity,horse_arrival,horse_name,weight,distance,baba, race_time,difference,horse_pass,pace,nobori,horse_weight,win_horse,prize_money'+ u"\n") tpl_url='http://db.netkeiba.com/?pid=jockey_detail&id=00663&page={0}' for i in xrange(1, 5): url=tpl_url.format( i ) soup = BeautifulSoup(urllib2.urlopen(url).read(),"lxml") tr_arr = soup.find('div', {'id':'contents_liquid'}).findAll('tbody') for tr in tr_arr: #日付#race_date lrg1= tr.findAll('td')[0].string #開催#kaisai lrg2= tr.findAll('td')[1].string #天気#weather lrg3= tr.findAll('td')[2].string #第○レース#race_number lrg4= tr.findAll('td')[3].string #レース名#race_name lrg5= tr.findAll('td')[4].string #映像(この部分、削除したいです) lrg6= tr.findAll('td')[5].string #頭数#tousuu lrg7= tr.findAll('td')[6].string #枠番#frame_number lrg8= tr.findAll('td')[7].string #馬番#horse_number lrg9= tr.findAll('td')[8].string #単勝#single_win_racio lrg10= tr.findAll('td')[9].string #人気#popularity lrg11= tr.findAll('td')[10].string #着順#horse_arrival lrg12= tr.findAll('td')[11].string #馬名#horse_name lrg13= tr.findAll('td',{'class':'txt_l'}) [1] #斤量#weight lrg14= tr.findAll('td')[13].string #距離#distance lrg15= tr.findAll('td')[14].string #馬場#baba lrg16= tr.findAll('td')[15].string #タイム#race_time lrg17= tr.findAll('td')[16].string #着差#difference lrg18= tr.findAll('td')[17].string #通過#horse_pass lrg19= tr.findAll('td')[18].string #ペース#pace lrg20= tr.findAll('td')[19].string #上り#nobori lrg21= tr.findAll('td')[20].string #馬体重#horse_weight lrg22= tr.findAll('td')[21].string #勝ち馬#win_horse lrg23= tr.findAll('td',{'class':'txt_l'}) [2] #賞金#prize_money lrg24= tr.findAll('td')[23].string print lrg1,lrg2,lrg3,lrg4,lrg5,lrg6,lrg7,lrg8,lrg9,lrg10,\ lrg11,lrg12,lrg13.a.string,lrg14,lrg15,lrg16,lrg17,\ lrg18,lrg19,lrg20,lrg21,lrg22,lrg23.a.string,lrg24 f.close()

コード

(参考)下記のコードが苦慮しておりますスクレイピング対象のHTMLの 最初の1行部分でございます。 開催日毎に、これが1つのページに、20行、連続してございます。 1行しか捕らえられず、困っております。 <tbody> <tr class=""> <td><a href="/race/list/20160807/">2016/08/07</a></td> <td><a href="/race/sum/04/20160807/">2新潟4</a></td> <td>晴</td> <td class="txt_right">12</td> <td class="bml txt_l"><a href="/race/201604020412/" title="3歳上500万下">3歳上500万下</a></td> <td> <a href="/?pid=movie&amp;id=201604020412" target="_blank"><img src="/style/netkeiba.ja/image/icon_douga.png" border="0"></a> </td> <td class="txt_right">15</td> <td class="txt_right">7</td> <td class="txt_right">13</td> <td class="r3ml txt_right">6.9</td> <td class="r3ml txt_right">3</td> <td class="r2ml txt_right">2</td> <td class=" txt_l"> <a href="/horse/2013103614/">チェイスダウン</a> </td> <td>54</td> <td>ダ1200</td> <td>良</td> <td class="txt_right">1:11.9</td> <td class="txt_right">0.3</td> <td>8-8</td> <td>34.5-37.1</td> <td class="r1ml">36.6</td> <td>468(+2)</td> <td class=" txt_l"> <a href="/horse/2013101531/">クリムゾンバローズ</a> </td> <td>300.0</td> ###試したこと forなどで、ループさせてみましたが、スキル不足でうまくいきませんでした。 ###補足情報(言語/FW/ツール等のバージョンなど) python2.7 findAllを多用して、力ずくで作ったプログラムでございます。 先輩の皆様方、御教示よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

attakei

2016/08/10 11:44

コードの部分をコードブロックで囲んでいただけますか。(``` または エディタの[</>]ボタンで囲めます。詳しくはヘルプを参照してください) 特にPythonのようにインデントが言語構造上非常に重要な言語は、コードブロックで囲まれている状態でないと正しい状態の把握がしづらくなり、回答が得られにくくなります
guest

回答1

0

ベストアンサー

私の判断ですが、HTMLソースを見たところでは、race_table_01クラスを持ったtableの子のtbodyの子のtrを取得するのが良いと思います。
tr_arr = soup.select("table.race_table_01 > tbody > tr")とすればそのように取得できます。

  • コード例(機能を制限したバージョン)

lang

1import urllib2 2import codecs 3from bs4 import BeautifulSoup 4 5tpl_url='http://db.netkeiba.com/?pid=jockey_detail&id=00663&page={0}' 6 7url = tpl_url.format( 1 ) # とりあえず1ページ目だけ 8soup = BeautifulSoup(urllib2.urlopen(url).read(),"lxml") 9 10tr_arr = soup.select("table.race_table_01 > tbody > tr") 11 12for tr in tr_arr: 13 tds = tr.findAll("td") 14 race_date = tds[0].a.text # 日付 15 kaisai = tds[1].a.text # 開催 16 print race_date, kaisai

(追記)

CSVファイルのところを書き忘れました。
ざっくり書くと、配列にまとめてjoin関数で結合、ヘッダーと同じくf.write()で出力します。1行出力なので、改行文字をつけます。

lang

1# forループの中 2 cols = [race_date, kaisai] 3 f.write(",".join(cols) + "\n"))

投稿2016/08/10 14:12

編集2016/08/10 14:55
argius

総合スコア9390

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問