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

回答編集履歴

15

秒数

2017/05/08 06:22

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -168,9 +168,13 @@
168
168
  あとは`xrange(1, 100000)`にすれば2013100000から2013199999までの情報がとれます。
169
169
 
170
170
  `sleep(1)`だとちょっと不安なのでもっと増やしたほうが個人的にはいいですが・・・
171
- `import random`をして`time.sleep(random.uniform(30, 50))`とかにすると10sec - 20secの間でランダムな秒数待てます。
171
+ `import random`をして`time.sleep(random.uniform(5, 10))`とかにすると5sec - 10secの間でランダムな秒数待てます。
172
172
 
173
- ただこれだけ待ってると99999件取得した場合に半月前後かかるとおもいます・・・w
173
+ ただこれだけ待ってると99999件取得した場合に尋常じゃない時間がかかます
174
174
 
175
+ 普通1秒に1アクセスでも問題にはならないようですが、岡崎市図書館事件のように、相手側のサーバーでの通信方式に不備があると障害を引き起こすこともあります。
175
176
 
177
+ 一番は相手側にスクレイピングの許可をもらえることですね。
178
+
179
+
176
180
  長文で申し訳ないです・・・

14

HEY

2017/05/08 06:22

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -167,10 +167,10 @@
167
167
 
168
168
  あとは`xrange(1, 100000)`にすれば2013100000から2013199999までの情報がとれます。
169
169
 
170
- `sleep(1)`だとちょっと不安なのでもっと増やしたほうがと思
170
+ `sleep(1)`だとちょっと不安なのでもっと増やしたほうが個人的にはいいが・・・
171
- `import random`をして`time.sleep(random.uniform(30, 50))`とかにすると30sec - 50secの間でランダムな秒数待てます。
171
+ `import random`をして`time.sleep(random.uniform(30, 50))`とかにすると10sec - 20secの間でランダムな秒数待てます。
172
172
 
173
- あとは寝実行すればいいいます
173
+ ただこれだけ待ってと99999件取得した場合半月前後かかるおもいます・・・w
174
174
 
175
175
 
176
176
  長文で申し訳ないです・・・

13

ごめん間違えて無編集でOKしちゃった

2017/05/08 06:18

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -120,7 +120,6 @@
120
120
  import codecs
121
121
  import time
122
122
  from bs4 import BeautifulSoup
123
- import random
124
123
 
125
124
  f = codecs.open('hiyoko.csv', 'w', 'utf-8')
126
125
  horse_name = ""
@@ -129,7 +128,7 @@
129
128
  for i in xrange(1, 10):
130
129
  url = start_url.format(i)
131
130
  soup = BeautifulSoup(urllib2.urlopen(url).read(), "lxml")
132
- time.sleep(random.uniform(1, 10))
131
+ time.sleep(1)
133
132
  horse_name_tag = soup.find('div', {'class': 'horse_title'})
134
133
 
135
134
  if horse_name_tag != None:

12

a

2017/05/08 06:10

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
File without changes

11

pep8違反修正

2017/05/08 06:09

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -120,22 +120,28 @@
120
120
  import codecs
121
121
  import time
122
122
  from bs4 import BeautifulSoup
123
+ import random
123
124
 
124
125
  f = codecs.open('hiyoko.csv', 'w', 'utf-8')
125
126
  horse_name = ""
126
127
  start_url = 'http://db.netkeiba.com/horse/201310069{0}/'
128
+
127
129
  for i in xrange(1, 10):
128
130
  url = start_url.format(i)
129
- soup = BeautifulSoup(urllib2.urlopen(url).read(),"lxml")
131
+ soup = BeautifulSoup(urllib2.urlopen(url).read(), "lxml")
130
- time.sleep(1)
132
+ time.sleep(random.uniform(1, 10))
131
- horse_name_tag = soup.find('div',{'class':'horse_title'})
133
+ horse_name_tag = soup.find('div', {'class': 'horse_title'})
134
+
132
135
  if horse_name_tag != None:
136
+
133
137
  if horse_name_tag.find('h1') != None:
134
138
  horse_name = horse_name_tag.find('h1').text
139
+ horse_name = "".join(
135
- horse_name = "".join([x for x in horse_name_tag.text if not x == u'\xa0' and not x == u'\n'])
140
+ [x for x in horse_name_tag.text if not x == u'\xa0' and not x == u'\n'])
136
141
  print horse_name.strip()
