質問編集履歴

4

タイトルを変更しました

2019/07/02 07:25

投稿

nasu0922
nasu0922

スコア17

test CHANGED
@@ -1 +1 @@
1
- WEBスクレイピング beautifulsoup4 情報取得できずにルプが抜ける問題
1
+ WEBスクレイピング beautifulsoup4 ページを変遷し情報取得するもペジを残し終わってしまう
test CHANGED
File without changes

3

実現したいこと、問題点等わかりやすく修正しました。また、ソースコードも余計なものは省きました

2019/07/02 07:25

投稿

nasu0922
nasu0922

スコア17

test CHANGED
File without changes
test CHANGED
@@ -1,289 +1,199 @@
1
1
  ### 前提・実現したいこと
2
2
 
3
- DMMぱちタウンからスロットの遊技機情報をWEBスクレイピングで取得し、CSV出力をしようとソースコードを作成しております
3
+ DMMぱちタウンからスロットの遊技機情報をWEBスクレイピングで取得したい
4
-
5
- ■実現したいこと
4
+
6
-
7
- スロットの全機種の情報取得(メーカーID、メーカ名、機種ID、機種名~機種概要)
5
+ スロットの全機種の情報取得(メーカーID、メーカ名、機種ID、機種名~機種概要)
8
-
6
+
9
- CSVファルに保存
7
+ <取得メージ>
8
+
10
-
9
+ 1.3491:https://p-town.dmm.com/machines/3491
10
+
11
+ [['3491', 'タマどき!', '4', 'JPS', '97.2%〜105.6%', '2019/10上旬予定', 'コンサートホールグループでのみ打つことができるオリジナルパチスロが、この『タマどき!』。擬似ボーナスを搭載したAT機となっており、リール左右の花が
12
+
13
+ 光ればボーナス確定だ。ボーナス後の32G間はボーナスの引き戻しに期待でき、最大ループ率は約90%と大量出玉への期待が膨らむ仕様となっている。花の光り方で滞在モードを示唆しているので、ここにも注目しておこう。', '']]・・・以下続く
14
+
15
+
16
+
11
- できていること
17
+ ###できていること
12
-
13
- 機種情報の取得~CSVファイル保存まで。
18
+
14
-
15
- ただし400機種分までしか取得できていないです。
19
+ 上記イメージ通りスロット機種情報の取得できていす。
20
+
21
+
22
+
16
-
23
+ ###できていないこと
24
+
25
+ ループはできていますが、400機種目(20ページ目の最後の機種)で終わってしまいます。
26
+
27
+
28
+
17
- ■解決したいこと
29
+ ### 実現したいこと
18
-
19
- スロット全機種の情報取得~CSVファイル保存までです。エラーが出ていませんが400機種で処理が終わってしまいます。
30
+
20
-
21
- プ処理がうまくいってないょうか
31
+ 全ペジを横断し、スロット全機種情報を取得たい
22
-
23
-
24
-
25
- ご協力お願いいたします。
26
-
27
-
28
-
29
- ### 発生している問題・エラーメッセージ
30
32
 
31
33
  エラーも特に出ていませんが、400機種を取得後にループを抜けて処理が終わってしまい、対応策が見つからず苦慮しております。
32
34
 
35
+ ### 該当のソースコード(余計なものは省きました)
36
+
37
+ ```python3
38
+
39
+ import requests
40
+
41
+ import random
42
+
43
+ import time
44
+
45
+ import re
46
+
47
+ from bs4 import BeautifulSoup
48
+
49
+
50
+
51
+ if __name__ == "__main__":
52
+
53
+
54
+
55
+ #requestsを使って、webから取得
56
+
57
+ base_url = 'https://p-town.dmm.com/machines'
58
+
59
+ target_url = '/slot'
60
+
61
+ r = requests.get(base_url + target_url)
62
+
63
+ soup = BeautifulSoup(r.text, 'lxml')
64
+
65
+
66
+
67
+ # データカラム定義
68
+
69
+ col_list = ['機種ID', '機種名', 'メーカーID', 'メーカー名', '機械割', '導入開始日', '機種概要', '取得日時']
70
+
71
+ num = 0
72
+
73
+ csv_list = []
74
+
75
+ #機種IDループ
76
+
77
+ for link_ in soup.find_all('a', class_='link', href=re.compile(r'/machines/' + '\d+')):
78
+
79
+ machine_url = link_.attrs.get('href')
80
+
81
+ machine_id = machine_url.rsplit('/', 1)[1]
82
+
83
+ selector = 'body > div.o-layout > div > div > main > section li'
84
+
85
+ nextpage = True
86
+
87
+ while nextpage:
88
+
89
+ # 次ページ有無チェック
90
+
91
+ for pages_ in soup.select(selector):
92
+
93
+ if pages_.attrs.get('class')[0] == 'item':
94
+
95
+ if pages_.text == '>':
96
+
97
+ if pages_.get('href') is not None:
98
+
99
+ nextpage = True
100
+
101
+ break
102
+
103
+ else:
104
+
105
+ nextpage = False
106
+
107
+ # 遊技機情報ループ
108
+
109
+ for pages_ in soup.select(selector):
110
+
111
+ machine_list = ['','','','','','','','']
112
+
113
+ if pages_.attrs.get('class')[0] == 'unit':
114
+
115
+ num += 1
116
+
117
+ target_url = pages_.next_element.attrs.get('href')
118
+
119
+ machine_id = target_url.rsplit('/', 1)[1]
120
+
121
+ machine_list[0] = machine_id
122
+
123
+ time.sleep(random.randint(1, 3)) #スリープ(1秒~3秒)
124
+
125
+ r2 = requests.get(base_url + '/' + machine_id)
126
+
127
+ soup2 = BeautifulSoup(r2.text, 'lxml')
128
+
129
+ print(str(num)+ '.'+ machine_id + ':' + base_url + '/' + machine_id)
130
+
131
+ #機種名取得
132
+
133
+ for title in soup2.select('h1[class="title"]'):
134
+
135
+ machine_name = title.get_text(strip=True)
136
+
137
+ machine_list[1] = machine_name
138
+
139
+ for tr in soup2.select('table[class="default-table"] tr'):
140
+
141
+ # 'tr'要素から'th'をpopして項目名を取得
142
+
143
+ th_ = tr.find_all("th").pop(0).get_text(strip=True).upper()
144
+
145
+ # 'tr'要素から'td'をpopしてデータを取得
146
+
147
+ td_ = tr.find_all("td").pop(0).get_text(strip=True)
148
+
149
+ if th_ == 'メーカー名':
150
+
151
+ try:
152
+
153
+ makers = tr.find_all('a', class_='textlink').pop(0).attrs['href']
154
+
155
+ makers = makers.rsplit('/', 1)[1]
156
+
157
+ except IndexError:
158
+
159
+ makers = -1
160
+
161
+ machine_list[2] = makers
162
+
163
+ machine_list[col_list.index(th_)] = td_
164
+
165
+ csv_list.append(machine_list)
166
+
167
+ #print(csv_list)
168
+
169
+ # 次ページ読込、なければループ終了
170
+
171
+ elif pages_.attrs.get('class')[0] == 'item':
172
+
173
+ if pages_.text == '>':
174
+
175
+ if pages_.next.attrs.get('href') is not None:
176
+
177
+ target_url = pages_.next.attrs.get('href')
178
+
179
+ r = requests.get(target_url)
180
+
181
+ soup = BeautifulSoup(r.text, 'lxml')
182
+
183
+ else:
184
+
185
+ nextpage = False
186
+
187
+ break
188
+
189
+
190
+
33
191
  ```
34
192
 
35
193
 
36
194
 
37
- ```
38
-
39
- ### 該当のソースコード
40
-
41
-
42
-
43
- ```python3
44
-
45
- import requests
46
-
47
- import logging
48
-
49
- import random
50
-
51
- import time
52
-
53
- import re
54
-
55
- import csv
56
-
57
- from bs4 import BeautifulSoup
58
-
59
- from os import chdir, path
60
-
61
- from datetime import datetime, timedelta, timezone
62
-
63
-
64
-
65
- if __name__ == "__main__":
66
-
67
-
68
-
69
- # タイムゾーンの生成
70
-
71
- JST = timezone(timedelta(hours=+9), 'JST')
72
-
73
-
74
-
75
- # カレントディレクトリをスクリプトパスに変更
76
-
77
- chdir(path.dirname(__file__))
78
-
79
-
80
-
81
- # ベースとなる出力ファイル名を定義
82
-
83
- out_file_base = path.splitext(path.basename(__file__))[0]
84
-
85
- out_file_base = out_file_base + '_{0:%Y%m%d}_{0:%H%M%S}'.format(datetime.now(JST))
86
-
87
-
88
-
89
- # ログファイル名を定義
90
-
91
- log_file_name = path.splitext(path.basename(__file__))[0] + '_log'
92
-
93
- log_file_name = log_file_name + '_{0:%Y%m%d}'.format(datetime.now(JST)) + '.log'
94
-
95
- # フォーマットを定義
96
-
97
- formatter = '%(asctime)s : %(levelname)s : %(message)s'
98
-
99
- # ログレベルを DEBUG に変更
100
-
101
- #logging.basicConfig(level=logging.DEBUG)
102
-
103
- logging.basicConfig(format=formatter, filename=log_file_name, level=logging.INFO)
104
-
105
- #logging.basicConfig(level=logging.DEBUG, format=formatter)
106
-
107
-
108
-
109
- # User-Agent をIE11に偽装する
110
-
111
- headers = {
112
-
113
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko'
114
-
115
- }
116
-
117
-
118
-
119
- #requestsを使って、webから取得
120
-
121
- base_url = 'https://p-town.dmm.com/machines'
122
-
123
- target_url = '/slot'
124
-
125
- r = requests.get(base_url + target_url, headers=headers)
126
-
127
- soup = BeautifulSoup(r.text, 'lxml')
128
-
129
-
130
-
131
- # データカラム定義
132
-
133
- col_list = ['機種ID', '機種名', 'メーカーID', 'メーカー名', '機械割', '導入開始日', '機種概要', '取得日時']
134
-
135
- num = 0
136
-
137
- csv_list = []
138
-
139
- #機種IDループ
140
-
141
- for link_ in soup.find_all('a', class_='link', href=re.compile(r'/machines/' + '\d+')):
142
-
143
- #csv_list = []
144
-
145
- machine_url = link_.attrs.get('href')
146
-
147
- machine_id = machine_url.rsplit('/', 1)[1]
148
-
149
- logging.info('%s %s', '[' + machine_id + ']:', base_url + '/' + machine_id)
150
-
151
- selector = 'body > div.o-layout > div > div > main > section li'
152
-
153
- nextpage = True
154
-
155
- while nextpage:
156
-
157
- # 次ページ有無チェック
158
-
159
- for pages_ in soup.select(selector):
160
-
161
- if pages_.attrs.get('class')[0] == 'item':
162
-
163
- if pages_.text == '>':
164
-
165
- if pages_.get('href') is not None:
166
-
167
- nextpage = True
168
-
169
- break
170
-
171
- else:
172
-
173
- nextpage = False
174
-
175
- # 遊技機情報ループ
176
-
177
- for pages_ in soup.select(selector):
178
-
179
- machine_list = ['','','','','','','','']
180
-
181
- if pages_.attrs.get('class')[0] == 'unit':
182
-
183
- num += 1
184
-
185
- target_url = pages_.next_element.attrs.get('href')
186
-
187
- machine_id = target_url.rsplit('/', 1)[1]
188
-
189
- machine_list[0] = machine_id
190
-
191
- time.sleep(random.randint(1, 3)) #スリープ(1秒~3秒)
192
-
193
- r2 = requests.get(base_url + '/' + machine_id, headers=headers)
194
-
195
- get_date = datetime.now(JST)
196
-
197
- soup2 = BeautifulSoup(r2.text, 'lxml')
198
-
199
- logging.info('%s %s', str(num) + '[' + machine_id + ']:', base_url + '/' + machine_id)
200
-
201
- print(str(num)+ '.'+ machine_id + ':' + base_url + '/' + machine_id)
202
-
203
- #機種名取得
204
-
205
- for title in soup2.select('h1[class="title"]'):
206
-
207
- machine_name = title.get_text(strip=True)
208
-
209
- machine_list[1] = machine_name
210
-
211
- for tr in soup2.select('table[class="default-table"] tr'):
212
-
213
- # 'tr'要素から'th'をpopして項目名を取得
214
-
215
- th_ = tr.find_all("th").pop(0).get_text(strip=True).upper()
216
-
217
- # 'tr'要素から'td'をpopしてデータを取得
218
-
219
- td_ = tr.find_all("td").pop(0).get_text(strip=True)
220
-
221
- if th_ == 'メーカー名':
222
-
223
- try:
224
-
225
- makers = tr.find_all('a', class_='textlink').pop(0).attrs['href']
226
-
227
- makers = makers.rsplit('/', 1)[1]
228
-
229
- except IndexError:
230
-
231
- makers = -1
232
-
233
- machine_list[2] = makers
234
-
235
- machine_list[col_list.index(th_)] = td_
236
-
237
- machine_list[col_list.index('取得日時')] = get_date.strftime('%Y-%m-%dT%H:%M:%S%z')
238
-
239
- csv_list.append(machine_list)
240
-
241
- #print(csv_list)
242
-
243
- # 次ページ読込、なければループ終了
244
-
245
- elif pages_.attrs.get('class')[0] == 'item':
246
-
247
- if pages_.text == '>':
248
-
249
- if pages_.next.attrs.get('href') is not None:
250
-
251
- target_url = pages_.next.attrs.get('href')
252
-
253
- r = requests.get(target_url, headers=headers)
254
-
255
- soup = BeautifulSoup(r.text, 'lxml')
256
-
257
- else:
258
-
259
- nextpage = False
260
-
261
- break
262
-
263
- # CSVファイル出力
264
-
265
- csv_file = out_file_base + '_' + '.csv'
266
-
267
- csvFields = col_list
268
-
269
- with open(csv_file, 'w', newline='', errors='replace', encoding='sjis') as f:
270
-
271
- writer = csv.writer(f, quoting=csv.QUOTE_NONNUMERIC)
272
-
273
- writer.writerow(csvFields)
274
-
275
- writer.writerows(csv_list)
276
-
277
-
278
-
279
- ```
280
-
281
-
282
-
283
195
  ### 試したこと
284
196
 
285
-
286
-
287
197
  スロット機種情報の20ページ目に何か原因があると思い、20ページ目から情報を取得したところ、特に問題なくループしたので
288
198
 
289
199
  ページそのものに何かあるわけではなさそうです。

2

2019/07/02 07:20

投稿

nasu0922
nasu0922

スコア17

test CHANGED
File without changes
test CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  DMMぱちタウンからスロットの遊技機情報をWEBスクレイピングで取得し、CSV出力をしようとソースコードを作成しております。
4
4
 
5
+ ■実現したいこと
6
+
7
+ スロットの全機種の情報取得(メーカーID、メーカ名、機種ID、機種名~機種概要)
8
+
9
+ CSVファイルに保存
10
+
11
+ ■できていること
12
+
13
+ 機種情報の取得~CSVファイル保存まで。
14
+
15
+ ただし、400機種分までしか取得できていないです。
16
+
17
+ ■解決したいこと
18
+
19
+ スロット全機種の情報取得~CSVファイル保存までです。エラーが出ていませんが400機種で処理が終わってしまいます。
20
+
21
+ ループ処理がうまくいってないのでしょうか。
22
+
23
+
24
+
25
+ ご協力お願いいたします。
26
+
27
+
28
+
5
29
  ### 発生している問題・エラーメッセージ
6
30
 
7
31
  エラーも特に出ていませんが、400機種を取得後にループを抜けて処理が終わってしまい、対応策が見つからず苦慮しております。

1

誤字を修正いたしました。

2019/06/29 04:04

投稿

nasu0922
nasu0922

スコア17

test CHANGED
File without changes
test CHANGED
@@ -1,6 +1,6 @@
1
1
  ### 前提・実現したいこと
2
2
 
3
- DMMぱちタウンからスロットの遊技機情報をWEBスクレイピングで取得し、CSV出力をしようソースコードを作成しております。
3
+ DMMぱちタウンからスロットの遊技機情報をWEBスクレイピングで取得し、CSV出力をしようソースコードを作成しております。
4
4
 
5
5
  ### 発生している問題・エラーメッセージ
6
6