24 Wed
(๋ถ๋ก) ์์ธ์ ์ฝ๋ก๋19 ๋ฐ์ํํฉ ๋ฐ์ดํฐ ์์ง
[1/7] ์์ธ์ ์ฝ๋ก๋ ๋ฐ์ํํฉ ๋ฐ์ดํฐ ์์ง ์ค๋นํ๊ธฐ
๋ฐ์ดํฐ ์์ง vs ํฌ๋กค๋ง
๋ฐ์ดํฐ ์์ง : ์น์ฌ์ดํธ์ ๋ด์ฉ์ ์ฝ์ด์ค๋ ๊ฒ, ์คํฌ๋ํ
ํฌ๋กค๋ง : ๊ฒ์์์ง์ด ํ์ดํผ๋งํฌ๋ฅผ ํ๊ณ ์น ํ์ด์ง์ ๋ด์ฉ์ ์ฝ์ด๊ฐ๋ ๊ฒ
ํ์ ๋๊ตฌ ์ค์น
request
: ์์ ๋ธ๋ผ์ฐ์ ๋ก ์น์ฌ์ดํธ๋ฅผ ์ฝ์ด์ค๋ ๋ชฉ์
beautifulsoup4
: ์ฝ์ด์จ ์น ์ฌ์ดํธ๋ฅผ ํด์ํ๋ ๋ชฉ์
tqdm
: ์ฌ๋ฌ ํ์ด์ง๋ฅผ ์ฝ์ด์ฌ ๋ ์งํ ์ํ๋ฅผ ํ์ธํ๋ ๋ชฉ์
์ค๋๊ฑธ๋ฆฌ๋ฉด์ ๋ฐ๋ณต๋๋ ์์ ์ ํ ๋ ์ฌ์ฉํ๋ฉด ์ข๋ค.
[2/7] ๋ฐ์ดํฐ ์์ง ์ ๋ก๋ด๋ฐฐ์ ํ์ค, ์ ์๊ถ, ๋ฌด๋ฆฌํ ๋คํธ์ํฌ ์์ฒญ ํ์ธํ๊ธฐ
์์งํด๋ ๋๋ ํ์ด์ง์ธ์ง ํ์ธํ๊ธฐ
๋ก๋ด ๋ฐฐ์ ํ์ค robots.txt
์น ์ฌ์ดํธ์ ๋ก๋ด์ด ์ ๊ทผํ๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํ ๊ท์ฝ
๊ถ๊ณ ์์ด๋ฉฐ, ์ ๊ทผ ๋ฐฉ์ง ์ค์ ์ ํ๋๋ผ๋ ๋ค๋ฅธ ์ฌ๋๋ค์ด ์ ๊ทผํ ์ ์๋ค.
์ ์๊ถ
๋ฌด๋ฆฌํ ๋คํธ์ํฌ ์์ฒญ
์์ธ์ ์ฌ์ดํธ robots.txt ํ์ธํ๊ธฐ

