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

回答編集履歴

4

軽微な修正

2020/08/13 06:13

投稿

nto
nto

スコア1438

answer CHANGED
@@ -54,27 +54,27 @@
54
54
  res = requests.get(url)
55
55
  self.soup = BeautifulSoup(res.content, 'html.parser')
56
56
  self.query = res.url[len(domain):]
57
+ if not self.soup.find('li', string='レビューの投稿はありません'):
57
- self.spread_writes()
58
+ self.spread_writes()
58
59
 
60
+
59
61
  def spread_writes(self):
60
62
  elems = ["#breadcrumb ul.cf li:nth-of-type(3)", "#breadcrumb ul.cf li:nth-of-type(4)",
61
63
  '.review_review_text', '.review_info', ".product_rep"]
62
- if self.soup.find('li', string='レビューの投稿はありません'):
63
- return
64
- else:
65
- elements = [self.soup.select(e) for e in elems]
66
- area = elements[0][0].string
67
- item = elements[1][0].string
68
- postdates = elements[3]
69
- comments = elements[2]
70
- reviews = elements[4]
71
- cnt = 1
72
- for pd, cmt, rv in tqdm(zip(postdates, comments, reviews), total=len(postdates), desc=f'id{self.pageid} page{self.pagenum} writing', leave=False):
73
- rv = rv.i["class"][0].replace('rep_','').replace('_','.')
74
- datas = [area, item, pd.text, cmt.text, rv]
75
- worksheet.append_row(datas)
76
- time.sleep(0.8)
77
64
 
65
+ elements = [self.soup.select(e) for e in elems]
66
+ area = elements[0][0].string
67
+ item = elements[1][0].string
68
+ postdates = elements[3]
69
+ comments = elements[2]
70
+ reviews = elements[4]
71
+ cnt = 1
72
+ for pd, cmt, rv in tqdm(zip(postdates, comments, reviews), total=len(postdates), desc=f'id{self.pageid} page{self.pagenum} writing', leave=False):
73
+ rv = rv.i["class"][0].replace('rep_','').replace('_','.')
74
+ datas = [area, item, pd.text, cmt.text, rv]
75
+ worksheet.append_row(datas)
76
+ time.sleep(0.8)
77
+
78
78
  if self.soup.find('a', string='次へ').get('href') != self.query:
79
79
  self.pagenum += 1
80
80
  self.pagedata_create()

3

追記

2020/08/13 06:13

投稿

nto
nto

スコア1438

answer CHANGED
@@ -32,8 +32,8 @@
32
32
  from oauth2client.service_account import ServiceAccountCredentials
33
33
  import gspread
34
34
  import time
35
+ from tqdm import tqdm
35
36
 
36
-
37
37
  scope = ['https://spreadsheets.google.com/feeds',
38
38
  'https://www.googleapis.com/auth/drive']
39
39
  credentials = ServiceAccountCredentials.from_json_keyfile_name('ファイル名.json', scope)

2

追記

2020/08/13 04:28

投稿

nto
nto

スコア1438

answer CHANGED
@@ -9,11 +9,23 @@
9
9
 
10
10
 
11
11
  ### 追記
12
- ある程度を纏めました。
12
+ て修正致しました。
13
- 以下でご所望の形でプレッドシートに追記していく事が出来るいま
13
+ クラしてしま、for文で回すという形を取りした
14
+ 大半は前回の追記と変わりませんが、classを使用する事で次のページへの遷移を楽にしました。
15
+ **次のページへのリンクURLと、現在開いているページURLが異なる**(次のページがある)といった場合に
14
- 他に質問されいてた最終の追加でが`append_row()`最終行の次の行に書き込みする事が出来ます。
16
+ `self.pagenum += 1`とし、もう一度`self.pagedata_create`行する事で次のページへの遷移実現しております。
15
17
 
16
18
 
