본문 바로가기

코딩으로 익히는 Python/Pandas

[Python] 19. 기상청데이터 파싱 분석 및 시각화 : bs4 BeautifulSoup, urlib.request , REQ예제

728x90
반응형
SMALL
from bs4 import BeautifulSoup
import urllib.request as REQ
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
import matplotlib
import seaborn as sns
rc('font', family='AppleGothic')
plt.rcParams['axes.unicode_minus'] = False

중앙일보 전체기사xml

jurl = 'https://rss.joins.com/joins_news_list.xml'
response = REQ.urlopen( jurl )
soup = BeautifulSoup( response, 'html.parser') #html.parser , html5lib
soup
[OUT] :

<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0">
<channel>
<title>중앙일보 | 전체기사</title>
<link/>http://joongang.joins.com
		<language>ko</language>
<copyright>Copyright by JoongAng Ilbo Co., Ltd. All Rights Reserved</copyright>
<pubdate>2021-01-14 오후 6:26:10</pubdate>
<lastbuilddate>2021-01-14 오후 6:26:10</lastbuilddate>
<description>중앙일보 - 현장의 진실을 중앙에 두다.</description>
<image/>
<title>중앙일보</title>
<url>https://images.joins.com/common/rss08/JoongAngIlbo_CI_Signature.png</url>
<link/>http://joongang.joins.com
			
		<item>
