回答編集履歴

5

補足

2018/02/21 12:23

投稿

umyu
umyu

スコア5846

test CHANGED
@@ -165,3 +165,89 @@
165
165
 
166
166
 
167
167
  こうすることで、関数内と渡すパラメータだけ意識すればよくなり影響範囲が少なくなります。
168
+
169
+
170
+
171
+ python 3バージョンのソースコードです。
172
+
173
+ ```Python
174
+
175
+ # -*- coding: utf8 -*-
176
+
177
+ import urllib.request
178
+
179
+ from bs4 import BeautifulSoup
180
+
181
+
182
+
183
+
184
+
185
+ def get_content(url:str):
186
+
187
+ """
188
+
189
+ @params url スクレイピング対象のURL
190
+
191
+ """
192
+
193
+ with urllib.request.urlopen(url) as response:
194
+
195
+ return BeautifulSoup(response.read(), "html.parser")
196
+
197
+
198
+
199
+
200
+
201
+ def get_data(soup) -> str:
202
+
203
+ i = 0
204
+
205
+ for parent in soup.find('div', {'class': 'race_otherdata'}):
206
+
207
+ data = parent.string.rstrip()
208
+
209
+ if len(data) == 0:
210
+
211
+ continue
212
+
213
+ if i == 2:
214
+
215
+ # 本賞金以降はSkip
216
+
217
+ continue
218
+
219
+ yield data
220
+
221
+ i += 1
222
+
223
+
224
+
225
+
226
+
227
+ def main() -> None:
228
+
229
+ url = 'http://race.netkeiba.com/?pid=race_old&id=p201805010301'
230
+
231
+ soup = get_content(url)
232
+
233
+ # python 3なのでcodec.openは不要
234
+
235
+ with open('tokyo_race_1.csv', 'w', encoding='utf-8') as f:
236
+
237
+ f.write('other_race_name' + u"\n")
238
+
239
+ for row in get_data(soup):
240
+
241
+ print(row)
242
+
243
+ f.write(row + "\n")
244
+
245
+
246
+
247
+
248
+
249
+ if __name__ == '__main__':
250
+
251
+ main()
252
+
253
+ ```

4

追記

2018/02/21 12:23

投稿

umyu
umyu

スコア5846

test CHANGED
@@ -125,3 +125,43 @@
125
125
  このコードを記述する時に一番時間がかかった点は`python 2.7`環境での`unicode`文字列の変換部分でした。
126
126
 
127
127
  制約事項などがない場合は`python 3`環境に移行することをおすすめいたします。
128
+
129
+
130
+
131
+ ---
132
+
133
+
134
+
135
+ 質問文のソースコードは回答した内容が一切反映されていないソースコードなのですが・・・その点。
136
+
137
+
138
+
139
+ まず、スクリプトの各変数の影響範囲を少なくすることを考えてくださいな。
140
+
141
+ 質問文の改訂されたソースコードだと、どの箇所が問題になっているか、一瞬では原因究明が行えないと思います。
142
+
143
+
144
+
145
+ それは、以下の3つの処理を一つのスクリプト内で行っているからです。
146
+
147
+
148
+
149
+ 1,WEBサイトからスクレイピング
150
+
151
+ 2,スクレイピングしたデータをタグを指定して該当部分を抽出
152
+
153
+ 3,抽出した内容をcsvファイルに書き出し。
154
+
155
+
156
+
157
+ こういう時は回答文のソースコードのように3つに関数を分割化を行います。
158
+
159
+ 1,get_content
160
+
161
+ 2,get_data
162
+
163
+ 3,main
164
+
165
+
166
+
167
+ こうすることで、関数内と渡すパラメータだけ意識すればよくなり影響範囲が少なくなります。

3

追記

2018/02/21 12:15

投稿

umyu
umyu

スコア5846

test CHANGED
@@ -12,9 +12,9 @@
12
12
 
