teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

2

1000円以下の商品の価格が取得できなかったので修正したところ、10000文字を超えたので出力結果のURLを簡略化

2018/02/17 08:02

投稿

nokonoko_1203
nokonoko_1203

スコア17

title CHANGED
File without changes
body CHANGED
@@ -50,17 +50,6 @@
50
50
  'url': item.find('detailpageurl').text
51
51
  })
52
52
  print("データをリストへ格納します: ", str(len(item_data)))
53
- # for price in price_datas:
54
- # print(price.prettify())
55
- # price = item.findAll("formattedprice").string
56
- # price = price_data.contents[0]
57
- # pprint.pprint(price.__dict__) #__dict__メソッドを覗く
58
- # print("価格を取得しました: ", price)
59
- # item_data.append({
60
- # 'price': price,
61
- # })
62
- # print("データをリストへ格納します", item_data)
63
- #return (soup.prettify())
64
53
  except HTTPError: #503エラーが出たら2秒後に再取得する
65
54
  print("再取得しています....")
66
55
  time.sleep(2)
@@ -127,9 +116,9 @@
127
116
  AttributeError: 'NoneType' object has no attribute 'contents'
128
117
  検索を終了します....
129
118
  リスト(1件のデータ)を出力します....
130
- [{'title': '独学プログラマー Python言語の基本から仕事のやり方まで', 'url': 'https://www.amazon.co.jp/%E7%8B%AC%E5%AD%A6%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC-Python%E8%A8%80%E8%AA%9E%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%8B%E3%82%89%E4%BB%95%E4%BA%8B%E3%81%AE%E3%82%84%E3%82%8A%E6%96%B9%E3%81%BE%E3%81%A7-%E3%82%B3%E3%83%BC%E3%83%AA%E3%83%BC%E3%83%BB%E3%82%A2%E3%83%AB%E3%82%BD%E3%83%95/dp/4822292274?SubscriptionId=AKIAIOE4UGAEQ6QGR3RA&tag=nokonoko1200e-22&linkCode=xm2&camp=2025&creative=165953&creativeASIN=4822292274', 'asin': '4822292274', 'price': '¥ 2,376'}]
131
- [{'title': '独学プログラマー Python言語の基本から仕事のやり方まで', 'url': 'https://www.amazon.co.jp/%E7%8B%AC%E5%AD%A6%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC-Python%E8%A8%80%E8%AA%9E%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%8B%E3%82%89%E4%BB%95%E4%BA%8B%E3%81%AE%E3%82%84%E3%82%8A%E6%96%B9%E3%81%BE%E3%81%A7-%E3%82%B3%E3%83%BC%E3%83%AA%E3%83%BC%E3%83%BB%E3%82%A2%E3%83%AB%E3%82%BD%E3%83%95/dp/4822292274?SubscriptionId=AKIAIOE4UGAEQ6QGR3RA&tag=nokonoko1200e-22&linkCode=xm2&camp=2025&creative=165953&creativeASIN=4822292274', 'asin': '4822292274', 'price': '¥ 2,376'}]
132
- [{'title': '独学プログラマー Python言語の基本から仕事のやり方まで', 'url': 'https://www.amazon.co.jp/%E7%8B%AC%E5%AD%A6%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC-Python%E8%A8%80%E8%AA%9E%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%8B%E3%82%89%E4%BB%95%E4%BA%8B%E3%81%AE%E3%82%84%E3%82%8A%E6%96%B9%E3%81%BE%E3%81%A7-%E3%82%B3%E3%83%BC%E3%83%AA%E3%83%BC%E3%83%BB%E3%82%A2%E3%83%AB%E3%82%BD%E3%83%95/dp/4822292274?SubscriptionId=AKIAIOE4UGAEQ6QGR3RA&tag=nokonoko1200e-22&linkCode=xm2&camp=2025&creative=165953&creativeASIN=4822292274', 'asin': '4822292274', 'price': '¥ 2,376'}]
119
+ [{'title': '独学プログラマー Python言語の基本から仕事のやり方まで', 'url': 'https://...', 'asin': '4822292274', 'price': '¥ 2,376'}]
120
+ [{'title': '独学プログラマー Python言語の基本から仕事のやり方まで', 'url': 'https://...', 'asin': '4822292274', 'price': '¥ 2,376'}]
121
+ [{'title': '独学プログラマー Python言語の基本から仕事のやり方まで', 'url': 'https:...', 'asin': '4822292274', 'price': '¥ 2,376'}]
133
122
  データの取得に成功しました