137
142
  cols = [horse_name]
138
143
  f.write(",".join(cols) + "\n")
144
+
139
145
  else:
140
146
  continue
141
147
 

10

また編集

2017/05/08 06:08

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -106,7 +106,7 @@
106
106
  ```python
107
107
  horse_name_tag=soup.find('div',{'class':'horse_title'}).find('div',{'class':'horse_title'}).find('h1')
108
108
  ```
109
- ここで`class=horse_title`の`div`の下でまた`class=horse_title`の`div`を探しちゃってるのでNoneになります。
109
+ ここで`class="horse_title"`の`div`の下でまた`class="horse_title"`の`div`を探しちゃってるのでNoneになります。
110
110
  サイト内で確認したら`class="horse_title"`の`div`の直下に`h1`があるので
111
111
  ```python
112
112
  horse_name_tag=soup.find('div',{'class':'horse_title'}).find('h1')
@@ -160,5 +160,12 @@
160
160
 
161
161
  * ページが変だったとき(馬の情報が空だったとき)はDOM要素が見つからず`None`が返るので、そのときはスキップ
162
162
 
163
+ あとは`xrange(1, 100000)`にすれば2013100000から2013199999までの情報がとれます。
163
164
 
165
+ `sleep(1)`だとちょっと不安なのでもっと増やしたほうが良いと思います。
166
+ `import random`をして`time.sleep(random.uniform(30, 50))`とかにすると30sec - 50secの間でランダムな秒数待てます。
167
+
168
+ あとは寝る前に実行すればいいと思います。
169
+
170
+
164
171
  長文で申し訳ないです・・・

9

さいごっていうのやめる

2017/05/08 05:59

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -88,7 +88,7 @@
88
88
  の部分で、find関数にタプルを渡してしまっています。(丸括弧が多い)
89
89
  この部分ですね。
90
90
  ```python
91
- find( ('div',{'class':'horse_title'}).find('h1') )
91
+ soup.find('div',{'class':'horse_title'}).find( ('div',{'class':'horse_title'}).find('h1') )
92
92
  ```
93
93
  このまま実行すると
94
94
  ```
@@ -96,17 +96,18 @@
96
96
  ```
97
97
  というエラーになります。なので、
98
98
  ```python
99
- find('div',{'class':'horse_title'}).find('h1')
99
+ soup.find('div',{'class':'horse_title'}).find('div',{'class':'horse_title'}).find('h1')
100
100
  ```
101
- これでOK。
101
+ これでOK。(違う理由でこれだとエラーになります。以下参照)
102
+
102
103
  おそらくただのタイプミスだとは思いますが一応。
103
104
 
104
-
105
+ 上記のままだエラーになる理由がこれ。
105
106
  ```python
106
- horse_name_tag=soup.find('div',{'class':'horse_title'}).find(('div',{'class':'horse_title'})).find('h1')
107
+ horse_name_tag=soup.find('div',{'class':'horse_title'}).find('div',{'class':'horse_title'}).find('h1')
107
108
  ```
108
109
  ここで`class=horse_title`の`div`の下でまた`class=horse_title`の`div`を探しちゃってるのでNoneになります。
109
- サイト内で確認したら`class=horse_title`の`div`の直下に`h1`があるので
110
+ サイト内で確認したら`class="horse_title"`の`div`の直下に`h1`があるので
110
111
  ```python
111
112
  horse_name_tag=soup.find('div',{'class':'horse_title'}).find('h1')
112
113
  ```
@@ -129,18 +130,19 @@
129
130
  time.sleep(1)
130
131
  horse_name_tag = soup.find('div',{'class':'horse_title'})
131
132
  if horse_name_tag != None:
132
- horse_name_tag.find('h1')
133
+ if horse_name_tag.find('h1') != None:
134
+ horse_name = horse_name_tag.find('h1').text
133
- horse_name = "".join([x for x in horse_name_tag.text if not x == u'\xa0' and not x == u'\n'])
135
+ horse_name = "".join([x for x in horse_name_tag.text if not x == u'\xa0' and not x == u'\n'])
134
- print horse_name.strip()
136
+ print horse_name.strip()
135
- cols = [horse_name]
137
+ cols = [horse_name]
136
- f.write(",".join(cols) + "\n")
138
+ f.write(",".join(cols) + "\n")
137
139
  else:
138
140
  continue
139
141
 
140
142
  f.close()
141
143
  ```
142
144
 
