Crawling_basic(01)

크롤링

즐거운 마음으로 크롤링 해 봅시다 !


01. file 준비

file
repository에 올려놓았다.

pycham을 열어서 python 가상환경(VENV)설정 후 그 file에서 진행.


02. 크롤링 : BeautifulSoup 설치

beautifulsoup 설치는 여기 에서 시작

Crawling_beautifulsoup

terminal에 위의 명령어 입력

BeautifulSoup 설치 되었는지 한번 더 확인

1
2
from bs4 import BeautifulSoup
print("library imported")

terminal에 library imported가 print 된다.


03. 크롤링 : code

03.1 객체 초기화

1
2
3
4
5
6
7
8
def main():
#객체 초기화, 뒤에있는 parser가 핵심: python에서 접근 가능하게 만들어줌
soup = BeautifulSoup(open("data/index.html"), "html.parser")
print(soup)

if __name__ == "__main__":
main()

함수를 만들어 html file을 열고 그 file을 parser로 python이 읽을 수 있는 형태로 가져온다.

out:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

library imported
<!DOCTYPE html>

<html>
<head>
<meta charset="utf-8"/>
<title>Crawl This Page</title>
</head>
<body>
<div class="cheshire">
<p>Don't crawl this.</p>
</div>
<div class="elice">
<p>Hello, Python Crawling!</p>
</div>
</body>
</html>

Process finished with exit code 0


읽어 오는 데 까지가 끝

03.2 원하는 객체 뽑아내기 : HTML tag로

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# /c/../Crawring/venv/Scripts/python
# -*- Encoding : UTF-8 -*-

from bs4 import BeautifulSoup

print("library imported")


def main():
# 객체 초기화, 뒤에있는 parser가 핵심: python에서 접근 가능하게 만들어줌
soup = BeautifulSoup(open("data/index.html"), "html.parser")
#원하는 data 출력
print(soup.find("div").get_text()) #find_all 쓰면 get_text가 안된다.
#저장(Excel:pandas, DB)

if __name__ == "__main__":
main()

out:
1
2
3
4
5
library imported

Don't crawl this.

Process finished with exit code 0
  • .find("div") : div tag를 뽑아오는 구문
  • .get_text() : div tag를 삭제하고 text만 뽑아옴
  • .find_all("div") : get text()가 안먹는다.

03.3 원하는 객체 뽑아내기 : class name으로

1
2
3
4
5
6
7
8
9
10
11

def main():
# 객체 초기화
soup = BeautifulSoup(open("data/index2.html"), "html.parser")
# 원하는 data 출력
print(soup.find("div", class_ = "elice").find("p").get_text())
# 저장(Excel:pandas, DB)

if __name__ == "__main__":
main()

03.4 원하는 객체 뽑아내기 : id 로

1
2
3
4
5
6
7
8
9
10
11

def main():
# 객체 초기화
soup = BeautifulSoup(open("data/index3.html"), "html.parser")
# 원하는 data 출력
print(soup.find("div", id = "main").find("p").get_text())
# 저장(Excel:pandas, DB)

if __name__ == "__main__":
main()


04. data 뽑아내기

  • 신비롭게 data 뽑아내는 거는 google colab에서 진행

04.1 data file 받아오기

  • Data file은 여기에서 무료로 혹은 유료로 받을 수 있다.
  • 인증키를 받아서 사용 해야 하는데, 인증키는 여기 서 개인정보를 입력하고 받아 오면 된다.
  • 인증키를 받았다면 google colab 열고 진행
  • 인증키는 입력한 메일로 오기 때문에 메일을 잘 쓰기 바란다.
1
2
3
4
5
import requests
key = "*본인의 인증키 숫자를 넣는다*"
url = "http://data.ex.co.kr/openapi/trtm/realUnitTrtm?key=`인증키여기`&type=json&iStartUnitCode=101&iEndUnitCode=103"

responses = requests.get(url)

<Response [200]>

인증키를 서공적으로 넣으면 위와 같은 out이 나온다.

04.2 responses로 json file 만들기

1
2
json = responses.json()

out:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
{'code': 'SUCCESS',
'count': 602,
'message': '인증키가 유효합니다.',
'numOfRows': 10,
'pageNo': 1,
'pageSize': 61,
'realUnitTrtmVO': [{'efcvTrfl': '18',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:25',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.466666666666667',
'timeMax': '9.216',
'timeMin': '5.800'},
{'efcvTrfl': '53',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:30',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.466666666666667',
'timeMax': '9.283',
'timeMin': '5.783'},
{'efcvTrfl': '14',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:35',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.416666666666667',
'timeMax': '8.400',
'timeMin': '6.050'},
{'efcvTrfl': '15',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:40',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.516666666666667',
'timeMax': '9.283',
'timeMin': '5.966'},
{'efcvTrfl': '41',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:45',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.5',
'timeMax': '8.800',
'timeMin': '5.750'},
{'efcvTrfl': '11',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:50',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.416666666666667',
'timeMax': '8.800',
'timeMin': '5.766'},
{'efcvTrfl': '8',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:55',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.433333333333334',
'timeMax': '8.350',
'timeMin': '5.750'},
{'efcvTrfl': '87',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '01 ',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.55',
'timeMax': '10.183',
'timeMin': '5.750'},
{'efcvTrfl': '30',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '01:00',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.625',
'timeMax': '10.183',
'timeMin': '6.600'},
{'efcvTrfl': '3',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '01:05',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.683333333333334',
'timeMax': '8.250',
'timeMin': '7.500'}]}
  • json 객체에 responses 함수를 이용하여 json형태의 file을 담고
  • cars : 내가 찾고 싶은 부분을 file의 형태에서 찾아서 넣는다.
  • file의 구조와 내가 찾고 싶은 부분을 알고 있어야 원하는 정보를 넣을 수 있다.

04.3 json file 에서 원하는 정보 빼오기

  • 알 수 없지만, realUnitTrtmVO 라는 tag? dictionarly에 접근하여
    정보를 빼보자.
1
cars = json["realUnitTrtmVO"]
out:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
[{'efcvTrfl': '18',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:25',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.466666666666667',
'timeMax': '9.216',
'timeMin': '5.800'},
{'efcvTrfl': '53',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:30',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.466666666666667',
'timeMax': '9.283',
'timeMin': '5.783'},
{'efcvTrfl': '14',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:35',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.416666666666667',
'timeMax': '8.400',
'timeMin': '6.050'},
{'efcvTrfl': '15',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:40',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.516666666666667',
'timeMax': '9.283',
'timeMin': '5.966'},
{'efcvTrfl': '41',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:45',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.5',
'timeMax': '8.800',
'timeMin': '5.750'},
{'efcvTrfl': '11',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:50',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.416666666666667',
'timeMax': '8.800',
'timeMin': '5.766'},
{'efcvTrfl': '8',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '00:55',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.433333333333334',
'timeMax': '8.350',
'timeMin': '5.750'},
{'efcvTrfl': '87',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '01 ',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.55',
'timeMax': '10.183',
'timeMin': '5.750'},
{'efcvTrfl': '30',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '01:00',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.625',
'timeMax': '10.183',
'timeMin': '6.600'},
{'efcvTrfl': '3',
'endUnitCode': '103 ',
'endUnitNm': '수원신갈',
'iEndUnitCode': None,
'iStartEndStdTypeCode': None,
'iStartUnitCode': None,
'numOfRows': None,
'pageNo': None,
'startEndStdTypeCode': '2',
'startEndStdTypeNm': '도착기준통행시간',
'startUnitCode': '101 ',
'startUnitNm': '서울',
'stdDate': '20220103',
'stdTime': '01:05',
'sumTmUnitTypeCode': None,
'tcsCarTypeCode': '1',
'tcsCarTypeDivCode': '1',
'tcsCarTypeDivName': '소형차',
'tcsCarTypeName': '1종',
'timeAvg': '7.683333333333334',
'timeMax': '8.250',
'timeMin': '7.500'}]

04.4 csv file로 출력

  • pandas를 이용하여 dictionarly, json file을 dataFrame, csv file로 변환
1
2
3
4
5
6
7
8
9
10
11
import pandas as pd
dt = []
for car in cars:
dic_df = {}
dic_df["data"] = car["stdDate"]
dic_df["time"] = car["stdTime"]
dic_df["destination"] = car["endUnitNm"]
dt.append(dic_df)

pd.DataFrame(dt).to_csv("temp.csv",index = False, encoding="euc-kr")

Encoding의 경우 해당 json file의 documents를 봐야함.

google과 같은 기업에서 API를 받아와서 사용 하는 것도 가능 하므로
앞으로 이 기술은 무궁무진한 발전 가능성이 있을 것으로 보임 ^^