134
123
  asin・商品名・URLを出力します
135
124
 
@@ -145,7 +134,7 @@
145
134
  追記:皆様のおかげで無事に解決できました!
146
135
  有難うございました!
147
136
 
148
- 出来上がったコードを下に記載しておきます!
137
+ 出来上がったコードを下に記載しておきます!****
149
138
  ```python
150
139
  # -*- coding: utf-8 -*-
151
140
  import bottlenose
@@ -159,12 +148,12 @@
159
148
  from amazon_api import amazon
160
149
 
161
150
  item_data = []
162
- key = input("search? >>")
151
+ key = "アフィリエイト" # input("search? >>")
163
152
 
164
153
 
165
154
  def getResponses():
166
155
  while len(item_data) < 10:
167
- print("データ取得を開始します")
156
+ print("データ取得します...")
168
157
  try:
169
158
  # xmlでレスポンスを取得
170
159
  response = amazon.ItemSearch(
@@ -178,19 +167,32 @@
178
167
  # itemタグを子・孫要素全て含めてリストで取得
179
168
  items = soup.findAll("item")
180
169
  for item in items: # 商品情報を1件ずつ取り出す
181
- # print(item.prettify()) # itemタグを整形して表示
182
- price_dict = item.find("amount")
170
+ price_dict = item.find("amount") # 商品の価格情報を取得
183
171
  try:
184
172
  price = price_dict.contents[0]
185
- except AttributeError:
173
+ except AttributeError: # Kindleの商品の場合<amount>タグが存在しない
186
- if price_dict is None:
187
- print("xmlに値段が記載されていません再取得します")
174
+ print("xmlに<amount>タグが記載されていないため商品価格が取得できません...再取得します...")
188
- url = item.find('detailpageurl').text #
175
+ url = item.find('detailpageurl').text
189
- request = requests.get(url)
176
+ request = requests.get(url)
190
- soup_url = BeautifulSoup(request.content, "lxml")
177
+ soup_url = BeautifulSoup(request.content, "lxml")
191
- text = str(soup_url.find("td", {'class':'a-color-price a-size-medium a-align-bottom'}))
178
+ text = str(soup_url.find("td", {'class':'a-color-price a-size-medium a-align-bottom'}))
179
+ try:
192
- search = re.search(r"\s+¥(\s\d+),(\d+)\s", text) #検索パターンのコンパイル
180
+ search = re.search(r"\s+¥(\s\d+),(\d+)\s", text) #検索パターンのサーチ
193
181
  price = search.group(1) + search.group(2)
182
+ except AttributeError:
183
+ print("価格が1000円以下ですので、情報を再取得します...")
184
+ for i in range(10):
185
+ try:
186
+ url = item.find('detailpageurl').text
187
+ request = requests.get(url)
188
+ soup_url = BeautifulSoup(request.content, "lxml")
189
+ text = str(soup_url.find("td", {'class':'a-color-price a-size-medium a-align-bottom'}))
190
+ search = re.search(r"\s+¥(\s\d+)\s", text) #検索パターンのサーチ
191
+ price = search.group(1)
192
+ except:
193
+ print("再取得しています...({}回目)".format(i))
194
+ else:
195
+ break
194
196
  print("価格を取得しました: ", price)
195
197
  item_data.append({
196
198
  'asin': item.find('asin').text,
@@ -198,17 +200,18 @@
198
200
  "price": price,
199
201
  'url': item.find('detailpageurl').text
200
202
  })
201
- print("データをリストへ格納します: ", str(len(item_data)))
203
+ print("データをリストへ格納します: ", str(len(item_data)), "\n")
204
+ except HTTPError: #503エラーが出たら2秒後に再取得する
202
- print("再取得しています....")
205
+ print("HTTPError: 再取得しています...")
203
206
  time.sleep(2)
204
207
  except TypeError as err: #TypeErrorが出たらエラーメッセージを出力して処理を中断する
205
- print("TypeError:処理を中断します")
208
+ print("TypeError: 処理を中断します")
206
209
  traceback.print_exc()
207
210
  break
208
211
  except AttributeError as err: #パースの仕方に問題があるとき
209
212
  print("パースの仕方に問題があります")
210
213
  traceback.print_exc()
211
- print("検索を終了します....")
214
+ print("検索を終了します...")
212
215
  break
213
216
  except : #それ以外のエラー
214
217
  print("エラーが発生しました")
@@ -221,7 +224,6 @@
221
224
 
222
225
  if __name__ == '__main__':
223
226
  book_lists = getResponses()
224
- print(book_lists)
225
227
  try:
226
228
  print("データの取得に成功しました", "\n", "asin・商品名・URLを出力します", "\n")
227
229
  for book_dicts in book_lists:

1

スクリプトが完成したので追記

2018/02/17 08:02

投稿

nokonoko_1203
nokonoko_1203

スコア17

title CHANGED
File without changes
body CHANGED
@@ -139,4 +139,98 @@
139
139
 
140
140
  ```
