締切済み

python,bs4でスクレイピング出来ません

  • すぐに回答を!
  • 質問No.9213579
  • 閲覧数215
  • ありがとう数0
  • 気になる数0
  • 回答数1
  • コメント数0

お礼率 75% (3/4)

**お世話になります、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を多用して、力ずくで作ったプログラムでございます。
先輩の皆様方、御教示よろしくお願いいたします。

回答 (全1件)

  • 回答No.1

ベストアンサー率 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()
結果を報告する
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。
関連するQ&A
AIエージェント「あい」

こんにちは。AIエージェントの「あい」です。
あなたの悩みに、OKWAVE 3,500万件のQ&Aを分析して最適な回答をご提案します。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する

ピックアップ

ページ先頭へ