13
13
  このメッセージが発生する条件は以下の2パターンが多いです。
14
14
 
15
- パターン1,値がNoneの変数に対して関数を呼び出そうとした。
15
+ パターン1,値が`None`の変数に対して関数を呼び出そうとした。
16
16
 
17
- soup_1.find('div',{'class':'race_otherdata'})の戻り値がNoneで、それに対して.findall()関数をよびだそうとした
17
+ 質問文の場合はsoup_1.find('div',{'class':'race_otherdata'})の戻り値が`None`で、それに対して.findall()関数をよびだそうとした
18
18
 
19
19
  パターン2,呼び出し関数のスペルミス。今回の場合はこちらです。
20
20
 
@@ -122,6 +122,6 @@
122
122
 
123
123
  ■余談
124
124
 
125
- このコードを記述する時に一番時間がかかった点はpython 2.7環境でのunicode文字列の変換部分でした。
125
+ このコードを記述する時に一番時間がかかった点は`python 2.7`環境での`unicode`文字列の変換部分でした。
126
126
 
127
- 制約事項などがない場合はpython 3環境に移行することをおすすめいたします。
127
+ 制約事項などがない場合は`python 3`環境に移行することをおすすめいたします。

2

補足

2018/02/21 00:48

投稿

umyu
umyu

スコア5846

test CHANGED
@@ -10,17 +10,25 @@
10
10
 
11
11
 
12
12
 
13
- このメッセージが発生する条件は
13
+ このメッセージが発生する条件は以下の2パターンが多いです。
14
14
 
15
- 1,soup_1.find('div',{'class':'race_otherdata'})の戻り値がNoneで、それに対して.findall()そうとした
15
+ パターン1,値がNoneの変数に対して関数そうとした
16
16
 
17
+ soup_1.find('div',{'class':'race_otherdata'})の戻り値がNoneで、それに対して.findall()関数をよびだそうとした
18
+
17
- 2,今回の場合はこちら 呼び出し関数のスペルミス。.findall => .find_all
19
+ パターン2,呼び出し関数のスペルミス。今回の場合はこちらです。
20
+
21
+ |○/×|関数名|
22
+
23
+ |:--|:--:|
24
+
25
+ |×|.findall|
26
+
27
+ |○|.find_all|
18
28
 
19
29
 
20
30
 
21
-
31
+ ---
22
-
23
-
24
32
 
25
33
  2行目の値も取り出したいとのことなので以下のソースコードでご要望の処理になりますか?
26
34
 

1

追記

2018/02/21 00:27

投稿

umyu
umyu

スコア5846

test CHANGED
@@ -1,4 +1,28 @@
1
+ > TypeError: 'NoneType' object is not callable
2
+
3
+
4
+
5
+ ぐーぐる翻訳
6
+
7
+ TypeError: 'NoneType'オブジェクトは呼び出し可能ではありません
8
+
9
+
10
+
11
+
12
+
1
- んな感じでしょうか?
13
+ のメッセージが発生する条件は
14
+
15
+ 1,soup_1.find('div',{'class':'race_otherdata'})の戻り値がNoneで、それに対して.findall()をよびだそうとした
16
+
17
+ 2,今回の場合はこちら 呼び出し関数のスペルミス。.findall => .find_all
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+ 2行目の値も取り出したいとのことなので以下のソースコードでご要望の処理になりますか?
2
26
 
3
27
 
4
28
 
@@ -80,6 +104,14 @@
80
104
 
81
105
  ```
82
106
 
107
+
108
+
109
+ ■参考情報
110
+
111
+ [Beautiful Soup 4.2.0 Doc. 日本語訳 (2013-11-19最終更新)](http://kondou.com/BS4/)
112
+
113
+
114
+
83
115
  ■余談
84
116
 
85
117
  このコードを記述する時に一番時間がかかった点はpython 2.7環境でのunicode文字列の変換部分でした。