141
141
 
142
- 対応策をご教示願います。
142
+ 対応策をご教示願います。
143
+
144
+
145
+ 追記:皆様のおかげで無事に解決できました!
146
+ 有難うございました!
147
+
148
+ 出来上がったコードを下に記載しておきます!
149
+ ```python
150
+ # -*- coding: utf-8 -*-
151
+ import bottlenose
152
+ import requests
153
+ from bs4 import BeautifulSoup
154
+ import time
155
+ import traceback
156
+ import re
157
+ from urllib.error import HTTPError
158
+ import pprint
159
+ from amazon_api import amazon
160
+
161
+ item_data = []
162
+ key = input("search? >>")
163
+
164
+
165
+ def getResponses():
166
+ while len(item_data) < 10:
167
+ print("データの取得を開始します")
168
+ try:
169
+ # xmlでレスポンスを取得
170
+ response = amazon.ItemSearch(
171
+ Keywords=str(key),
172
+ SearchIndex="All",
173
+ ItemPage='1',
174
+ ResponseGroup="Large"
175
+ )
176
+ # xmlをパース
177
+ soup = BeautifulSoup(response, "lxml")
178
+ # itemタグを子・孫要素全て含めてリストで取得
179
+ items = soup.findAll("item")
180
+ for item in items: # 商品情報を1件ずつ取り出す
181
+ # print(item.prettify()) # itemタグを整形して表示
182
+ price_dict = item.find("amount")
183
+ try:
184
+ price = price_dict.contents[0]
185
+ except AttributeError:
186
+ if price_dict is None:
187
+ print("xmlに値段が記載されていません・再取得します")
188
+ url = item.find('detailpageurl').text #
189
+ request = requests.get(url)
190
+ soup_url = BeautifulSoup(request.content, "lxml")
191
+ text = str(soup_url.find("td", {'class':'a-color-price a-size-medium a-align-bottom'}))
192
+ search = re.search(r"\s+¥(\s\d+),(\d+)\s", text) #検索パターンのコンパイル
193
+ price = search.group(1) + search.group(2)
194
+ print("価格を取得しました: ", price)
195
+ item_data.append({
196
+ 'asin': item.find('asin').text,
197
+ 'title': item.find('title').text,
198
+ "price": price,
199
+ 'url': item.find('detailpageurl').text
200
+ })
201
+ print("データをリストへ格納します: ", str(len(item_data)))
202
+ print("再取得しています....")
203
+ time.sleep(2)
204
+ except TypeError as err: #TypeErrorが出たらエラーメッセージを出力して処理を中断する
205
+ print("TypeError:処理を中断します")
206
+ traceback.print_exc()
207
+ break
208
+ except AttributeError as err: #パースの仕方に問題があるとき
209
+ print("パースの仕方に問題があります")
210
+ traceback.print_exc()
211
+ print("検索を終了します....")
212
+ break
213
+ except : #それ以外のエラー
214
+ print("エラーが発生しました")
215
+ traceback.print_exc()
216
+ print("検索を終了します....")
217
+ break
218
+ print("合計{}件のデータリストに格納しました....".format(str(len(item_data))), "\n")
219
+ return item_data
220
+
221
+
222
+ if __name__ == '__main__':
223
+ book_lists = getResponses()
224
+ print(book_lists)
225
+ try:
226
+ print("データの取得に成功しました", "\n", "asin・商品名・URLを出力します", "\n")
227
+ for book_dicts in book_lists:
228
+ print("asin: ", book_dicts["asin"])
229
+ print("title: ", book_dicts["title"])
230
+ print("price: ", book_dicts["price"])
231
+ print("url: ", book_dicts["url"])
232
+ print("\t")
233
+ except TypeError as err:
234
+ print(err)
235
+ print("処理を終了します....")
236
+ ```