143
- これで動きます。
145
+ これで動くはずです。
144
146
 
145
147
 
146
148
  最初コード書いたときに、最初に定義したurlという変数をfor内で上書きしちゃってました。

8

さいごのさいごの編集

2017/05/08 05:52

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -85,7 +85,7 @@
85
85
  ```python
86
86
  horse_name_tag=soup.find('div',{'class':'horse_title'}).find(('div',{'class':'horse_title'}).find('h1'))
87
87
  ```
88
- の部分で、find関数にタプルを渡してしまっています。(丸括弧を閉じる場所違う
88
+ の部分で、find関数にタプルを渡してしまっています。(丸括弧が多い
89
89
  この部分ですね。
90
90
  ```python
91
91
  find( ('div',{'class':'horse_title'}).find('h1') )
@@ -94,9 +94,9 @@
94
94
  ```
95
95
  AttributeError: 'tuple' object has no attribute 'find'
96
96
  ```
97
- というエラーになります。
97
+ というエラーになります。なので、
98
98
  ```python
99
- find( ('div',{'class':'horse_title'}) ).find('h1')
99
+ find('div',{'class':'horse_title'}).find('h1')
100
100
  ```
101
101
  これでOK。
102
102
  おそらくただのタイプミスだとは思いますが一応。

7

さいごの編集

2017/05/08 05:45

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -85,7 +85,7 @@
85
85
  ```python
86
86
  horse_name_tag=soup.find('div',{'class':'horse_title'}).find(('div',{'class':'horse_title'}).find('h1'))
87
87
  ```
88
- の部分で、find関数にタプルを渡してしまっています。(丸括弧が多い
88
+ の部分で、find関数にタプルを渡してしまっています。(丸括弧を閉じる場所違う
89
89
  この部分ですね。
90
90
  ```python
91
91
  find( ('div',{'class':'horse_title'}).find('h1') )
@@ -95,7 +95,10 @@
95
95
  AttributeError: 'tuple' object has no attribute 'find'
96
96
  ```
97
97
  というエラーになります。
98
-
98
+ ```python
99
+ find( ('div',{'class':'horse_title'}) ).find('h1')
100
+ ```
101
+ これでOK。
99
102
  おそらくただのタイプミスだとは思いますが一応。
100
103
 
101
104
  あと

6

加筆修正

2017/05/08 05:43

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -49,6 +49,8 @@
49
49
  ずっと`http://db.netkeiba.com/horse/2013100691/`のままなので同じものしか取得できませんでした。
50
50
  2.7の仕様はよく分かってませんので、きっとなにかがPython3と違うのでしょう。
51
51
  `print i` をするとちゃんと順番にたされた数字が返ってきてるのですが・・・
52
+ **※このへんは変数urlを上書きしてるのが原因でした。一番下で言及します**
53
+
52
54
  なのでいろいろやってこうなりました。
53
55
  ```python
54
56
  # -*- coding:utf-8 -*-
@@ -140,6 +142,8 @@
140
142
 
141
143
  最初コード書いたときに、最初に定義したurlという変数をfor内で上書きしちゃってました。
142
144
 
145
+ `format`関数は文字列内に`{0}`などがなくてもエラー吐かないんですね・・・
146
+
143
147
  確か同スコープ内なので、最初のurlはstart_urlという変数にいれて、for内でフォーマットして使うものはurlとしました。
144
148
 
145
149
  ## 最後にもう一度まとめ

5

長文になったのでまとめを最初に書きます。

2017/05/08 05:41

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -1,3 +1,13 @@
1
+ ## 長文になったのでまとめを最初に書いときます
2
+ * `find`にタプルを渡してるのでエラーになってた
3
+
4
+ * `url`の変数を上書きしない
5
+
6
+ * DOM要素の指定ミス(最初の`div`タグの指定を2回行っていたため、`h1`が見つからず`None`が返ってた)
7
+
8
+ * ページが変だったとき(馬の情報が空だったとき)はDOM要素が見つからず`None`が返るので、そのときはスキップ
9
+
10
+ ## 以下、試行の変遷記録(笑)
1
11
  最初に言っておくと、Python3しか書けないのでPython3で書きました。
2
12
  連番をurlに埋め込んで使うのは良いと思いますが、ページが変なページで取得したものがNoneだったらエラーになってしまいます。
3
13
  なのでifで回避すれば動くと思います。
@@ -132,7 +142,7 @@
132
142
 
133
143
  確か同スコープ内なので、最初のurlはstart_urlという変数にいれて、for内でフォーマットして使うものはurlとしました。
134
144
 
135
- ## まとめ
145
+ ## 最後にもう一度まとめ
136
146
  * `find`にタプルを渡してるのでエラーになってた
137
147
 
138
148
  * `url`の変数を上書きしない

4

ちょい修正

2017/05/08 05:36

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -68,8 +68,36 @@
68
68
  f.close()
69
69
  ```
70
70
  ## 追記:
71
+
71
- すみません。初歩的なミスした。
72
+ 質問者様のコード
72
73
  ```python
74
+ horse_name_tag=soup.find('div',{'class':'horse_title'}).find(('div',{'class':'horse_title'}).find('h1'))
75
+ ```
76
+ の部分で、find関数にタプルを渡してしまっています。(丸括弧が多い)
77
+ この部分ですね。
78
+ ```python
79
+ find( ('div',{'class':'horse_title'}).find('h1') )
80
+ ```
81
+ このまま実行すると
82
+ ```
83
+ AttributeError: 'tuple' object has no attribute 'find'
84
+ ```
85
+ というエラーになります。
86
+
87
+ おそらくただのタイプミスだとは思いますが一応。
88
+
89
+ あと
90
+ ```python
91
+ horse_name_tag=soup.find('div',{'class':'horse_title'}).find(('div',{'class':'horse_title'})).find('h1')
92
+ ```
93
+ ここで`class=horse_title`の`div`の下でまた`class=horse_title`の`div`を探しちゃってるのでNoneになります。
94
+ サイト内で確認したら`class=horse_title`の`div`の直下に`h1`があるので
95
+ ```python
96
+ horse_name_tag=soup.find('div',{'class':'horse_title'}).find('h1')
97
+ ```
98
+ これで取得できます。
99
+ あとはページが変だったときにNoneが返るのをifで分岐してエラー回避して・・・
100
+ ```python
73
101
  # -*- coding:utf-8 -*-
74
102
 
75
103
  import urllib2
@@ -99,6 +127,19 @@
99
127
 
100
128
  これで動きます。
101
129
 
102
- 最初に定義したurlという変数をfor内で上書きしちゃってたらそりゃうごきませんですね。
103
130
 
131
+ 最初コード書いたときに、最初に定義したurlという変数をfor内で上書きしちゃってました。
132
+
104
- 同スコープ内なので、最初のurlはstart_urlという変数にいれて、for内でフォーマットして使うものはurlとしました。
133
+ 確か同スコープ内なので、最初のurlはstart_urlという変数にいれて、for内でフォーマットして使うものはurlとしました。
134
+
135
+ ## まとめ
136
+ * `find`にタプルを渡してるのでエラーになってた
137
+
138
+ * `url`の変数を上書きしない
139
+
140
+ * DOM要素の指定ミス(最初の`div`タグの指定を2回行っていたため、`h1`が見つからず`None`が返ってた)
141
+
142
+ * ページが変だったとき(馬の情報が空だったとき)はDOM要素が見つからず`None`が返るので、そのときはスキップ
143
+
144
+
145
+ 長文で申し訳ないです・・・

3

修正

2017/05/08 05:34

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -34,7 +34,7 @@
34
34
 
35
35
  求めているものと違ったら申し訳ありません。
36
36
 
37
- 追記:
37
+ ## 追記:
38
38
  2.7で質問にあるコードでいろいろやってみたのですが、なんかxrangeで返るイテレータをforで回してurlに入れ込んでもurlが変わらないみたいです。
39
39
  ずっと`http://db.netkeiba.com/horse/2013100691/`のままなので同じものしか取得できませんでした。
40
40
  2.7の仕様はよく分かってませんので、きっとなにかがPython3と違うのでしょう。
@@ -59,8 +59,35 @@
59
59
  if horse_name_tag != None:
60
60
  horse_name_tag.find('h1')
61
61
  horse_name = "".join([x for x in horse_name_tag.text if not x == u'\xa0' and not x == u'\n'])
62
- print horse_name
62
+ print horse_name.strip()
63
+ cols = [horse_name]
64
+ f.write(",".join(cols) + "\n")
65
+ else:
66
+ continue
63
67
 
68
+ f.close()
69
+ ```
70
+ ## 追記:
71
+ すみません。初歩的なミスでした。
72
+ ```python
73
+ # -*- coding:utf-8 -*-
74
+
75
+ import urllib2
76
+ import codecs
77
+ import time
78
+ from bs4 import BeautifulSoup
79
+
80
+ f = codecs.open('hiyoko.csv', 'w', 'utf-8')
81
+ horse_name = ""
82
+ start_url = 'http://db.netkeiba.com/horse/201310069{0}/'
83
+ for i in xrange(1, 10):
84
+ url = start_url.format(i)
85
+ soup = BeautifulSoup(urllib2.urlopen(url).read(),"lxml")
86
+ time.sleep(1)
87
+ horse_name_tag = soup.find('div',{'class':'horse_title'})
88
+ if horse_name_tag != None:
89
+ horse_name_tag.find('h1')
90
+ horse_name = "".join([x for x in horse_name_tag.text if not x == u'\xa0' and not x == u'\n'])
64
91
  print horse_name.strip()
65
92
  cols = [horse_name]
66
93
  f.write(",".join(cols) + "\n")
@@ -70,4 +97,8 @@
70
97
  f.close()
71
98
  ```
72
99
 
100
+ これで動きます。
101
+
73
- Python3.x系なら最初のコードで動くいます。
102
+ 最初に定義したurlという変数をfor内で上書きしちゃってたらそりゃうごきせんで
103
+
104
+ 同スコープ内なので、最初のurlはstart_urlという変数にいれて、for内でフォーマットして使うものはurlとしました。

2

2\.7でやってみた

2017/05/08 05:12

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -32,4 +32,42 @@
32
32
 
33
33
  ```
34
34
 
35
- 求めているものと違ったら申し訳ありません。
35
+ 求めているものと違ったら申し訳ありません。
36
+
37
+ 追記:
38
+ 2.7で質問にあるコードでいろいろやってみたのですが、なんかxrangeで返るイテレータをforで回してurlに入れ込んでもurlが変わらないみたいです。
39
+ ずっと`http://db.netkeiba.com/horse/2013100691/`のままなので同じものしか取得できませんでした。
40
+ 2.7の仕様はよく分かってませんので、きっとなにかがPython3と違うのでしょう。
41
+ `print i` をするとちゃんと順番にたされた数字が返ってきてるのですが・・・
42
+ なのでいろいろやってこうなりました。
43
+ ```python
44
+ # -*- coding:utf-8 -*-
45
+
46
+ import urllib2
47
+ import codecs
48
+ import time
49
+ from bs4 import BeautifulSoup
50
+
51
+ f = codecs.open('hiyoko.csv', 'w', 'utf-8')
52
+ horse_name = ""
53
+
54
+ for i in xrange(1, 10):
55
+ url = 'http://db.netkeiba.com/horse/201310069%d/' % i
56
+ soup = BeautifulSoup(urllib2.urlopen(url).read(),"lxml")
57
+ time.sleep(5)
58
+ horse_name_tag = soup.find('div',{'class':'horse_title'})
59
+ if horse_name_tag != None:
60
+ horse_name_tag.find('h1')
61
+ horse_name = "".join([x for x in horse_name_tag.text if not x == u'\xa0' and not x == u'\n'])
62
+ print horse_name
63
+
64
+ print horse_name.strip()
65
+ cols = [horse_name]
66
+ f.write(",".join(cols) + "\n")
67
+ else:
68
+ continue
69
+
70
+ f.close()
71
+ ```
72
+
73
+ Python3.x系なら最初のコードで動くと思います。

1

冗長なのでちょっと直しました

2017/05/08 05:04

投稿

kurosuke___
kurosuke___

スコア217

answer CHANGED
@@ -14,17 +14,18 @@
14
14
 
15
15
  for i in range(1, 99999):
16
16
  soup = BeautifulSoup(urlopen(url.format(i)), "lxml")
17
+ time.sleep(5)
17
18
  div = soup.find('div', class_='horse_title')
18
19
 
19
20
  # divがNoneTypeObjectだったらcontinue
20
21
  if div != None:
21
22
  horse_name = div.h1.text
22
- print(horse_name)
23
+ if horse_name != None:
23
- horse_name_list.append(horse_name)
24
+ horse_name_list.append(horse_name)
24
- time.sleep(5)
25
+ else:
26
+ continue
25
27
  else:
26
28
  print("取得できないから飛ばすよ")
27
- time.sleep(5)
28
29
  continue
29
30
 
30
31
  print(horse_name_list)