- 締切済み
python,bs4でスクレイピング出来ません
**お世話になります、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&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を多用して、力ずくで作ったプログラムでございます。 先輩の皆様方、御教示よろしくお願いいたします。
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- keeponsmile
- ベストアンサー率0% (0/0)
前回のはミスっていましたので修正しました。 # -*- coding:utf-8 -*- import urllib2 import codecs import cStringIO import csv from bs4 import BeautifulSoup # CSVをUnicodeで保存 class UnicodeWriter: """ A CSV writer which will write rows to CSV file "f", which is encoded in the given encoding. """ def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): # Redirect output to a queue self.queue = cStringIO.StringIO() self.writer = csv.writer(self.queue, dialect=dialect, **kwds) self.stream = f self.encoder = codecs.getincrementalencoder(encoding)() def writerow(self, row): self.writer.writerow([s.encode("utf-8") for s in row]) # Fetch UTF-8 output from the queue ... data = self.queue.getvalue() data = data.decode("utf-8") # ... and reencode it into the target encoding data = self.encoder.encode(data) # write to the target stream self.stream.write(data) # empty queue self.queue.truncate(0) def writerows(self, rows): for row in rows: self.writerow(row) def cmd(): base_url = 'http://db.netkeiba.com/?pid=jockey_detail&id=00663&page={0}' data = [] for i in xrange(1, 5): url = base_url.format(i) soup = BeautifulSoup(urllib2.urlopen(url).read(), 'html.parser') tr = soup.select('#contents_liquid > table > tbody > tr') td = [[x.get_text().strip() for x in y.select('td')] for y in tr] data.extend(td) # CSV保存 with open('horse.csv', 'wt') as fw: writer = UnicodeWriter(fw) writer.writerows(data) if __name__ == '__main__': cmd()