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

質問編集履歴

2

追記

2020/04/05 13:32

投稿

Kokku
Kokku

スコア39

title CHANGED
File without changes
body CHANGED
@@ -5,6 +5,8 @@
5
5
 
6
6
  pythonを使い対象のサイトをスクレイピングしようと思いpymongoモジュールをインストールしてコードに書き込み実行すると下記のようなエラーが出てしまいます。(pip install pymongo)とpowershellに入力。
7
7
 
8
+
9
+ エラー内容
8
10
  ```エラー内容
9
11
  PS C:\Users\shota\documents\scraping> python crawler_2.py
10
12
  Traceback (most recent call last):
@@ -31,7 +33,7 @@
31
33
  pymongo.errors.ServerSelectionTimeoutError: localhost:27017: [WinError 10061] 対象のコンピューターによって拒否されたため、接続できませんでした。
32
34
  ```
33
35
 
34
-
36
+ コード
35
37
  ```
36
38
  import re #reモジュールをインストールする
37
39
  import time

1

追記

2020/04/05 13:32

投稿

Kokku
Kokku

スコア39

title CHANGED
File without changes
body CHANGED
@@ -3,7 +3,7 @@
3
3
  python3.8
4
4
 
5
5
 
6
- pythonを使い対象のサイトをスクレイピングしようと思いpymongoモジュールをインストールしてコードに書き込み実行すると下記のようなエラーが出てしまいます。
6
+ pythonを使い対象のサイトをスクレイピングしようと思いpymongoモジュールをインストールしてコードに書き込み実行すると下記のようなエラーが出てしまいます。(pip install pymongo)とpowershellに入力。
7
7
 
8
8
  ```エラー内容
9
9
  PS C:\Users\shota\documents\scraping> python crawler_2.py
@@ -31,4 +31,102 @@
31
31
  pymongo.errors.ServerSelectionTimeoutError: localhost:27017: [WinError 10061] 対象のコンピューターによって拒否されたため、接続できませんでした。
32
32
  ```
33
33
 
34
+
35
+ ```
36
+ import re #reモジュールをインストールする
37
+ import time
38
+ import requests
39
+ import lxml.html
40
+ from pymongo import MongoClient
41
+
42
+
43
+ def main():
44
+
45
+ """
46
+ クローラーのメイン処理
47
+
48
+ """
49
+ """
50
+ session = requests.Session() #複数のページをクロールするのでSessionを使う。
51
+ response = session.get('https://gihyo.jp/dp')
52
+ urls = scrape_list_page(response)
53
+ for url in urls:
54
+ time.sleep(1)
55
+ response = session.get(url) #Sessionを使って詳細ページを取得する。
56
+ ebook = scrape_detail_page(response) #詳細ページからスクレイピングして電子書籍の情報を得る。
57
+ print(ebook) #電子書籍の情報を取得する。
58
+ #break #まず1ページだけで試すため、break文でループを始める。
59
+ """
60
+
61
+ client = MongoClient('localhost',27017) #ローカルホストのMongoDBに接続する。
62
+ collection = client.scraping.ebooks #scrapingデータベースのebookコレクションを得る。
63
+ #データを一意に識別するキーを格納するkeyフィールドにユニークなインデックスを作成する。
64
+ collection.create_index('key',unique=True)
65
+
66
+ response = requests.get('https://gihyo.jp/dp') #一覧ページを取得する。
67
+ urls = scrape_list_page(response) #詳細ページのURL一覧を取得する。
68
+ for url in urls:
69
+ key = extract_key(url) #URLからキーを取得する。
70
+
71
+ ebook = collection.find_one({'key':key}) #MongoDBからkeyに該当するデータを探す。
72
+ if not ebook: #MongoDBに存在しない場合だけ、詳細ページをクロールする。
73
+ time.sleep(1)
74
+ response = requests.get(url)
75
+ ebook = scrape_detail_page(response)
76
+ collection.insert_one(ebook) #電子書籍の情報をMongoDBに保存する。
77
+
78
+ print(ebook) #電子書籍の情報を表示する。
79
+
80
+
81
+ def scrape_list_page(response):
82
+ """
83
+ 一覧ページのResponseから詳細ページのURLを抜き出す
84
+ """
85
+ root = lxml.html.fromstring(response.content)
86
+ root.make_links_absolute(response.url)
87
+
88
+ for a in root.cssselect('#listBook a[itemprop="url"]'):
89
+ url = a.get('href')
90
+ yield url
91
+
92
+
93
+ def scrape_detail_page(response):
94
+ """
95
+ 詳細ページのResponseから電子書籍の情報をdictで得る。。
96
+ """
97
+ root = lxml.html.fromstring(response.content)
98
+
99
+ ebook = {
100
+ 'url': response.url, #URL
101
+ 'key': extract_key(response.url), #URLから抜き出したキー
102
+ 'title': root.cssselect('#bookTitle')[0].text_content(), #タイトル
103
+ 'price': root.cssselect('.buy')[0].text.strip(),#価格(.textで直接の子である文字列のみを取得)
104
+ 'content': [normalize_sapces(h3.text_content()) for h3 in root.cssselect('#content > h3')], #目次
105
+ }
106
+
107
+ return ebook #dictを返す。
108
+
109
+
110
+
111
+ def extract_key(url):
112
+ """
113
+ URLからキー(URLの末尾のISBN)を抜き出す。
114
+ """
115
+ m = re.search(r'/([^/]+)$',url)
116
+ return m.group(1)
117
+
118
+
119
+ def normalize_sapces(s):
120
+ """
121
+ 連続する空白を1つのスペースに置き替え、前後の空白は削除した新しい文字列を取得する。
122
+ """
123
+
124
+ return re.sub(r'\s+', ' ',s).strip()
125
+
126
+
127
+ if __name__ == '__main__':
128
+ main()
129
+
130
+ ```
131
+
34
132
  このサイトでpymongoと検索をかけ、いろいろ原因を探ってみましたが、windows向けの回答が見つからなくネットで見てもわかりませんでした。