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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

6351閲覧

Pythonのreやpandasを使った外部サイトからのデータ取得が出来ません

ponkotsu

総合スコア10

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2016/03/13 03:34

http://www.keipy53.esy.es/2015/01/24/getbaseballdata.html

を参考に、npbサイトから野球選手のデータを取得しています。
今回、全チームのデータを一度に取得したく考え、teamListを作成し、for文で回しているのですが
25 columns Passed ,passed data had 24 columns
と出てしまい、上手く動きません
columns_name に一つ項目を付け加えたことが原因だと思うのですが、
re_dataにもカラム数に合わせて、項目を増やすことは出来るのでしょうか

python

1# -*- coding: utf-8 -*- 2import re 3import urllib.request, urllib.error 4from bs4 import BeautifulSoup 5from pandas import DataFrame 6import numpy as np 7import pandas as pd 8 9opener = urllib.request.build_opener() 10years = [2011,2012,2013,2014,2015] 11teamList = ["h","bs","f","m","l","e","g","t","c","d","db","s"] 12batting_data = DataFrame() 13for year in years : 14 for team in teamList : 15 url="http://bis.npb.or.jp/"+str(year)+"/stats/idb1_"+team+".html" 16 html = opener.open(url).read() 17 shtml = html.decode('Shift-JIS','replace') 18 soup = BeautifulSoup(shtml) 19 data = soup.findAll("tr", attrs={"class":"ststats"}) 20 re_tag = re.compile(r'<tr.*?>|</tr>|<br/>|</td>|<td class="stplayer">|\n') 21 re_data = [re_tag.sub("", str(d)).split("<td>") for d in data] 22 23 columns_name = ["Team","Year","Name","G","PA","AB","R","H","2B","3B","HR","TB","RBI","SB","CS","SAC","SF","BB","IBB","HBP","SO","GIDP","AVG","SLG","OBP"] 24 _batting_data=DataFrame(re_data, columns = columns_name) 25 _batting_data.Year=year 26 _batting_data.Team = team 27 batting_data= pd.concat([batting_data, _batting_data], axis=0) 28batting_data.to_csv('data/batting_bs.csv')

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

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

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

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

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

argius

2016/03/18 06:41

エラーに出ている通り、データには24カラムしか無いので、整合性がおかしいと言われています。足りない1カラムをどのように埋めたいのか、その点についてヒントいただけると回答できるかも知れません。
guest

回答1

0

ベストアンサー

情報追加依頼してしまいましたが、
とりあえず、データの各行の最後の列にダミーの1カラムを追加する場合について書いておきます。

re_data = [re_tag.sub("", str(d)).split("<td>") for d in data]
[re_tag.sub("", str(d)).split("<td>") for d in data]の部分は、「内包表記」と呼ばれるものです。

dataはHTMLテーブルの行(tr)が複数個まとめられたリストになっていますので、それを1つずつ取り出したものがdです。
re_tag.sub("", str(d)).split("<td>")の部分が、
dを加工して別のリストに変換する処理になっています。
この場合だと、<tr><td>A</td><td>B</td></tr>(細かいところは省略)というHTMLがあったら、Pythonのリスト['A', 'B']に変換します。

この行の最後の列にダミーの1カラムを追加するとしたら、リストの連結もしくは要素の追加を使って、リストに要素を足せばOKです。

lang

1re_data = [re_tag.sub("", str(d)).split("<td>") + ['X'] for d in data]

上の例で言うと、['A', 'B'] + ['X']を計算していることになり、['A', 'B', 'X']が得られます。

こうすれば、全ての行の25カラム目にXという値が設定されたデータができます。

投稿2016/03/18 07:13

argius

総合スコア9390

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

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

ponkotsu

2016/03/21 10:11

先頭に空の一行を入れたかったのですが、ちょっと参考にやってみます ありがとうございます
argius

2016/03/21 10:54

では、["X"]は後ろではなく前に付ければ良さそうですね。 1列目にはインデックス番号らしきものが自動で入るのでそこには差し込めませんでしたが、 2列目に「(EMPTY)」という名前の空の列を追加することはできました。 もともと足りない1列も合わせて、2つ追加しないといけないみたいですね。 re_data = [ ["", ""] + re_tag.sub("", str(d)).split("<td>") for d in data] columns_name = ["(EMPTY)", "Team","Year","Name","G", "PA","AB","R","H","2B","3B","HR","TB","RBI","SB", "CS","SAC","SF","BB","IBB","HBP","SO","GIDP","AVG","SLG","OBP"]
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問