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

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

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

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

3回答

2358閲覧

繰り返し処理でAPIの上限を超える結果を取得したい

fujiko20

総合スコア19

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2019/04/18 23:09

前提・実現したいこと

プログラミング初心者です。Python3でAPIを使い、国会会議録から該当キーワードの検索結果を年度ごとに取得し、ファイルに書き込みたいと考えています。このAPIは一度に取得できる検索結果の件数が100件と決まっているため、繰り返し処理を書きました。しかしエラーは出ないものの、上限設定を超えた結果は得られていません。

発生している問題・エラーメッセージ

エラーメッセージは出ず、取得した検索結果はファイルに書き込まれますが、確認すると取得できている検索結果はデフォルト上限設定の100件のみに留まっています。

該当のソースコード

Python3

1import requests 2from bs4 import BeautifulSoup 3 4#検索結果の総件数を取得する関数 5#総件数は<numberofrecords>の要素として返ってくる 6def all_api(year): 7 with open('../thesis/sr'+ str(year) +'.txt', 'r', encoding="utf-8-sig") as fr: 8 soup = BeautifulSoup(fr, 'lxml') 9 nor = int(soup.find("numberofrecords").string) 10 fr.close 11 return(nor) 12 13#検索結果をファイルに書き込む 14for i in range(1990, 1992+1): 15 url = 'http://kokkai.ndl.go.jp/api/1.0/speech?maximumRecords%3D100%26any%3D責任%26from%3D' + str(i) +'-01-01%26until%3D' + str(i) + '-12-31' 16 req = requests.get(url) 17 fw = open('../thesis/sr'+ str(i) +'.txt', 'w', encoding="utf-8") 18 fw.write(req.text) 19 res_num = all_api(i) 20 fw.close 21 22count = 1 #検索結果の開始位置「startRecord」を指定するためのカウンタ 23 24#検索結果が100件を超える場合、urlで取得した検索結果を該当ファイルに追記する 25for i in range(1990, 1992+1): 26 while res_num > 0: 27 with open('../thesis/sr'+ str(i) +'.txt', 'a', encoding="utf-8-sig") as fa: 28       url = 'http://kokkai.ndl.go.jp/api/1.0/speech?startRecord%3D' + str(count) + '%26maximumRecords%3D100%26any%3D責任%26from%3D' + str(i) + '-01-01%26until%3D' + str(i) + '-12-31' 29 req = requests.get(url) 30 fa.write(req.text) 31 res_num = res_num - 100 32 count += 1

試したこと

国会会議録APIの仕様を確認し、<numberofrecords>以外の返戻タグを使って同じ処理を書こうとしました。しかし、うまくいきませんでした。

補足情報(FW/ツールのバージョンなど)

国会会議録APIの仕様は以下のとおりです。

・国会会議録検索システム -国会会議録検索システム検索用APIについて-
http://kokkai.ndl.go.jp/api.html

※teratailの使い方にも慣れていないため、何かおかしなことをしていたら、お手数ですがご指摘ください。至らぬ点は改めていきます。

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

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

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

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

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

guest

回答3

0

ベストアンサー

国会会議録検索システム検索用APIについて のページの表"指定可能な検索パラメータ"の1項目に"開始位置"の説明があり、パラメータ名がstartRecordであることと、以下の備考が書かれています。
『総結果件数の中の出現位置を指定する。(※4)
省略時のデフォルト値は発言単位、会議単位ともに「1」』

そして表の下に以下の説明があります。
『(※4)総結果件数が一回の最大取得件数を超える場合、開始位置を変えて繰り返し取得することで、一回の最大取得件数を超えるレコードを取得できます。』

==
これらを総合して考えると
・同じ100件のデータしか取得できないのは、開始位置(startRecord)の設定をしていないため。(開始位置が毎回デフォールト値の1となっているので、毎回1~100番目の結果が得られている)
・2回目の取得時はstartRecordを101にする、3回目の取得はstartRecordを201にする、というように開始位置を変えて繰り返し取得すれば、「一回の最大取得件数を超えるレコードを取得できます」という事になるのではないか。

と思われます。 試してみてください。

投稿2019/04/19 00:34

coco_bauer

総合スコア6915

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

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

fujiko20

2019/04/19 22:13

丁寧にご教示くださり、感謝です! 開始位置(startRecord)の意味合いを完全に勘違いしておりました。こちらを変更してみたら、問題なく動くようになりました。本当にありがとうございます!
guest

0

ぱっと見でわかる問題点として「res_num」がファイルごとに分けられておりませんが、どのファイルも100件までしかないのでしょうか?

python3

1import requests 2from bs4 import BeautifulSoup 3 4#検索結果の総件数を取得する関数 5#総件数は<numberofrecords>の要素として返ってくる 6def all_api(year): 7 with open('../thesis/sr'+ str(year) +'.txt', 'r', encoding="utf-8-sig") as fr: 8 soup = BeautifulSoup(fr, 'lxml') 9 nor = int(soup.find("numberofrecords").string) 10 #fr.close ← with構文なのでいらない 11 return(nor) 12 13res = {} #resをファイルごとに分ける。 14#検索結果をファイルに書き込む 15for i in range(1990, 1992+1): 16 url = 'http://kokkai.ndl.go.jp/api/1.0/speech?maximumRecords%3D100%26any%3D責任%26from%3D' + str(i) +'-01-01%26until%3D' + str(i) + '-12-31' 17 req = requests.get(url) 18 with open('../thesis/sr'+ str(i) +'.txt', 'w', encoding="utf-8-sig") as fw: 19 fw.write(req.text) 20 res_num[i] = all_api(i) 21 22count = 1 #検索結果の開始位置「startRecord」を指定するためのカウンタ 23 24#検索結果が100件を超える場合、urlで取得した検索結果を該当ファイルに追記する 25for i in range(1990, 1992+1): 26 while res_num[i] > 0: 27 with open('../thesis/sr'+ str(i) +'.txt', 'a', encoding="utf-8-sig") as fa: 28       url = 'http://kokkai.ndl.go.jp/api/1.0/speech?startRecord%3D' + str(count) + '%26maximumRecords%3D100%26any%3D責任%26from%3D' + str(i) + '-01-01%26until%3D' + str(i) + '-12-31' 29 req = requests.get(url) 30 fa.write(req.text) 31 res_num[i] = res_num[i] - 100 32 count += 1

下の方の話の通り、もしこれでうまくいかないのであれば、
res_numとreq.textを途中でprintで出力して中身を確認してみてください。

投稿2019/04/18 23:44

編集2019/04/18 23:50
gyungyun545

総合スコア84

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

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

fujiko20

2019/04/19 22:16

丁寧にご教示くださいまして、本当にありがとうございます! 「res_num」がファイルごとに分けられていない問題、恥ずかしながらご指摘を受けて初めて気づきました。この部分を関数にするのではなく、for文の中に記述することで結果が取得できるようになりました!
guest

0

単に元サイトでの取得制限に引っかかってるだけでは。
その繰り返し処理中でどんな結果が得られてるのかみてみればどうでしょう、

投稿2019/04/18 23:44

y_waiwai

総合スコア87749

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

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

fujiko20

2019/04/19 22:19

ご教示ありがとうございます。おっしゃるとおり取得制限の問題で、繰り返し処理が書ければ回避できることなのですが、そこがうまくいかずに悩んでおりました。基本をもっと頑張ります!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問