質問編集履歴

2

追記

2020/04/05 13:32

投稿

Kokku
Kokku

スコア39

test CHANGED
File without changes
test CHANGED
@@ -12,6 +12,10 @@
12
12
 
13
13
 
14
14
 
15
+
16
+
17
+ エラー内容
18
+
15
19
  ```エラー内容
16
20
 
17
21
  PS C:\Users\shota\documents\scraping> python crawler_2.py
@@ -64,7 +68,7 @@
64
68
 
65
69
 
66
70
 
67
-
71
+ コード
68
72
 
69
73
  ```
70
74
 

1

追記

2020/04/05 13:32

投稿

Kokku
Kokku

スコア39

test CHANGED
File without changes
test CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
 
10
10
 
11
- pythonを使い対象のサイトをスクレイピングしようと思いpymongoモジュールをインストールしてコードに書き込み実行すると下記のようなエラーが出てしまいます。
11
+ pythonを使い対象のサイトをスクレイピングしようと思いpymongoモジュールをインストールしてコードに書き込み実行すると下記のようなエラーが出てしまいます。(pip install pymongo)とpowershellに入力。
12
12
 
13
13
 
14
14
 
@@ -64,4 +64,200 @@
64
64
 
65
65
 
66
66
 
67
+
68
+
69
+ ```
70
+
71
+ import re #reモジュールをインストールする
72
+
73
+ import time
74
+
75
+ import requests
76
+
77
+ import lxml.html
78
+
79
+ from pymongo import MongoClient
80
+
81
+
82
+
83
+
84
+
85
+ def main():
86
+
87
+
88
+
89
+ """
90
+
91
+ クローラーのメイン処理
92
+
93
+
94
+
95
+ """
96
+
97
+ """
98
+
99
+ session = requests.Session() #複数のページをクロールするのでSessionを使う。
100
+
101
+ response = session.get('https://gihyo.jp/dp')
102
+
103
+ urls = scrape_list_page(response)
104
+
105
+ for url in urls:
106
+
107
+ time.sleep(1)
108
+
109
+ response = session.get(url) #Sessionを使って詳細ページを取得する。
110
+
111
+ ebook = scrape_detail_page(response) #詳細ページからスクレイピングして電子書籍の情報を得る。
112
+
113
+ print(ebook) #電子書籍の情報を取得する。
114
+
115
+ #break #まず1ページだけで試すため、break文でループを始める。
116
+
117
+ """
118
+
119
+
120
+
121
+ client = MongoClient('localhost',27017) #ローカルホストのMongoDBに接続する。
122
+
123
+ collection = client.scraping.ebooks #scrapingデータベースのebookコレクションを得る。
124
+
125
+ #データを一意に識別するキーを格納するkeyフィールドにユニークなインデックスを作成する。
126
+
127
+ collection.create_index('key',unique=True)
128
+
129
+
130
+
131
+ response = requests.get('https://gihyo.jp/dp') #一覧ページを取得する。
132
+
133
+ urls = scrape_list_page(response) #詳細ページのURL一覧を取得する。
134
+
135
+ for url in urls:
136
+
137
+ key = extract_key(url) #URLからキーを取得する。
138
+
139
+
140
+
141
+ ebook = collection.find_one({'key':key}) #MongoDBからkeyに該当するデータを探す。
142
+
143
+ if not ebook: #MongoDBに存在しない場合だけ、詳細ページをクロールする。
144
+
145
+ time.sleep(1)
146
+
147
+ response = requests.get(url)
148
+
149
+ ebook = scrape_detail_page(response)
150
+
151
+ collection.insert_one(ebook) #電子書籍の情報をMongoDBに保存する。
152
+
153
+
154
+
155
+ print(ebook) #電子書籍の情報を表示する。
156
+
157
+
158
+
159
+
160
+
161
+ def scrape_list_page(response):
162
+
163
+ """
164
+
165
+ 一覧ページのResponseから詳細ページのURLを抜き出す
166
+
167
+ """
168
+
169
+ root = lxml.html.fromstring(response.content)
170
+
171
+ root.make_links_absolute(response.url)
172
+
173
+
174
+
175
+ for a in root.cssselect('#listBook a[itemprop="url"]'):
176
+
177
+ url = a.get('href')
178
+
179
+ yield url
180
+
181
+
182
+
183
+
184
+
185
+ def scrape_detail_page(response):
186
+
187
+ """
188
+
189
+ 詳細ページのResponseから電子書籍の情報をdictで得る。。
190
+
191
+ """
192
+
193
+ root = lxml.html.fromstring(response.content)
194
+
195
+
196
+
197
+ ebook = {
198
+
199
+ 'url': response.url, #URL
200
+
201
+ 'key': extract_key(response.url), #URLから抜き出したキー
202
+
203
+ 'title': root.cssselect('#bookTitle')[0].text_content(), #タイトル
204
+
205
+ 'price': root.cssselect('.buy')[0].text.strip(),#価格(.textで直接の子である文字列のみを取得)
206
+
207
+ 'content': [normalize_sapces(h3.text_content()) for h3 in root.cssselect('#content > h3')], #目次
208
+
209
+ }
210
+
211
+
212
+
213
+ return ebook #dictを返す。
214
+
215
+
216
+
217
+
218
+
219
+
220
+
221
+ def extract_key(url):
222
+
223
+ """
224
+
225
+ URLからキー(URLの末尾のISBN)を抜き出す。
226
+
227
+ """
228
+
229
+ m = re.search(r'/([^/]+)$',url)
230
+
231
+ return m.group(1)
232
+
233
+
234
+
235
+
236
+
237
+ def normalize_sapces(s):
238
+
239
+ """
240
+
241
+ 連続する空白を1つのスペースに置き替え、前後の空白は削除した新しい文字列を取得する。
242
+
243
+ """
244
+
245
+
246
+
247
+ return re.sub(r'\s+', ' ',s).strip()
248
+
249
+
250
+
251
+
252
+
253
+ if __name__ == '__main__':
254
+
255
+ main()
256
+
257
+
258
+
259
+ ```
260
+
261
+
262
+
67
263
  このサイトでpymongoと検索をかけ、いろいろ原因を探ってみましたが、windows向けの回答が見つからなくネットで見てもわかりませんでした。