<title><![CDATA[이규원 검사 ‘불법출금’ 의혹 수사‧감찰, 2년째 뭉개는 親 정권 검사들]]></title>
<link/><![CDATA[https://news.joins.com/article/23970731?cloc=rss-news-total_list]]>
<description><![CDATA[곽 의원이 같은 달인 2019년 7월 이 검사 등에 대해 허위공문서 작성 및 행사 등으로 고소한 데 따른 것이라는 게 대검 감찰부 측의 설명이다. ‘고소 사건 처분 경과’에 따라 감찰 민원은 공람종결 처분을 내렸다고 했는데, 정작 고소 사건은 1년 2개월이 지나서야 처음으로 고소자 측에 연락한 것이다. 한 수도권 검찰 ]]></description>
<author><![CDATA[김수민.강광우 기자]]></author>
<pubdate>2021-01-14T18:23:31+09:00</pubdate>
</item>
<item>
...

 

# soup.select('selector')
for item in soup.select('item'):
    print("기사제목:", item.title.string)
    print('기사내용:', item.description.string)
    print("==================")
[OUT] :

기사제목: 이규원 검사 ‘불법출금’ 의혹 수사‧감찰, 2년째 뭉개는 親 정권 검사들
기사내용: 곽 의원이 같은 달인 2019년 7월 이 검사 등에 대해 허위공문서 작성 및 행사 등으로 고소한 데 따른 것이라는 게 대검 감찰부 측의 설명이다. ‘고소 사건 처분 경과’에 따라 감찰 민원은 공람종결 처분을 내렸다고 했는데, 정작 고소 사건은 1년 2개월이 지나서야 처음으로 고소자 측에 연락한 것이다. 한 수도권 검찰 
==================
기사제목: 쿠팡, 충주시와 농산물 판로확대 나서
기사내용: 쿠팡은 충주시와 충주시청에서 지역 우수 농특산품 홍보와 판로확대를 위한 업무협약(MOU)을 체결했다고14일 밝혔다. 쿠팡은 이번 협약으로 충주사과, 복숭아 등 충주시가 인증한 우수 농특산물을 직거래로 원활하게 공급받을 수 있게 됐다. 충주시는 지역 농민들의 농산물을 쿠팡 로켓프레시 새벽배송, 당일배송으로 간편
==================
기사제목: '서울시장 출마' 이종구 "안철수·오세훈·나경원은 옛 가요무대" 
기사내용: 4ㆍ7 서울시장 보궐선거 출마 의사를 밝힌 이종구 전 미래통합당(현 국민의힘) 의원이 "서울시의 당면 문제인 미친 집값을 잡고 세금 폭탄을 제거하는 소방수 역할을 하겠다"고 말했다. 그 이유에 대해 그는 "안철수 대표는 국민의힘이 추구하는 정체성과 맞지 않는다. 오세훈 전 시장은 앞뒤 안 맞는 언행을 한다. 나경원 
==================
기사제목: 법원은 ‘박원순 성추행’ 인정…경찰 부실 수사 논란 커졌다
기사내용: 5개월 넘게 박원순 시장의 성추행 의혹을 수사해놓고 사실관계를 밝히지 못하고 비서실 직원들의 강제추행 방조 혐의도 불기소 의견으로 넘긴 경찰을 두고 부실 수사 논란도 확산하고 있다. 14일 서울중앙지법 형사 31부(부장판사 조성필)는 동료 직원 B씨를 성폭행해 준강간치상 혐의로 기소된 전 서울시장 비서실 직원 A
==================
기사제목: 서울시, 부양의무제 전면 폐지…‘방배동 모자 비극’ 재발 막는다
기사내용: 서울시가 부양의무자의 소득·재산이 파악되면 공적 지원 제도에서 배제하는 ‘부양의무제’를 전면 폐지한다. 서울시는 14일 "방배동 모자의 비극이 다시는 없어야 한다는 반성과 성찰을 토대로 기존 복지 사각지대 발굴·지원 시스템을 재검토했다"며 "전국 최초로 부양의무제를 폐지할 것"이라고 밝혔다. 김선순 서울시 
==================
기사제목: CIA, 70년 숨긴 비밀문건 2700쪽 공개…UFO 비밀 풀릴까
기사내용: 13일(현지시간) 가디언 등에 따르면 미국 UFO 전문 웹사이트 블랙볼트 는 미확인비행현상과 관련해 CIA가 모은 정보 2700쪽의 문건 모음집을 지난 7일 공개했다. 블랙볼트가 입수해 공개한 비밀해제 문서 중엔 1991년 러시아에서 발생한 미스터리한 폭발 사고에 관해 CIA 관계자들이 논의한 문서가 담겼다. 이에 대해 CIA의
==================
기사제목: [뉴스픽] 대법원, 박근혜 국정 농단 최종 결론
기사내용: - 대법원, 박근혜 국정 농단 최종 결론 . - '밤 9시 이후 식당 내 취식금지' 풀리나 . - 코로나 피해 특고ㆍ프리랜서 지원금 받는다 .
==================
기사제목: 한화에너지, 프랑스 토탈과 美 신재생에너지 합작사 설립
기사내용: 한화에너지는 14일 "토탈과 합작사를 설립해 미국 시장에서 태양광 발전 사업을 공동으로 진행한다"며 "토탈이 한화에너지의 미국 자회사인 174파워글로벌(Power Global)의 사업권에 투자하자는 방식"이라고 밝혔다. 정인섭 한화에너지 대표이사는 "코로나19로 어느 때보다 시장의 불확실성이 높아진 상황에서 이번 합작사 
==================
기사제목: 원자력학회 “이낙연 ‘원전마피아 결탁’ 망언은 명예훼손…공식 사과하라”
기사내용: 한국원자력학회는 14일 "‘원전 마피아’ 망언으로 원자력 종사자의 명예를 훼손한 이낙연 더불어민주당 대표에게 공식 사과를 요구한다"고 밝혔다. 또한 "원전 마피아의 결탁이 있었나 밝혀야 한다"는 이 대표의 발언에 대해선 "원자력계를 범죄 집단과 동일시하는 망언"이라며 "에너지자립을 위해 60여년간 헌신하여 세계
==================
기사제목: '연중라이브' 열애 손예진♥현빈, 시간 거스른 사랑의 흔적
기사내용: 손예진과 현빈의 그 때 그 꿀 떨어졌던 인터뷰 영상을 다시 꺼낸다. 새해 첫날을 뜨겁게 달군 2021년 첫 스캔들의 주인공 현빈·손예진 커플의 시간을 거스른 사랑의 흔적들과 2018년 '연예가중계' 인터뷰 당시 보여준 남다른 핑크빛 기류까지 모두 공개될 예정이다. 또한 2012년 연인 관계로 발전해 9년째 사랑을 키워가고
==================
기사제목: 정권 말 '알박기 낙하산' 내려오나…올해 공공기관장 절반 이상 교체
기사내용: 공공기관장 절반 이상이 올해 공석 혹은 임기만료로 대거 교체된다. 특히 이번에는 사실상 문재인 정부 임기 내 마지막 공공기관장 인사가 될 가능성이 높다. 조해진 국민의힘 의원은 "문재인 대통령의 공약과는 반대로 지금 정권에서 낙하산 인사는 더 많아지고 있다"며 "다음에 혹시라도 정권이 바뀔 수도 있으니 이번에 
==================

기상청 데이터 xml

kurl ='http://www.weather.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=109'
kresponse = REQ.urlopen( kurl )
ksoup = BeautifulSoup( kresponse, 'html.parser') #html.parser , html5lib
ksoup
[OUT] :

<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0">
<channel>
<title>기상청 육상 중기예보</title>
<link/>http://www.kma.go.kr/weather/forecast/mid-term_02.jsp
<description>기상청 날씨 웹서비스</description>
<language>ko</language>
<generator>기상청</generator>
<pubdate>2021년 01월 14일 (목)요일 18:00</pubdate>
<item>
<author>기상청</author>
<category>육상중기예보</category>
<title>서울,경기도 육상 중기예보 - 2021년 01월 14일 (목)요일 18:00 발표</title>
<link/>http://www.kma.go.kr/weather/forecast/mid-term_02.jsp
<guid>http://www.kma.go.kr/weather/forecast/mid-term_02.jsp</guid>
<description>
<header>
<title>서울,경기도 육상중기예보</title>
<tm>202101141800</tm>
<wf><![CDATA[○ (강수) 17일(일) 오후와 18일(월) 오전에는 눈이 내리겠습니다.<br />          한편, 17일(일)~18일(월)은 다소 많은 눈이 쌓일 가능성이 있으니, 앞으로 발표되는 기상정보를 참고하기 바랍니다.<br />○ (기온) 17일 아침 기온은 -16~-9도, 낮 기온은 -3~-1도로 오늘(14일, 아침 기온 -10~-3도, 낮 기온 6~10도)보다 낮아 춥겠습니다. <br />          18일(월)~24일(일)의 아침 기온은 -13~1도, 낮 기온은 -3~6도로 평년(아침 기온 -9~-5도, 낮 기온 1~4도)과 비슷하겠습니다.      <br />○ (해상) 서해중부해상의 물결은 17일(일)은 1.0~3.5m로 높게 일겠고 바람도 강하게 불겠으며, 그 밖의 날은 0.5~2.5m로 일겠습니다.<br />○ (주말전망) 16일(토)은 구름많다가 아침부터 차차 맑아지겠고, 17일(일)은 맑다가 오후에 구름많고 눈이 내리겠습니다.<br />              아침 기온은 -16~-6도, 낮 기온은 -3~-1도의 분포가 되겠습니다. 특히, 17일(일) 아침기온은 대부분 지역에서 -10도 이하로 떨어져 춥겠습니다.]]></wf>
</header>
<body>
<location wl_ver="3">
<province>서울ㆍ인천ㆍ경기도</province>
<city>서울</city>
<data>
<mode>A02</mode>
<tmef>2021-01-17 00:00</tmef>
<wf>맑음</wf>
...

 

#도시만 출력하시오
for location in ksoup.select('location'):
    print(location.city.string)
[OUT] :

서울
인천
수원
파주
이천
평택
백령도
과천
광명
강화
김포
시흥
안산
부천
의정부
고양
양주
동두천
연천
포천
가평
구리
남양주
양평
하남
안양
오산
화성
성남
의왕
군포
안성
용인
광주
여주

 

for location in ksoup.select('location'):
    print(location.city.string)
    print("======================")
    for data in location.select('data'):
        print('날짜:',  data.tmef.string )
        print('날씨 : ',data.wf.string)
        print('최저 : ',data.tmn.text)
        print('최고 : ',data.tmx.text)
        print("--------------------------")
[OUT] :

서울
======================
날짜: 2021-01-17 00:00
날씨 :  맑음
최저 :  -11
최고 :  -2
--------------------------
날짜: 2021-01-17 12:00
날씨 :  구름많고 눈
최저 :  -11
최고 :  -2
--------------------------
날짜: 2021-01-18 00:00
날씨 :  구름많고 눈
최저 :  -2
최고 :  4
--------------------------
날짜: 2021-01-18 12:00
날씨 :  맑음
최저 :  -2
최고 :  4
--------------------------
날짜: 2021-01-19 00:00
날씨 :  맑음
최저 :  -11
최고 :  -1
--------------------------
날짜: 2021-01-19 12:00
날씨 :  맑음
최저 :  -11
최고 :  -1
--------------------------
...

 

kList = []
for location in ksoup.select('location'):
    for data in location.select('data'):
        kList.append( {'도시':location.city.string,
                      '날짜':data.tmef.string,
                      '날씨':data.wf.string,
                      '최저':int(data.tmn.string),
                      '최고':int(data.tmx.string)}  )
kList
[OUT] :

[{'도시': '서울', '날짜': '2021-01-17 00:00', '날씨': '맑음', '최저': -11, '최고': -2},
 {'도시': '서울', '날짜': '2021-01-17 12:00', '날씨': '구름많고 눈', '최저': -11, '최고': -2},
 {'도시': '서울', '날짜': '2021-01-18 00:00', '날씨': '구름많고 눈', '최저': -2, '최고': 4},
 {'도시': '서울', '날짜': '2021-01-18 12:00', '날씨': '맑음', '최저': -2, '최고': 4},
 {'도시': '서울', '날짜': '2021-01-19 00:00', '날씨': '맑음', '최저': -11, '최고': -1},
 {'도시': '서울', '날짜': '2021-01-19 12:00', '날씨': '맑음', '최저': -11, '최고': -1},
 {'도시': '서울', '날짜': '2021-01-20 00:00', '날씨': '맑음', '최저': -8, '최고': 3},
 {'도시': '서울', '날짜': '2021-01-20 12:00', '날씨': '구름많음', '최저': -8, '최고': 3},
 {'도시': '서울', '날짜': '2021-01-21 00:00', '날씨': '구름많음', '최저': -3, '최고': 5},
 {'도시': '서울', '날짜': '2021-01-21 12:00', '날씨': '흐림', '최저': -3, '최고': 5},
 {'도시': '서울', '날짜': '2021-01-22 00:00', '날씨': '흐림', '최저': 1, '최고': 5},
 {'도시': '서울', '날짜': '2021-01-23 00:00', '날씨': '흐림', '최저': -1, '최고': 4},
 {'도시': '서울', '날짜': '2021-01-24 00:00', '날씨': '흐림', '최저': -2, '최고': 3},
 {'도시': '인천', '날짜': '2021-01-17 00:00', '날씨': '맑음', '최저': -9, '최고': -2},
 {'도시': '인천', '날짜': '2021-01-17 12:00', '날씨': '구름많고 눈', '최저': -9, '최고': -2},
 {'도시': '인천', '날짜': '2021-01-18 00:00', '날씨': '구름많고 눈', '최저': 0, '최고': 4},
 {'도시': '인천', '날짜': '2021-01-18 12:00', '날씨': '맑음', '최저': 0, '최고': 4},
 {'도시': '인천', '날짜': '2021-01-19 00:00', '날씨': '맑음', '최저': -11, '최고': -3},
 {'도시': '인천', '날짜': '2021-01-19 12:00', '날씨': '맑음', '최저': -11, '최고': -3},
 {'도시': '인천', '날짜': '2021-01-20 00:00', '날씨': '맑음', '최저': -7, '최고': 2},
 {'도시': '인천', '날짜': '2021-01-20 12:00', '날씨': '구름많음', '최저': -7, '최고': 2},
 {'도시': '인천', '날짜': '2021-01-21 00:00', '날씨': '구름많음', '최저': -2, '최고': 4},
 {'도시': '인천', '날짜': '2021-01-21 12:00', '날씨': '흐림', '최저': -2, '최고': 4}
 ...

 

kdf = pd.DataFrame( kList)
kdf


연습문제

#1. 도시와 날짜를 인덱스로 설정하시오

 

#2. 도시별 최고, 최저기온 평균을 구하시오


#3. '눈'이 오는 도시 날짜 날씨를 구하시오


#4. 최저기온이 가장낮은 도시, 날짜, 최고기온을 구하시오

 

#5. 도시를 입력받아 해당도시 데이터를 구하시오
도시입력:
날짜  날씨 최고  최저
....


#6. 느낌 컬럼을 추가하고 최고기온에 따라 다음과 같이 표시하시오
- 10 도 이하면: 매우 추움
- 5~-9 면: 추움
- 나머지 : 보통

 

#7. 서울지역의 날짜별 최고 최저기온을 바차트로 그리시오


#8. 여주지역 최저기온이 -10 도 이하인데이터를 구하시오

 

#9. 여주지역 전체 최고기온 중 최고기온이 0 도 이상이 차지하는비율을 구하시오
(예를들어  출력결과:0도이상 15% )


#10. 일교차 컬럼을 추가하고,최고기온과 최저기온의 차이가 가장높은 도시,날짜,최저,최고,일교차를 구하시오


Solution

#1. 도시와 날짜를 인덱스로 설정하시오

kdf.set_index(['도시','날짜'] ,inplace=True)
pd.set_option("display.max_rows", None)
kdf

 

#2. 도시별 최고, 최저기온 평균을 구하시오

kdf.pivot_table( index='도시' )

 

#3. '눈'이 오는 도시 날짜 날씨를 구하시오

kdf[ kdf['날씨'].str.contains('눈') ] # 없음


#4. 최저기온이 가장낮은 도시, 날짜, 최고기온을 구하시오

kdf.nsmallest( 1, columns='최저', keep='all' )

 

#5. 도시를 입력받아 해당도시 데이터를 구하시오
도시입력:
날짜  날씨 최고  최저
....

city = input('도시입력:')
kdf.loc[city]

 

#6. 느낌 컬럼을 추가하고 최고기온에 따라 다음과 같이 표시하시오
- 10 도 이하면: 매우 추움
- 5~-9 면: 추움
- 나머지 : 보통

def fn(v):
    if -9<=v<=-5:
        return '추움'
    elif -10 >= v:
        return '매우추움'
    else:
        return '보통'
kdf['느낌'] = kdf['최저'].apply( fn )
kdf

 

#7. 서울지역의 날짜별 최고 최저기온을 바차트로 그리시오

g = kdf.loc['서울'].groupby('날짜')
g.mean().plot(kind='bar')
plt.show()

 

 

#8. 여주지역 최저기온이 -10 도 이하인데이터를 구하시오

yeo =kdf.loc['여주']
yeo[ yeo['최저']<=-10 ]

 

#9. 여주지역 전체 최고기온 중 최고기온이 0 도 이상이 차지하는비율을 구하시오
(예를들어  출력결과:0도이상 15% )

zeroCount = len(  kdf.loc['여주'].query('최고>=0') )
tot = len( kdf.loc['여주'] )
print(tot, zeroCount )
round( (zeroCount/tot)*100 ,2)
[OUT] :

13 6 # 13 중 6

46.15 # 46.15(%)

 

#10. 일교차 컬럼을 추가하고,최고기온과 최저기온의 차이가 가장높은 도시,날짜,최저,최고,일교차를 구하시오

kdf['일교차'] = kdf['최고'] - kdf['최저']
kdf.nlargest(1,'일교차',keep='all')


review
- 직접 파싱해와서 데이터 분석해보기
728x90
반응형
LIST