19
+ また、件数が膨大になってしまう事を懸念し勝手ながら`tqdm`で進捗状況を計れる様にしました。
20
+ (ご不要の場合には`zip(postdates, comments, reviews)`とし、tqdm内オプションを取り外して下さい。)
21
+
22
+ スプレッドシートへの書き込みですが
23
+ API側で書き込みが出来る件数が定められている様です。(通常は100秒に100件まで)
24
+ ネット環境にも依存すると思いますがtime.sleep()での制御を任意で調整して下さい。
25
+ tqdmによるプログレスバーにて1件あたりの書き込みに何秒が要しているか確認ができます。
26
+ 1.1~1.2sec程度になる様に抑えてあげるといいでしょう。
27
+ 1.0~1.1secで設定するとたまに書き込み制限されてしまいエラーで弾かれてしまいます。
28
+
17
29
  ```python
18
30
  import requests
19
31
  from bs4 import BeautifulSoup
@@ -28,33 +40,48 @@
28
40
  gc = gspread.authorize(credentials)
29
41
  SPREADSHEET_KEY = 'スプレッドシートキー'
30
42
  worksheet = gc.open_by_key(SPREADSHEET_KEY).sheet1
43
+ domain = 'https://furunavi.jp'
31
44
 
32
45
 
46
+ class Main:
33
- def sample(pageid):
47
+ def __init__(self, pageid):
48
+ self.pageid = pageid
49
+ self.pagenum = 1
50
+
51
+ def pagedata_create(self):
52
+ domain = 'https://furunavi.jp'
34
- url = 'https://furunavi.jp/review_list.aspx?pid={}'.format(pageid)
53
+ url = '{}/review_list.aspx?pid={}&p={}'.format(domain, self.pageid, self.pagenum)
35
- res = requests.get(url)
54
+ res = requests.get(url)
36
- soup = BeautifulSoup(res.content, 'html.parser')
55
+ self.soup = BeautifulSoup(res.content, 'html.parser')
56
+ self.query = res.url[len(domain):]
37
- spread_writes(soup)
57
+ self.spread_writes()
38
58
 
39
- def spread_writes(page):
59
+ def spread_writes(self):
40
- elems = ["#breadcrumb ul.cf li:nth-of-type(3)", "#breadcrumb ul.cf li:nth-of-type(4)",
60
+ elems = ["#breadcrumb ul.cf li:nth-of-type(3)", "#breadcrumb ul.cf li:nth-of-type(4)",
41
- '.review_review_text', '.review_info', ".product_rep"]
61
+ '.review_review_text', '.review_info', ".product_rep"]
42
- if page.find('li', string='レビューの投稿はありません'):
62
+ if self.soup.find('li', string='レビューの投稿はありません'):
43
- return
63
+ return
44
- else:
64
+ else:
45
- elements = [page.select(e) for e in elems]
65
+ elements = [self.soup.select(e) for e in elems]
46
- item_name1 = elements[0][0].string
66
+ area = elements[0][0].string
47
- item_name2 = elements[1][0].string
67
+ item = elements[1][0].string
48
- postdates = elements[3]
68
+ postdates = elements[3]
49
- comments = elements[2]
69
+ comments = elements[2]
50
- reviews = elements[4]
70
+ reviews = elements[4]
71
+ cnt = 1
51
- for pd, cmt, rv in zip(postdates, comments, reviews):
72
+ for pd, cmt, rv in tqdm(zip(postdates, comments, reviews), total=len(postdates), desc=f'id{self.pageid} page{self.pagenum} writing', leave=False):
52
- rv = rv.i["class"][0].replace('rep_','').replace('_','.')
73
+ rv = rv.i["class"][0].replace('rep_','').replace('_','.')
53
- datas = [item_name1, item_name2, pd.string, cmt.string, rv]
74
+ datas = [area, item, pd.text, cmt.text, rv]
54
- worksheet.append_row(datas)
75
+ worksheet.append_row(datas)
55
-
76
+ time.sleep(0.8)
56
77
 
78
+ if self.soup.find('a', string='次へ').get('href') != self.query:
79
+ self.pagenum += 1
80
+ self.pagedata_create()
81
+
57
- for page in range(91610, 91620):
82
+ for i in range(73086, 73099):
58
- sample(page)
59
- time.sleep(1)
83
+ main = Main(i)
84
+ main.pagedata_create()
85
+ print(f'{i} Done!')
86
+ print('Finished!')
60
87
  ```

1

追記

2020/08/13 04:25

投稿

nto
nto

スコア1438

answer CHANGED
@@ -5,4 +5,56 @@
5
5
 
6
6
  ```python
7
7
  wks = gc.open_by_key(SPREADSHEET_KEY).sheet1
8
+ ```
9
+
10
+
11
+ ### 追記
12
+ ある程度を纏めました。
13
+ 以下でご所望の形でスプレッドシートに追記していく事が出来ると思います。
14
+ 他に質問をされいてた最終行の追加ですが`append_row()`で最終行の次の行に書き込みをする事が出来ます。
15
+
16
+
17
+ ```python
18
+ import requests
19
+ from bs4 import BeautifulSoup
20
+ from oauth2client.service_account import ServiceAccountCredentials
21
+ import gspread
22
+ import time
23
+
24
+
25
+ scope = ['https://spreadsheets.google.com/feeds',
26
+ 'https://www.googleapis.com/auth/drive']
27
+ credentials = ServiceAccountCredentials.from_json_keyfile_name('ファイル名.json', scope)
28
+ gc = gspread.authorize(credentials)
29
+ SPREADSHEET_KEY = 'スプレッドシートキー'
30
+ worksheet = gc.open_by_key(SPREADSHEET_KEY).sheet1
31
+
32
+
33
+ def sample(pageid):
34
+ url = 'https://furunavi.jp/review_list.aspx?pid={}'.format(pageid)
35
+ res = requests.get(url)
36
+ soup = BeautifulSoup(res.content, 'html.parser')
37
+ spread_writes(soup)
38
+
39
+ def spread_writes(page):
40
+ elems = ["#breadcrumb ul.cf li:nth-of-type(3)", "#breadcrumb ul.cf li:nth-of-type(4)",
41
+ '.review_review_text', '.review_info', ".product_rep"]
42
+ if page.find('li', string='レビューの投稿はありません'):
43
+ return
44
+ else:
45
+ elements = [page.select(e) for e in elems]
46
+ item_name1 = elements[0][0].string
47
+ item_name2 = elements[1][0].string
48
+ postdates = elements[3]
49
+ comments = elements[2]
50
+ reviews = elements[4]
51
+ for pd, cmt, rv in zip(postdates, comments, reviews):
52
+ rv = rv.i["class"][0].replace('rep_','').replace('_','.')
53
+ datas = [item_name1, item_name2, pd.string, cmt.string, rv]
54
+ worksheet.append_row(datas)
55
+
56
+
57
+ for page in range(91610, 91620):
58
+ sample(page)
59
+ time.sleep(1)
8
60
  ```