๊ฐ์ ธ๊ฐ๋ ๋๋ค๊ณ ํ์ฉ๋์ด ์์
์ฌ์ดํธ ๋งต๋ ๋ณผ ์ ์๋ค
๋ค์ด๋ฒ ์ฌ์ดํธ robots.txt ํ์ธํ๊ธฐ
User-agent: *
Disallow: /
Allow : /$
๊ตฌ๊ธ์์ ๊ฒ์์ด ์ ์๋๋ ์ด์ ๋
/
๋ฃจํธ ๊ฒฝ๋ก ์ดํ์ ๋ชจ๋ ์ ๋ณด๋ฅผ ๊ฑฐ๋ถํ๊ธฐ ๋๋ฌธ/$
๋ ๋ฉ์ธ ํ์ด์ง๋ ์ฝ์ด๋ ๋๋ค๋ ๋ป
์ ์๊ถ ํ์ธํ๊ธฐ
์์ธ์๋ ๊ณต๊ณต๋๋ฆฌ ์ ์๊ถ
๋ณ๋์ ํ๋ฝ์์ด ์์ ์ด์ฉ์ด ๊ฐ๋ฅํ๋ค
๋ฌด๋ฆฌํ ๋คํธ์ํฌ ์์ฒญ
์ฌ๋ฌ ํ์ด์ง๋ฅผ ํ ๋ฒ์ ์ฝ์ด์ค๋ฉด DDOS ๊ณต๊ฒฉ์ผ๋ก ์์ฌ๋ฐ์ ์ ์๋ค.
๋ฐ๋ผ์ time.sleep() ์ผ๋ก ๊ฐ๊ฒฉ์ ๋๊ณ ๊ฐ์ ธ์จ๋ค.
๋ฐ์ดํฐ ์์ง ๋ฐฉ๋ฒ
์์ง ํ๊ณ ์ ํ๋ ํ์ด์ง์ URL์ ์์๋ณธ๋ค
ํ์ด์ฌ์ ์์ ๋ธ๋ผ์ฐ์ requests๋ฅผ ํตํด URL์ ์ ๊ทผํ๋ค.
response.status_code๊ฐ 200 OK๋ผ๋ฉด ์ ์ ์๋ต
request์ response๊ฐ์์ response.txt๋ง ๋ฐ์์จ๋ค.
html ํ ์คํธ๋ฅผ bs(response.txt, 'html.parse')๋ก ํด์ํ๋ค.
soup.select๋ฅผ ํตํด ์ํ๋ ํ๊ทธ์ ์ ๊ทผํ๋ค.
๋ชฉ๋ก์ ๋ฐ์์จ๋ค.
๋ชฉ๋ก์์ ํ์ ๋ฐ์์จ๋ค.
ํ์ ๋ชจ์ ๋ฐ์ดํฐํ๋ ์์ผ๋ก ๋ง๋ ๋ค.
๋ฐ์ดํฐ์ ์์น
๊ฐ๋ฐ์ ์ฝ๋๋ก ์์ค ์ฝ๋๋ฅผ ๋ณด๋ฉด html ํ๊ทธ์ ํด๋น ๋ด์ฉ์ด ์์ง๋ง read_html๋ก ์ฝ์ด์ฌ ์ ์๋ค.
[3/7] ๋ธ๋ผ์ฐ์ ์ ๋คํธ์ํฌํญ๊ณผ JSON ํ์ผํ์ ์ดํดํ๊ธฐ
๋ฐ์ดํฐ ์์ง
๋ณดํต ๋ณด์ด์ง ์๋ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ธฐ ์ํด ์ ๋ ๋์์ ์ฌ์ฉ
๋ธ๋ผ์ฐ์ ๋์ ์๋ฆฌ๋ฅผ ์๋ฉด ์ ๋ ๋์์ ์ฌ์ฉํ์ง ์์๋ ์์ง ๊ฐ๋ฅ
๊ฐ๋ฐ์ ๋๊ตฌ - Network - XHR - URL - Preview ์์๋ฅผ ํตํด JSON ํ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ํ์ธํ ์ ์๋ค.
JSON
์ ์ด์จ, JavaScript Object Notation
์์ฑ-๊ฐ ์๋๋ ํค-๊ฐ ์์ผ๋ก ์ด๋ฃจ์ด์ง ๋ฐ์ดํฐ ์ค๋ธ์ ํธ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๊ฐ๋ฐฉํ ํ์ค ํฌ๋งท
ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ํ๋ซํผ์ ๋ ๋ฆฝ์ ์ด์ด์ ์๋ง์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์ ์ฌ์ฉํ ์ ์๋ค.
ํ์ด์ฌ์ ํ๋ค์ค๋ JSON์ ์ฝ๊ณ ์ธ ์ ์๋ค.
์์ธ ์ฝ๋ก๋ ๋ฐ์ํํฉ ๋ฐ์ดํฐ ์์ง ์์
ํ์ด์ง๋ณ ๋ฐ์ดํฐ ์์ง
์ ์ฒด ํ์ด์ง ์์ง
1๋ฒ์ ๋ฐ๋ณต๋ฌธ์ ํตํด์ ์งํ
pd.concat
์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ํ๋๋ก ๋ณํฉ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ => html ํ๊ทธ ์ ๊ฑฐ
to_csv
๋ก ์ ์ฒด ๋ฐ์ดํฐ ๋ณํฉpd.read_csv
๋ก ๋ฐ์ดํฐ๊ฐ ์ ์ ์ฅ๋์๋์ง ์ฝ์ด์์ ํ์ธ์์ง ๋, ๋ถ์ ์์
[4/7] ๊ธฐ์กด์ read_html ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ฌ ์ ์๋ ์ด์ ์ ๊ธฐ์กด์ ์์ง๋ฐฉ๋ฒ
์ฝ๋ก๋ ํ์ง์๊ฐ ๋์ด๋๋ฉด์ ๊ณต๊ฐ ๋ฐฉ์์ด ๋ฌ๋ผ์ง
์ด์ ์ฝ๋
# ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ถ๋ฌ์ต๋๋ค.
import pandas as pd
import numpy as np
# ํฌ๋กค๋ง์ผ๋ก ๊ฐ์ ธ์ฌ url ์ฃผ์๋ฅผ ์
๋ ฅํฉ๋๋ค.
url = "http://www.seoul.go.kr/coronaV/coronaStatus.do"
url
'http://www.seoul.go.kr/coronaV/coronaStatus.do'
"""
11์ ์ค์ ์ดํ ํ์ง์๊ฐ ์ฆ๊ฐํ๋ฉด์ ๋ฐ์ดํฐ ๊ณต๊ฐ ๋ฐฉ์์ด ๋ฌ๋ผ์ ธ์ pandas ์ read_html ๋ก๋ ๋ถ๋ฌ์ฌ ์๊ฐ ์์ต๋๋ค.
๊ธฐ์กด์ read_html ๋ก๋ ์ปฌ๋ผ๋ช
์ ๋ถ๋ฌ์ค๊ณ ๋ฐ์ดํฐ๋ requests ๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์ฝ์ด์ต๋๋ค.
"""
'\n11์ ์ค์ ์ดํ ํ์ง์๊ฐ ์ฆ๊ฐํ๋ฉด์ ๋ฐ์ดํฐ ๊ณต๊ฐ ๋ฐฉ์์ด ๋ฌ๋ผ์ ธ์ pandas ์ read_html ๋ก๋ ๋ถ๋ฌ์ฌ ์๊ฐ ์์ต๋๋ค.\n๊ธฐ์กด์ read_html ๋ก๋ ์ปฌ๋ผ๋ช
์ ๋ถ๋ฌ์ค๊ณ ๋ฐ์ดํฐ๋ requests ๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์ฝ์ด์ต๋๋ค.\n'
# ํ๋ค์ค์ read_html ์ ํตํด ์ url์ ์๋ ๋ถ๋ฌ์ต๋๋ค.
table = pd.read_html(url)
len(table)
6
# read_html ์ ์ฌ์ดํธ ๋ด์ html ํ๊ทธ๋ฅผ ๋ถ๋ฌ์ต๋๋ค.
table[0]
๊ฐ๋จ๊ตฌ
๊ฐ๋๊ตฌ
๊ฐ๋ถ๊ตฌ
๊ฐ์๊ตฌ
๊ด์ ๊ตฌ
๊ด์ง๊ตฌ
๊ตฌ๋ก๊ตฌ
๊ธ์ฒ๊ตฌ
๋ ธ์๊ตฌ
๋๋ด๊ตฌ
๋๋๋ฌธ๊ตฌ
๋์๊ตฌ
๋งํฌ๊ตฌ
0
1441
1100
817
1732
1437
947
1117
483
1366
972
1114
1279
1007
1
+13
+5
+4
+3
+3
+3
+5
+1
+2
+2
+1
+6
+2
2
์๋๋ฌธ๊ตฌ
์์ด๊ตฌ
์ฑ๋๊ตฌ
์ฑ๋ถ๊ตฌ
์กํ๊ตฌ
์์ฒ๊ตฌ
์๋ฑํฌ๊ตฌ
์ฉ์ฐ๊ตฌ
์ํ๊ตฌ
์ข ๋ก๊ตฌ
์ค๊ตฌ
์ค๋๊ตฌ
๊ธฐํ
3
796
1174
807
1332
1717
1170
1147
864
1308
596
501
1292
3460
4
+1
+2
+4
+4
+7
+4
+3
+5
+9
0
+6
+1
+1
# table ๋ณ์ ์์ ์๋ table ํ๊ทธ์ ๊ฐ์ ํ๋์ฉ ์ฝ์ด๋ณด๋ฉฐ ํ์ง์ ๋ชฉ๋ก์ด ์๋ ํ
์ด๋ธ์ ๊ฐ์ ธ์ต๋๋ค.
table[1]
๊ฐ๋จ๊ตฌ
๊ฐ๋๊ตฌ
๊ฐ๋ถ๊ตฌ
๊ฐ์๊ตฌ
๊ด์ ๊ตฌ
๊ด์ง๊ตฌ
0
1441
1100
817
1732
1437
947
1
+13
+5
+4
+3
+3
+3
2
๊ตฌ๋ก๊ตฌ
๊ธ์ฒ๊ตฌ
๋ ธ์๊ตฌ
๋๋ด๊ตฌ
๋๋๋ฌธ๊ตฌ
๋์๊ตฌ
3
1117
483
1366
972
1114
1279
4
+5
+1
+2
+2
+1
+6
5
๋งํฌ๊ตฌ
์๋๋ฌธ๊ตฌ
์์ด๊ตฌ
์ฑ๋๊ตฌ
์ฑ๋ถ๊ตฌ
์กํ๊ตฌ
6
1007
796
1174
807
1332
1717
7
+2
+1
+2
+4
+4
+7
8
์์ฒ๊ตฌ
์๋ฑํฌ๊ตฌ
์ฉ์ฐ๊ตฌ
์ํ๊ตฌ
์ข ๋ก๊ตฌ
์ค๊ตฌ
9
1170
1147
864
1308
596
501
10
+4
+3
+5
+9
0
+6
11
์ค๋๊ตฌ
๊ธฐํ
NaN
NaN
NaN
NaN
12
1292
3460
NaN
NaN
NaN
NaN
13
+1
+1
NaN
NaN
NaN
NaN
# ๋ฏธ๋ฆฌ๋ณด๊ธฐ ํฉ๋๋ค.
df = table[3]
df.head()
์ฐ๋ฒ
ํ์
ํ์ง์ผ
๊ฑฐ์ฃผ์ง
์ฌํ๋ ฅ
์ ์ด๋ ฅ
ํด์ํํฉ
๋ฐ๋ ์ฝ๋
import requests
# f-string
url = "https://news.seoul.go.kr/api/27/getCorona19Status/get_status_ajax.php?draw=1"
# url = f"{url}&columns%5B0%5D%5Bdata%5D=0&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=1&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=true&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=2&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=3&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=true&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=4&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=true&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B5%5D%5Bdata%5D=5&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=true&columns%5B5%5D%5Borderable%5D=true&columns%5B5%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B5%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B6%5D%5Bdata%5D=6&columns%5B6%5D%5Bname%5D=&columns%5B6%5D%5Bsearchable%5D=true&columns%5B6%5D%5Borderable%5D=true&columns%5B6%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B6%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=desc"
url = f"{url}&start=0&length=100"
# "&search%5Bvalue%5D=&search%5Bregex%5D=true&_=1606633538547"
url
'https://news.seoul.go.kr/api/27/getCorona19Status/get_status_ajax.php?draw=1&start=0&length=100'
url์ด ๋๋ฌด ๊ธธ๊ธฐ ๋๋ฌธ์ f-string์ ์ด์ฉํ์ฌ ์๋ฅธ๋ค
์ค์ํ ๋ถ๋ถ์
draw
์start
draw
๋ ํ์ด์ง ๋ฒํธstart
๋ ํ ์ด๋ธ ๋ฒํธ
response = requests.get(url)
data_json = response.json()
# pd.DataFrame(data_json["data"])
requests.get
์ ํตํด url ์ ๊ฐ์ ธ์ค๊ณ ์ด๋ฅผ json ํํ๋ก ๋ณํ
records_total = data_json['recordsTotal']
records_total
10976
end_page = round(records_total / 100) + 1
end_page
111
ํ์ฌ๋ 10976๋ช , 111 ํ์ด์ง
2021.03.23
data = data_json["data"]
# data
pd.DataFrame(data)
0
1
2
3
4
5
6
0
<p class='corona19_no'>30976</p>
99355
2021-03-22
์ฉ์ฐ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
1
<p class='corona19_no'>30975</p>
99325
2021-03-22
๋๋ด๊ตฌ
-
ํ์๋ ํ์ง์ ์ ์ด
<b class=''></b>
2
<p class='corona19_no'>30974</p>
99409
2021-03-22
์๋ฑํฌ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
3
<p class='corona19_no'>30973</p>
99415
2021-03-22
๊ด์ง๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
4
<p class='corona19_no'>30972</p>
99394
2021-03-22
๊ฐ๋ถ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
...
...
...
...
...
...
...
...
95
<p class='corona19_no'>30881</p>
99100
2021-03-22
๋งํฌ๊ตฌ
-
ํ์๋ ํ์ง์ ์ ์ด
<b class=''></b>
96
<p class='corona19_no'>30880</p>
99095
2021-03-22
๋งํฌ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
97
<p class='corona19_no'>30879</p>
98120
2021-03-20
์ค๊ตฌ
-
๊ธฐํ ํ์ง์ ์ ์ด
<b class=''></b>
98
<p class='corona19_no'>30878</p>
99016
2021-03-21
๊ฐ๋ถ๊ตฌ
-
๊ธฐํ ํ์ง์ ์ ์ด
<b class=''></b>
99
<p class='corona19_no'>30877</p>
98966
2021-03-21
๋งํฌ๊ตฌ
-
๊ธฐํ ํ์ง์ ์ ์ด
<b class=''></b>
100 rows ร 7 columns
1~6์ ์ฐ๋ฒ, ํ์, ํ์ง์ผ ๋ฑ์ ์ ๋ณด
html ํ๊ทธ๊ฐ ์๋ ๊ฒ์ผ๋ก ๋ณด์ ์ ์ฒ๋ฆฌ ํ์
ํด๋น ํ์ด์ง๋ 100๊ฐ์ ํ ์ด๋ธ๋ง ๊ฐ์ง๊ณ ์๊ณ ์ด๋ฅผ ๋ฐ๋ณตํด์ ๊ฐ์ง๊ณ ์ค๊ธฐ ์ํด ํจ์ ํ์
[5/7] ๋คํธ์ํฌ ํญ์ ๋ณด๋ ๋ฐฉ๋ฒ๊ณผ ์์งํ URL ์ฐพ๊ณ ์์ฒญํ๊ธฐ
ํจ์๋ก ๋ง๋ค๊ธฐ
def get_seoul_covid19_100(page_no):
"""
page_no : ์
๋ ฅ๊ฐ์ผ๋ก ํ์ด์ง ๋ฒํธ๋ฅผ ์
๋ ฅํ๋ฉด ํด๋น ๋ฒํธ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด
start_no : ์
๋ ฅ๋ฐ์ page_no๋ก ์์ ๋ฒํธ๋ฅผ ์๋ฏธ
"""
start_no = (page_no - 1) * 100
url = f"https://news.seoul.go.kr/api/27/getCorona19Status/get_status_ajax.php?draw={page_no}"
url = f"{url}&order%5B0%5D%5Bdir%5D=desc&start={start_no}&length=100"
response = requests.get(url)
data_json = response.json()
return data_json
# ๋ฐ์ดํฐ๊ฐ ์ ๋
# get_seoul_covid19_100(3)
# ๋ฐ์ดํฐ๊ฐ ์์ ๋
get_seoul_covid19_100(-1)
{'data': [], 'draw': -1, 'recordsFiltered': 10976, 'recordsTotal': 10976}
๋ฐ์ดํฐ๊ฐ ์์ด๋ ์ ๊ฐ์ ธ์ค๊ณ , ๋ฐ์ดํฐ๊ฐ ์์ด๋
[]
๋ฅผ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ์์ธ์ฒ๋ฆฌ๊ฐ ํ์ ์์์๋ฌ๊ฐ ๋์ง ์๊ธฐ ๋๋ฌธ์ ์์ธ์ฒ๋ฆฌ๊ฐ ํ์ ์์ง๋ง, ํ ํ์๋ ์์
[6/7] ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ์์งํ๋ ํจ์๋ฅผ ๋ง๋ค๊ณ ๋ฐ๋ณต๋ฌธ์ผ๋ก ์ ์ฒด ๋ฐ์ดํฐ ์์งํ๊ธฐ
์ ์ฒด ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
tqdm
์ค๋ ๊ฑธ๋ฆฌ๋ ์์ ์ ์งํ์ํ๋ฅผ ํ์ํด ์ค๋๋ค.
๋ณ๋์ ์ค์น๊ฐ ํ์ ํฉ๋๋ค.
!pip install tqdm
์ผ๋ก ์ค์น๊ฐ ํ์ํฉ๋๋ค.
# !pip install tqdm
# time.sleep ์ผ๋ก ์์ฐจ๋ฅผ ๋๊ธฐ ์ํด
import time
# tqdm : ์งํ์ํ๋ฅผ ํ์ํ๊ธฐ ์ํด
from tqdm import trange
# # ์ฃผ์์ฒ๋ฆฌ : ctrl + /
# page_list = []
# for page_no in trange(1, 4):
# one_page = get_seoul_covid19_100(page_no)
# if len(one_page["data"]) > 0:
# one_page = pd.DataFrame(one_page["data"])
# page_list.append(one_page)
# time.sleep(0.5)
# else:
# break
# page_list
# pd.concat(page_list)
์์ฌ์ ํผํ๊ธฐ ์ํด
time
์ฌ์ฉtrange
๋ฅผ ์ฐ๋ฉด ์งํ์ํฉ์ ์๊ฐ์ ์ผ๋ก ๋ณผ ์ ์์
# ์ ์ฒด ํ์ด์ง๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ ์ ์ผ๋ถ ํ์ด์ง๋ง ์คํ
page_list = []
# ๋ฐ์ดํฐ๊ฐ ์ ๋๋ก ๋ก๋ ๋๋์ง ์๋ถ๋ถ 3ํ์ด์ง ์ ๋๋ง ํ์ธํ๊ณ ์ ์ฒดํ์ด์ง๋ฅผ ๊ฐ์ ธ์ค๋ก ํฉ๋๋ค.
# ์ฒ์๋ถํฐ ์ ์ฒด ํ์ด์ง๋ฅผ ์์งํ๋ฉด ์ค๊ฐ์ ์ค๋ฅ๊ฐ ๋๋ ์ฐพ๊ธฐ๊ฐ ์ด๋ ต์ต๋๋ค.
# ์ผ๋ถ๋ง ์ฐ์ ๊ฐ์ ธ์ ๋ณด๊ณ ์ ๋์ํ๋ค๋ฉด ์ ์ฒด๋ฅผ ๊ฐ์ ธ์ค๋๋ก ํฉ๋๋ค.
all_page = 3
for page_no in trange(all_page + 1):
one_page = get_seoul_covid19_100(page_no)
one_page = pd.DataFrame(one_page["data"])
page_list.append(one_page)
# ์๋ฒ์ ํ๋ฒ์ ๋๋ฌด ๋ง์์์ฒญ์ ๋ณด๋ด๋ฉด ์๋ฒ์ ๋ถ๋ด์ด ๋ฉ๋๋ค.
# ์๋ฒ์ ๋ถ๋ด์ ์ฃผ์ง ์๊ธฐ ์์ 0.5์ด์ฉ ์ฌ์๋ค ๊ฐ์ ธ์ต๋๋ค.
time.sleep(0.5)
100%|โโโโโโโโโโ| 4/4 [00:05<00:00, 1.43s/it]
# ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๊ฐ ๋ง๋์ง ํ์ธ ๋๋ฌด ๋ง์ ์ ์๊ธฐ ๋๋ฌธ์ ์ฌ๋ผ์ด์ฑ์ผ๋ก ์๋ผ์ ๋ณด๊ธฐ
pd.concat(page_list)
0
1
2
3
4
5
6
0
<p class='corona19_no'>30976</p>
99355
2021-03-22
์ฉ์ฐ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
1
<p class='corona19_no'>30975</p>
99325
2021-03-22
๋๋ด๊ตฌ
-
ํ์๋ ํ์ง์ ์ ์ด
<b class=''></b>
2
<p class='corona19_no'>30974</p>
99409
2021-03-22
์๋ฑํฌ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
3
<p class='corona19_no'>30973</p>
99415
2021-03-22
๊ด์ง๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
4
<p class='corona19_no'>30972</p>
99394
2021-03-22
๊ฐ๋ถ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
...
...
...
...
...
...
...
...
95
<p class='corona19_no'>30681</p>
98407
2021-03-20
์ฑ๋ถ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
96
<p class='corona19_no'>30680</p>
98373
2021-03-20
๋๋๋ฌธ๊ตฌ
-
๊ธฐํ ํ์ง์ ์ ์ด
<b class=''></b>
97
<p class='corona19_no'>30679</p>
98386
2021-03-20
๊ฐ๋ถ๊ตฌ
-
๊ธฐํ ํ์ง์ ์ ์ด
<b class=''></b>
98
<p class='corona19_no'>30678</p>
98291
2021-03-20
์ฑ๋ถ๊ตฌ
-
๋ ธ์๊ตฌ ์์ฌ ๊ณต๊ณต๊ธฐ๊ด ๊ด๋ จ
<b class=''></b>
99
<p class='corona19_no'>30677</p>
98400
2021-03-20
์ฑ๋ถ๊ตฌ
-
ํ์๋ ํ์ง์ ์ ์ด
<b class=''></b>
300 rows ร 7 columns
def get_multi_page_list(start_page, end_page = 80):
# ๋ฐ์ดํฐ๊ฐ ์ ๋๋ก ๋ก๋ ๋๋์ง ์๋ถ๋ถ 3ํ์ด์ง ์ ๋๋ง ํ์ธํ๊ณ ์ ์ฒดํ์ด์ง๋ฅผ ๊ฐ์ ธ์ค๋ก ํฉ๋๋ค.
page_list = []
for page_no in trange(start_page, end_page + 1):
one_page = get_seoul_covid19_100(page_no)
if len(one_page["data"]) > 0:
one_page = pd.DataFrame(one_page["data"])
page_list.append(one_page)
# ์๋ฒ์ ํ๋ฒ์ ๋๋ฌด ๋ง์์์ฒญ์ ๋ณด๋ด๋ฉด ์๋ฒ์ ๋ถ๋ด์ด ๋ฉ๋๋ค.
# ์๋ฒ์ ๋ถ๋ด์ ์ฃผ์ง ์๊ธฐ ์์ 0.5์ด์ฉ ์ฌ์๋ค ๊ฐ์ ธ์ต๋๋ค.
time.sleep(0.5)
else:
# ์์ง๋ ๊ฐ์ด ์๋ค๋ฉด False๋ฅผ ๋ฐํํฉ๋๋ค.
# False ๋ฐํ ์ ์์งํ ๋ฆฌ์คํธ๋ฅผ ๋ฐํํ๋๋ก ํฉ๋๋ค.
return page_list
return page_list
one_page["data"]
๊ฐ 0์ดํ๋ฉด ValueError๊ฐ ๋ฐ์ํ๋ฏ๋ก ์์ธ์ฒ๋ฆฌ
# ๋ฐ๋ก ์ค์ ํ์ง ์์ผ๋ฉด end_page ๋ณ์์ ๋ค์ด์๋ ์ซ์๊ฐ ๋ง์ง๋ง ํ์ด์ง๊ฐ ๋ฉ๋๋ค.
end_page
111
# ์์ํ์ด์ง์ ๋ํ์ด์ง๋ฅผ ๊ผญ ํ์ธํด ์ฃผ์ธ์.
start_page = 1
# end_page = 88
page_list = get_multi_page_list(start_page, end_page)
# ๋ฐ์ดํฐ๊ฐ ๋๋ฌด ๋ง๊ธฐ ๋๋ฌธ์ ์ฌ๋ผ์ด์ฑ์ผ๋ก 1๊ฐ๋ง ๋ฏธ๋ฆฌ๋ณด๊ธฐ
page_list[:1]
99%|โโโโโโโโโโ| 110/111 [02:53<00:01, 1.42s/it]
๊ฒฐ๊ณผ๋ ์๋ต, ๊ต์ฅํ ๋ง์
# concat์ ํตํด ํ๋์ ๋ฐ์ดํฐํ๋ ์์ผ๋ก ํฉ์ณ์ค๋๋ค.
df_all = pd.concat(page_list)
df_all.shape
(10976, 7)
df
์ฐ๋ฒ
ํ์
ํ์ง์ผ
๊ฑฐ์ฃผ์ง
์ฌํ๋ ฅ
์ ์ด๋ ฅ
ํด์ํํฉ
# read_html ๋ก ์ฝ์ด์จ 3๋ฒ์งธ ํ
์ด๋ธ์ ์ปฌ๋ผ๋ช
์ ์์งํ ๋ฐ์ดํฐ์ ์ปฌ๋ผ์ผ๋ก ์ฌ์ฉํฉ๋๋ค.
cols = df.columns.tolist()
cols
['์ฐ๋ฒ', 'ํ์', 'ํ์ง์ผ', '๊ฑฐ์ฃผ์ง', '์ฌํ๋ ฅ', '์ ์ด๋ ฅ', 'ํด์ํํฉ']
df_all.columns = cols
df_all.head()
์ฐ๋ฒ
ํ์
ํ์ง์ผ
๊ฑฐ์ฃผ์ง
์ฌํ๋ ฅ
์ ์ด๋ ฅ
ํด์ํํฉ
0
<p class='corona19_no'>30976</p>
99355
2021-03-22
์ฉ์ฐ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
1
<p class='corona19_no'>30975</p>
99325
2021-03-22
๋๋ด๊ตฌ
-
ํ์๋ ํ์ง์ ์ ์ด
<b class=''></b>
2
<p class='corona19_no'>30974</p>
99409
2021-03-22
์๋ฑํฌ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
3
<p class='corona19_no'>30973</p>
99415
2021-03-22
๊ด์ง๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
4
<p class='corona19_no'>30972</p>
99394
2021-03-22
๊ฐ๋ถ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
<b class=''></b>
df_all.shape
(10976, 7)
๋ฐ์ดํฐ๋ฅผ ํฉ์น๊ณ ์ปฌ๋ผ๋ช ์ ๋ถ์ฌํ๋ ๊ณผ์
10976๋ช ์ ๋ฐ์ดํฐ์ 7๊ฐ์ ์ปฌ๋ผ ์กด์ฌ
[7/7] ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ์ ์ ์ฅํ๊ณ ํ์ธํ๊ธฐ
๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
์ฐ๋ฒ๊ณผ ํด์ํํฉ
import re
def extract_number(num_string):
if type(num_string) == str:
num_string = num_string.replace("corona19", "")
num = re.sub("[^0-9]", "", num_string)
num = int(num)
return num
else:
return num_string
num_string = "<p class='corona19_no'>7625</p>"
extract_number(num_string)
7625
df_all["์ฐ๋ฒ"] = df_all["์ฐ๋ฒ"].map(extract_number)
df_all["์ฐ๋ฒ"].head()
0 30976
1 30975
2 30974
3 30973
4 30972
Name: ์ฐ๋ฒ, dtype: int64
def extract_hangeul(origin_text):
subtract_text = re.sub("[^๊ฐ-ํฃ]", "", origin_text)
return subtract_text
extract_hangeul("<b class='status1'>ํด์</b>")
'ํด์'
extract_hangeul("<b class='status2'>์ฌ๋ง</b>")
'์ฌ๋ง'
extract_hangeul("<b class=''></b>")
''
# ์ ๊ทํํ์์ผ๋ก ๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ๋ ์๊ณ str.contains๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ ์์ต๋๋ค.
# df_all["ํด์ํํฉ"] = df_all["ํด์ํํฉ"].map(extract_hangeul)
# df_all["ํด์ํํฉ"].value_counts()
df_all["ํด์ํํฉ"].value_counts()
<b class='status1'>ํด์</b> 8741
<b class='status1'></b> 1524
<b class=''></b> 514
<b class='status2'></b> 104
<b class='status2'>์ฌ๋ง</b> 93
Name: ํด์ํํฉ, dtype: int64
df_all.loc[df_all["ํด์ํํฉ"].str.contains("ํด์"), "ํด์ํํฉ"] = "ํด์"
df_all.loc[df_all["ํด์ํํฉ"].str.contains("์ฌ๋ง"), "ํด์ํํฉ"] = "์ฌ๋ง"
df_all.loc[~df_all["ํด์ํํฉ"].str.contains("ํด์|์ฌ๋ง"), "ํด์ํํฉ"] = np.nan
df_all["ํด์ํํฉ"].value_counts()
ํด์ 8741
์ฌ๋ง 93
Name: ํด์ํํฉ, dtype: int64
last_date = df_all.iloc[0]["ํ์ง์ผ"]
last_date
'2021-03-22'
# ๋ง์ง๋ง ํ์ง์ผ์ ํ์ผ๋ช
์ ์จ์ฃผ๊ธฐ ์ํด . ์ _ ๋ก ๋ณ๊ฒฝํฉ๋๋ค.
# ํ์ฅ์์ ๊ตฌ๋ถ์ด ์ฝ๊ฒ ๋๋๋ก _ ๋ก ๋ณ๊ฒฝํฉ๋๋ค.
date = last_date.replace(".", "_")
date
'2021-03-22'
# ํ์ผ๋ช
์ ๋ง๋ค์ด ์ค๋๋ค.
# file_name
file_name = f"seoul-covid19-{date}.csv"
file_name
'seoul-covid19-2021-03-22.csv'
# csv ํ์ผ๋ก ์ ์ฅํฉ๋๋ค.
df_all.to_csv(file_name, index=False)
# ์ ๋๋ก ์ ์ฅ๋์๋์ง ํ์ธํฉ๋๋ค.
pd.read_csv(file_name)
์ฐ๋ฒ
ํ์
ํ์ง์ผ
๊ฑฐ์ฃผ์ง
์ฌํ๋ ฅ
์ ์ด๋ ฅ
ํด์ํํฉ
0
30976
99355
2021-03-22
์ฉ์ฐ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
NaN
1
30975
99325
2021-03-22
๋๋ด๊ตฌ
-
ํ์๋ ํ์ง์ ์ ์ด
NaN
2
30974
99409
2021-03-22
์๋ฑํฌ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
NaN
3
30973
99415
2021-03-22
๊ด์ง๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
NaN
4
30972
99394
2021-03-22
๊ฐ๋ถ๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
NaN
...
...
...
...
...
...
...
...
10971
20005
63500
2021-01-03
๊ตฌ๋ก๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
์ฌ๋ง
10972
20004
63375
2021-01-03
ํ์๋
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
ํด์
10973
20003
64010
2021-01-03
์ฑ๋ถ๊ตฌ
-
ํ์๋ ํ์ง์ ์ ์ด
ํด์
10974
20002
64155
2021-01-03
๊ตฌ๋ก๊ตฌ
-
๊ฐ์ผ๊ฒฝ๋ก ์กฐ์ฌ์ค
ํด์
10975
20001
64083
2021-01-03
๊ฐ๋จ๊ตฌ
-
๊ธฐํ ํ์ง์ ์ ์ด
ํด์
10976 rows ร 7 columns
re
์ ๊ทํํ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ฒ๋ฆฌ๋ฅผ ํจ<p class='corona19_no'>30976</p> => 30976
[0-9]
๊ฐ ์๋๋ฉด ๋น ๋ฌธ์ ์ฒ๋ฆฌ ๊ทธ๋ฆฌ๊ณ corona19๋ ๋น ๋ฌธ์ ์ฒ๋ฆฌ
Last updated
Was this helpful?