KeyError: 'items'
LOOP = 100
image_idx = 0
for x in range(LOOP):
1検索キーワードの上限(100件)に達してAPIから結果を取得できなくなったのでは。
requests.get
の戻り値のレスポンスに対して、raise_for_status()
を実行してステータスコードを確認してくださいな。
サンプルコードです。(未テスト)
Python
1from logging import getLogger, StreamHandler, Formatter, DEBUG
2import requests
3import shutil
4
5LOGGER = getLogger('custom_search_api')
6HANDLER = StreamHandler()
7HANDLER.setLevel(DEBUG)
8HANDLER.setFormatter(Formatter('%(message)s'))
9LOGGER.setLevel(DEBUG)
10LOGGER.addHandler(HANDLER)
11
12
13def fetch(url: str, params: dict=None):
14 res = requests.get(url, params)
15 res.raise_for_status()
16 return res
17
18API_PATH = "https://www.googleapis.com/customsearch/v1"
19start_index = 1
20PARAMS = {
21 "cx" : "xxxx:xxxx", #検索エンジンID
22 "key": "xxxxxxxxx", #APIキー
23 "q" : "映画", #検索ワード
24 "searchType": "image", #検索タイプ
25 "start" : start_index, #開始インデックス
26 "num" : 10 #1回の検索における取得件数(デフォルトで10件)
27}
28for _ in range(10): # 10 * 10 = 100
29 res = fetch(API_PATH, params)
30 LOGGER.info('#' * 80)
31 res_json = res.json()
32 for idx, items in enumerate(res_json['items'], start=start_index):
33 path = "imgs/" + str(idx) + ".png"
34 download_link = items['link']
35 LOGGER.info(f'url:{download_link}')
36 r = requests.get(download_link, stream=True)
37 if r.status_code == 200:
38 with open(path, 'wb') as f:
39 r.raw.decode_content = True
40 shutil.copyfileobj(r.raw, f)
41 start_index = res_json['queries']['nextPage'][0].get('startIndex')
42 LOGGER.info(f'next:{start_index}')
43 params['start'] = start_index
あと、無料枠の場合は1日のクエリ制限100もあります。
参考:Yahoo、Bing、Googleでの画像収集事情まとめ
大手の検索エンジンは画像検索に関しては制限がきついです。
回答の要旨を上手く伝えきれていないので、補足説明。
質問文のコードはnumを考慮していなく1クエリ100件を上手く処理できないコードです。
"num" : 10 #1回の検索における取得件数(デフォルトで10件)
wandbox
私の回答文のコードを参考に10クエリ*10件の総数:100に変更してみてくださいな。
スクレイピングは相手サイトの都合にかなり影響されます。
例外の発生が許容されないのならばtry~exceptを行うようなコードにしてください。
python 再試行、python リトライで検索するといろいろHITするかと。
1,requests.getの戻り値のレスポンスオブジェクトに対して以下のどちらかの処理をいれると、
質問文のエラーより前に問題が発見できるかと。
1-a,try~except
で囲んで、raise_for_status()
を呼び出す。 (回答者:推奨コード)
Python
1 try:
2 res = requests.get(url, params)
3 res.raise_for_status()
4 except Exception as ex:
5 LOGGER.exception(ex)
1-b,HTTPステータスコード:statuscode
をみる。
Python
1 res = requests.get(url, params)
2 print(res.status_code)
2,リトライ処理を行う。
requests
を使っているならば、from urllib3.util.retry import Retry
参考:KeyError の再試行について
3,あと相手サーバーの負荷軽減のために適度なsleepを入れてくださいな。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/08/27 18:32
2018/08/27 18:40
退会済みユーザー
2018/08/28 05:16
退会済みユーザー
2018/08/28 09:33
退会済みユーザー
2018/08/31 03:12