質問編集履歴
2
1000円以下の商品の価格が取得できなかったので修正したところ、10000文字を超えたので出力結果のURLを簡略化
test
CHANGED
File without changes
|
test
CHANGED
@@ -102,28 +102,6 @@
|
|
102
102
|
|
103
103
|
print("データをリストへ格納します: ", str(len(item_data)))
|
104
104
|
|
105
|
-
# for price in price_datas:
|
106
|
-
|
107
|
-
# print(price.prettify())
|
108
|
-
|
109
|
-
# price = item.findAll("formattedprice").string
|
110
|
-
|
111
|
-
# price = price_data.contents[0]
|
112
|
-
|
113
|
-
# pprint.pprint(price.__dict__) #__dict__メソッドを覗く
|
114
|
-
|
115
|
-
# print("価格を取得しました: ", price)
|
116
|
-
|
117
|
-
# item_data.append({
|
118
|
-
|
119
|
-
# 'price': price,
|
120
|
-
|
121
|
-
# })
|
122
|
-
|
123
|
-
# print("データをリストへ格納します", item_data)
|
124
|
-
|
125
|
-
#return (soup.prettify())
|
126
|
-
|
127
105
|
except HTTPError: #503エラーが出たら2秒後に再取得する
|
128
106
|
|
129
107
|
print("再取得しています....")
|
@@ -256,11 +234,11 @@
|
|
256
234
|
|
257
235
|
リスト(1件のデータ)を出力します....
|
258
236
|
|
259
|
-
[{'title': '独学プログラマー Python言語の基本から仕事のやり方まで', 'url': 'https://
|
260
|
-
|
261
|
-
[{'title': '独学プログラマー Python言語の基本から仕事のやり方まで', 'url': 'https://
|
262
|
-
|
263
|
-
[{'title': '独学プログラマー Python言語の基本から仕事のやり方まで', 'url': 'https:
|
237
|
+
[{'title': '独学プログラマー Python言語の基本から仕事のやり方まで', 'url': 'https://...', 'asin': '4822292274', 'price': '¥ 2,376'}]
|
238
|
+
|
239
|
+
[{'title': '独学プログラマー Python言語の基本から仕事のやり方まで', 'url': 'https://...', 'asin': '4822292274', 'price': '¥ 2,376'}]
|
240
|
+
|
241
|
+
[{'title': '独学プログラマー Python言語の基本から仕事のやり方まで', 'url': 'https:...', 'asin': '4822292274', 'price': '¥ 2,376'}]
|
264
242
|
|
265
243
|
データの取得に成功しました
|
266
244
|
|
@@ -292,7 +270,7 @@
|
|
292
270
|
|
293
271
|
|
294
272
|
|
295
|
-
出来上がったコードを下に記載しておきます!
|
273
|
+
出来上がったコードを下に記載しておきます!****
|
296
274
|
|
297
275
|
```python
|
298
276
|
|
@@ -320,7 +298,7 @@
|
|
320
298
|
|
321
299
|
item_data = []
|
322
300
|
|
323
|
-
key = input("search? >>")
|
301
|
+
key = "アフィリエイト" # input("search? >>")
|
324
302
|
|
325
303
|
|
326
304
|
|
@@ -330,7 +308,7 @@
|
|
330
308
|
|
331
309
|
while len(item_data) < 10:
|
332
310
|
|
333
|
-
print("データ
|
311
|
+
print("データを取得します...")
|
334
312
|
|
335
313
|
try:
|
336
314
|
|
@@ -358,32 +336,58 @@
|
|
358
336
|
|
359
337
|
for item in items: # 商品情報を1件ずつ取り出す
|
360
338
|
|
361
|
-
# print(item.prettify()) # itemタグを整形して表示
|
362
|
-
|
363
|
-
price_dict = item.find("amount")
|
339
|
+
price_dict = item.find("amount") # 商品の価格情報を取得
|
364
340
|
|
365
341
|
try:
|
366
342
|
|
367
343
|
price = price_dict.contents[0]
|
368
344
|
|
369
|
-
except AttributeError:
|
345
|
+
except AttributeError: # Kindleの商品の場合<amount>タグが存在しない
|
370
|
-
|
371
|
-
|
346
|
+
|
372
|
-
|
373
|
-
|
347
|
+
print("xmlに<amount>タグが記載されていないため商品価格が取得できません...再取得します...")
|
374
|
-
|
348
|
+
|
375
|
-
|
349
|
+
url = item.find('detailpageurl').text
|
376
|
-
|
350
|
+
|
377
|
-
|
351
|
+
request = requests.get(url)
|
378
|
-
|
352
|
+
|
379
|
-
|
353
|
+
soup_url = BeautifulSoup(request.content, "lxml")
|
380
|
-
|
354
|
+
|
381
|
-
|
355
|
+
text = str(soup_url.find("td", {'class':'a-color-price a-size-medium a-align-bottom'}))
|
356
|
+
|
382
|
-
|
357
|
+
try:
|
358
|
+
|
383
|
-
search = re.search(r"\s+¥(\s\d+),(\d+)\s", text) #検索パターンの
|
359
|
+
search = re.search(r"\s+¥(\s\d+),(\d+)\s", text) #検索パターンのサーチ
|
384
360
|
|
385
361
|
price = search.group(1) + search.group(2)
|
386
362
|
|
363
|
+
except AttributeError:
|
364
|
+
|
365
|
+
print("価格が1000円以下ですので、情報を再取得します...")
|
366
|
+
|
367
|
+
for i in range(10):
|
368
|
+
|
369
|
+
try:
|
370
|
+
|
371
|
+
url = item.find('detailpageurl').text
|
372
|
+
|
373
|
+
request = requests.get(url)
|
374
|
+
|
375
|
+
soup_url = BeautifulSoup(request.content, "lxml")
|
376
|
+
|
377
|
+
text = str(soup_url.find("td", {'class':'a-color-price a-size-medium a-align-bottom'}))
|
378
|
+
|
379
|
+
search = re.search(r"\s+¥(\s\d+)\s", text) #検索パターンのサーチ
|
380
|
+
|
381
|
+
price = search.group(1)
|
382
|
+
|
383
|
+
except:
|
384
|
+
|
385
|
+
print("再取得しています...({}回目)".format(i))
|
386
|
+
|
387
|
+
else:
|
388
|
+
|
389
|
+
break
|
390
|
+
|
387
391
|
print("価格を取得しました: ", price)
|
388
392
|
|
389
393
|
item_data.append({
|
@@ -398,15 +402,17 @@
|
|
398
402
|
|
399
403
|
})
|
400
404
|
|
401
|
-
print("データをリストへ格納します: ", str(len(item_data)))
|
405
|
+
print("データをリストへ格納します: ", str(len(item_data)), "\n")
|
406
|
+
|
402
|
-
|
407
|
+
except HTTPError: #503エラーが出たら2秒後に再取得する
|
408
|
+
|
403
|
-
print("再取得しています...
|
409
|
+
print("HTTPError: 再取得しています...")
|
404
410
|
|
405
411
|
time.sleep(2)
|
406
412
|
|
407
413
|
except TypeError as err: #TypeErrorが出たらエラーメッセージを出力して処理を中断する
|
408
414
|
|
409
|
-
print("TypeError:処理を中断します")
|
415
|
+
print("TypeError: 処理を中断します")
|
410
416
|
|
411
417
|
traceback.print_exc()
|
412
418
|
|
@@ -418,18 +424,18 @@
|
|
418
424
|
|
419
425
|
traceback.print_exc()
|
420
426
|
|
427
|
+
print("検索を終了します...")
|
428
|
+
|
429
|
+
break
|
430
|
+
|
431
|
+
except : #それ以外のエラー
|
432
|
+
|
433
|
+
print("エラーが発生しました")
|
434
|
+
|
435
|
+
traceback.print_exc()
|
436
|
+
|
421
437
|
print("検索を終了します....")
|
422
438
|
|
423
|
-
break
|
424
|
-
|
425
|
-
except : #それ以外のエラー
|
426
|
-
|
427
|
-
print("エラーが発生しました")
|
428
|
-
|
429
|
-
traceback.print_exc()
|
430
|
-
|
431
|
-
print("検索を終了します....")
|
432
|
-
|
433
439
|
break
|
434
440
|
|
435
441
|
print("合計{}件のデータリストに格納しました....".format(str(len(item_data))), "\n")
|
@@ -444,8 +450,6 @@
|
|
444
450
|
|
445
451
|
book_lists = getResponses()
|
446
452
|
|
447
|
-
print(book_lists)
|
448
|
-
|
449
453
|
try:
|
450
454
|
|
451
455
|
print("データの取得に成功しました", "\n", "asin・商品名・URLを出力します", "\n")
|
1
スクリプトが完成したので追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -281,3 +281,191 @@
|
|
281
281
|
|
282
282
|
|
283
283
|
対応策をご教示願います。
|
284
|
+
|
285
|
+
|
286
|
+
|
287
|
+
|
288
|
+
|
289
|
+
追記:皆様のおかげで無事に解決できました!
|
290
|
+
|
291
|
+
有難うございました!
|
292
|
+
|
293
|
+
|
294
|
+
|
295
|
+
出来上がったコードを下に記載しておきます!
|
296
|
+
|
297
|
+
```python
|
298
|
+
|
299
|
+
# -*- coding: utf-8 -*-
|
300
|
+
|
301
|
+
import bottlenose
|
302
|
+
|
303
|
+
import requests
|
304
|
+
|
305
|
+
from bs4 import BeautifulSoup
|
306
|
+
|
307
|
+
import time
|
308
|
+
|
309
|
+
import traceback
|
310
|
+
|
311
|
+
import re
|
312
|
+
|
313
|
+
from urllib.error import HTTPError
|
314
|
+
|
315
|
+
import pprint
|
316
|
+
|
317
|
+
from amazon_api import amazon
|
318
|
+
|
319
|
+
|
320
|
+
|
321
|
+
item_data = []
|
322
|
+
|
323
|
+
key = input("search? >>")
|
324
|
+
|
325
|
+
|
326
|
+
|
327
|
+
|
328
|
+
|
329
|
+
def getResponses():
|
330
|
+
|
331
|
+
while len(item_data) < 10:
|
332
|
+
|
333
|
+
print("データの取得を開始します")
|
334
|
+
|
335
|
+
try:
|
336
|
+
|
337
|
+
# xmlでレスポンスを取得
|
338
|
+
|
339
|
+
response = amazon.ItemSearch(
|
340
|
+
|
341
|
+
Keywords=str(key),
|
342
|
+
|
343
|
+
SearchIndex="All",
|
344
|
+
|
345
|
+
ItemPage='1',
|
346
|
+
|
347
|
+
ResponseGroup="Large"
|
348
|
+
|
349
|
+
)
|
350
|
+
|
351
|
+
# xmlをパース
|
352
|
+
|
353
|
+
soup = BeautifulSoup(response, "lxml")
|
354
|
+
|
355
|
+
# itemタグを子・孫要素全て含めてリストで取得
|
356
|
+
|
357
|
+
items = soup.findAll("item")
|
358
|
+
|
359
|
+
for item in items: # 商品情報を1件ずつ取り出す
|
360
|
+
|
361
|
+
# print(item.prettify()) # itemタグを整形して表示
|
362
|
+
|
363
|
+
price_dict = item.find("amount")
|
364
|
+
|
365
|
+
try:
|
366
|
+
|
367
|
+
price = price_dict.contents[0]
|
368
|
+
|
369
|
+
except AttributeError:
|
370
|
+
|
371
|
+
if price_dict is None:
|
372
|
+
|
373
|
+
print("xmlに値段が記載されていません・再取得します")
|
374
|
+
|
375
|
+
url = item.find('detailpageurl').text #
|
376
|
+
|
377
|
+
request = requests.get(url)
|
378
|
+
|
379
|
+
soup_url = BeautifulSoup(request.content, "lxml")
|
380
|
+
|
381
|
+
text = str(soup_url.find("td", {'class':'a-color-price a-size-medium a-align-bottom'}))
|
382
|
+
|
383
|
+
search = re.search(r"\s+¥(\s\d+),(\d+)\s", text) #検索パターンのコンパイル
|
384
|
+
|
385
|
+
price = search.group(1) + search.group(2)
|
386
|
+
|
387
|
+
print("価格を取得しました: ", price)
|
388
|
+
|
389
|
+
item_data.append({
|
390
|
+
|
391
|
+
'asin': item.find('asin').text,
|
392
|
+
|
393
|
+
'title': item.find('title').text,
|
394
|
+
|
395
|
+
"price": price,
|
396
|
+
|
397
|
+
'url': item.find('detailpageurl').text
|
398
|
+
|
399
|
+
})
|
400
|
+
|
401
|
+
print("データをリストへ格納します: ", str(len(item_data)))
|
402
|
+
|
403
|
+
print("再取得しています....")
|
404
|
+
|
405
|
+
time.sleep(2)
|
406
|
+
|
407
|
+
except TypeError as err: #TypeErrorが出たらエラーメッセージを出力して処理を中断する
|
408
|
+
|
409
|
+
print("TypeError:処理を中断します")
|
410
|
+
|
411
|
+
traceback.print_exc()
|
412
|
+
|
413
|
+
break
|
414
|
+
|
415
|
+
except AttributeError as err: #パースの仕方に問題があるとき
|
416
|
+
|
417
|
+
print("パースの仕方に問題があります")
|
418
|
+
|
419
|
+
traceback.print_exc()
|
420
|
+
|
421
|
+
print("検索を終了します....")
|
422
|
+
|
423
|
+
break
|
424
|
+
|
425
|
+
except : #それ以外のエラー
|
426
|
+
|
427
|
+
print("エラーが発生しました")
|
428
|
+
|
429
|
+
traceback.print_exc()
|
430
|
+
|
431
|
+
print("検索を終了します....")
|
432
|
+
|
433
|
+
break
|
434
|
+
|
435
|
+
print("合計{}件のデータリストに格納しました....".format(str(len(item_data))), "\n")
|
436
|
+
|
437
|
+
return item_data
|
438
|
+
|
439
|
+
|
440
|
+
|
441
|
+
|
442
|
+
|
443
|
+
if __name__ == '__main__':
|
444
|
+
|
445
|
+
book_lists = getResponses()
|
446
|
+
|
447
|
+
print(book_lists)
|
448
|
+
|
449
|
+
try:
|
450
|
+
|
451
|
+
print("データの取得に成功しました", "\n", "asin・商品名・URLを出力します", "\n")
|
452
|
+
|
453
|
+
for book_dicts in book_lists:
|
454
|
+
|
455
|
+
print("asin: ", book_dicts["asin"])
|
456
|
+
|
457
|
+
print("title: ", book_dicts["title"])
|
458
|
+
|
459
|
+
print("price: ", book_dicts["price"])
|
460
|
+
|
461
|
+
print("url: ", book_dicts["url"])
|
462
|
+
|
463
|
+
print("\t")
|
464
|
+
|
465
|
+
except TypeError as err:
|
466
|
+
|
467
|
+
print(err)
|
468
|
+
|
469
|
+
print("処理を終了します....")
|
470
|
+
|
471
|
+
```
|