👨🏻‍🏫IT 활동/인공지능교육 - NLP

[NLP] Day4 - HTML2

728x90
반응형

HTTP 이어서 ~

In [22]:
# get ( = Read ) 가장 일반적인 경우 사용

import requests
url = 'http://httpbin.org/'
resp = requests.get(url+'get',params={'key':'value','key1':'value'})
resp = requests.head(url+'get')
# head만 가져오는 것  / body는 비어있어야 함.


# dictionary 형태로 들어감
In [12]:
# post ( = Create )

import requests
url = 'http://httpbin.org/'
resp = requests.post(url+'post',data={'key':'value','key1':'value'})
# parameter 가 아니라 data임 (dictionary인건 마찬가지)
In [17]:
# put ( = Update )

import requests
url = 'http://httpbin.org/'
resp = requests.put(url+'put',data={'key':'value','key1':'value'})
# parameter 가 아니라 data임 (dictionary인건 마찬가지)
In [12]:
# del ( = delete )

import requests
url = 'http://httpbin.org/'
resp = requests.post(url+'post',data={'key':'value','key1':'value'})
# parameter 가 아니라 data임 (dictionary인건 마찬가지)

결과 확인

In [28]:
type(resp)
resp.status_code # 200인지 확인하고 ( 내 잘못 아님)
resp.headers
resp.request.headers
resp.request.body  # 잘 날아갔는지 확인
resp.content # byte type 그대로
resp.text # string으로 바꾼 것인지
resp.encoding = 'utf-8'
In [23]:
resp.content
Out[23]:
b''
In [24]:
print(resp.request.headers) # or body
print(resp.text) # 응답 부분
# arg에 Key value쌍이 들어감
# post 할 때는 header가 아니라 'body'에 들어감 
{'User-Agent': 'python-requests/2.18.4', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}

In [25]:
resp.text
Out[25]:
''

Print Names

In [37]:
# http://www.crawler-test.com/status_codes/status_403 
# _ 다음에 숫자 임의로 붙여서 에러 확인

import requests

url = "https://www.google.com/search"
headers = {'user-agent' :'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'}
# headers 에 mozila부분만 들어가도 가능함
# headers에 각자의 user-agent값을 key-value로 입력하면 된다.

def download(url, param=None,retries=3):     # 에러가 났을 때, 3번 정도 더 시도해 보는 것.
    resp = None
    
    try:
        resp = requests.get(url,params=param,headers=headers)
        resp.raise_for_status()
    except requests.exceptions.HTTPError as e:
        if 500 <= resp.status_code < 600 and retries > 0:    # 500대 에러이면 한 번 더 시도하는 것
            print('Retries: {0}'.format(retries))
            return download(url,param,retries-1)    # 여기서는 딱 3번 돔 (재귀적으로)
        else:
            print(resp.status_code)
            print(resp.reason)
            print(resp.request.headers)
            
    return resp

#html = download(url)
#html.read().decode('utf-8')

## 파이썬 검색해서 하면 안뜸 searchMozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36가 disallowed 이기 때문에 ( forbidden )
## 파라미터는 항상 바이트 타입으로 보내야함. 
## 한글로 그대로 대신 적어주면 에러 뜸 

### header 추가하면 403 에러 뜨지 않음  
### 에러 400 : 내 잘못 / 500 : 서버 잘못, 다시 시도해봐야함 
In [39]:
download('http://www.crawler-test.com/status_codes/status_500')

# try except에 의해서 범위에 벗어나기에 403으로 나와야한다. 
Retries: 3
Retries: 2
Retries: 1
500
Internal Server Error
{'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
Out[39]:
<Response [500]>
In [57]:
# http://pythonscraping.com/pages/files/form.html
In [120]:
# 이건 Post함수
# http://www.crawler-test.com/status_codes/status_403 
# _ 다음에 숫자 임의로 붙여서 에러 확인

import requests

url = "https://www.google.com/search"
headers = {'user-agent' :'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'}
# headers 에 mozila부분만 들어가도 가능함
# headers에 각자의 user-agent값을 key-value로 입력하면 된다.

def postDownload(url, data=None,cookie=None,retries=3):     # 에러가 났을 때, 3번 정도 더 시도해 보는 것.
    resp = None
    
    try:
        resp = requests.post(url,data=data,headers=headers,cookies=cookie)   # auto login할 때 cookie 필요함
        resp.raise_for_status()
    except requests.exceptions.HTTPError as e:
        if 500 <= resp.status_code < 600 and retries > 0:    # 500대 에러이면 한 번 더 시도하는 것
            print('Retries: {0}'.format(retries))
            return download(url,data,cookie,retries-1)    # 여기서는 딱 3번 돔 (재귀적으로)
        else:
            print(resp.status_code)
            print(resp.reason)
            print(resp.request.headers)
            
    return resp

#html = download(url)
#html.read().decode('utf-8')

## 파이썬 검색해서 하면 안뜸 searchMozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36가 disallowed 이기 때문에 ( forbidden )
## 파라미터는 항상 바이트 타입으로 보내야함. 
## 한글로 그대로 대신 적어주면 에러 뜸 

### header 추가하면 403 에러 뜨지 않음  
### 에러 400 : 내 잘못 / 500 : 서버 잘못, 다시 시도해봐야함 
In [121]:
url = 'http://pythonscraping.com/pages/files/processing.php'
html = postDownload(url,{'firstname':'Lee','lastname':'Chamin'})

print(html.status_code)
print(html.reason)
print(html.request.body)
print(html.request.headers)

html.text
200
OK
firstname=Lee&lastname=Chamin
{'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '29', 'Content-Type': 'application/x-www-form-urlencoded'}
Out[121]:
'Hello there, Lee Chamin!'
In [122]:
# get으로 위에랑 똑같이

html2 = download(url,{'firstname':'이','lastname':1})

print(html2.status_code)
print(html2.headers)
print(html2.request.body)
print(html2.request.headers)

# None으로 나온다. 
html2.text
# 결과가 안뜨는 것을 보면 이 페이지는 get이 아닌 post만 받는다는 것을 알 수 있다.
200
{'Date': 'Thu, 07 Mar 2019 07:13:52 GMT', 'Server': 'Apache', 'Keep-Alive': 'timeout=5, max=100', 'Connection': 'Keep-Alive', 'Transfer-Encoding': 'chunked', 'Content-Type': 'text/html; charset=UTF-8'}
None
{'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
Out[122]:
'Hello there,  !'

Auto Login - Using Cookie

In [141]:
# http://pythonscraping.com/pages/cookies/login.html
# post로 넘겨 자동로그인 하기

cookie = html.cookies.get_dict()

url = 'http://pythonscraping.com/pages/cookies/welcome.php'
html = postDownload(url,{}, cookie)
In [142]:
html.text

# 쿠키를 이용해서 로그인이 완료된 모습을 볼 수 있다 
Out[142]:
'\n<h2>Welcome to the Website!</h2>\nYou have logged in successfully! <br><a href="profile.php">Check out your profile!</a>'
In [143]:
# parameter는 정상적으로 전해짐
html.request.body
In [144]:
# cookie를 받아와야함 ( response내의 )
html.cookies

# 딕셔너리 정보를 가져오기 위해 get_dict() 붙임
html.cookies.get_dict()
Out[144]:
{}

Session

In [149]:
session = requests.Session()

resp = session.post(url,data={'username':'lee','password':'password'})
In [150]:
resp.text
# login이 안된 모습. 
Out[150]:
'\n<h2>Welcome to the Website!</h2>\nWhoops! You logged in wrong. Try again with any username, and the password "password"<br><a href="login.html">Log in here</a>'
In [154]:
# cookie값을 들고와야 로그인 할 수 있음 
cookie = resp.cookies.get_dict()
resp = session.post(url,{},cookie)
resp.text
Out[154]:
'\n<h2>Welcome to the Website!</h2>\nYou have logged in successfully! <br><a href="profile.php">Check out your profile!</a>'

공공데이터포털

In [177]:
# getDownload
import requests

def getDownload(url, param = None, retries = 3):
    resp = None
    try:
        resp = requests.get(url, params = param, headers = headers)
        resp.raise_for_status()
    except requests.exceptions.HTTPError as e:
        if 500 <= resp.status_code < 600 and retries > 0:
            print('Retries : {0}'.format(retries))
            return getDownload(url, param, retries -1)
        else:
            print(resp.status_code)
            print(resp.reason)
            print(resp.request.headers)
            
    return resp
In [180]:
# _returnType=json 끝에 붙이기 ( 변환 )
# 하나하나 다 뜯어야함

#url = ''  # 뒤에거 뜯어서 param으로
url = 'http://openapi.airkorea.or.kr/openapi/services/rest/ArpltnInforInqireSvc/getCtprvnRltmMesureDnsty?'
param={
    "serviceKey":"sh3rYw7QjwAhsCW88FOOcPwFQ9%2F4E3uFZX6rDHwjtkpu9yFwvVX1fMb%2Bz%2B2n4CSdn50fmS0AbD7IqNL8O4qcAA%3D%3D",
    "numOfRows": 10,
    "pageNo":1,
    "sidoName":"서울",
    "ver":1.3,
    "_returnType":"json"}

html = getDownload(url,param)
html.text
Out[180]:
'<?xml version="1.0" encoding="UTF-8"?>\r\n\r\n\r\n\r\n\r\n<response>\r\n\t<header>\r\n\t\t<resultCode>30</resultCode>\r\n\t\t<resultMsg>SERVICE KEY IS NOT REGISTERED ERROR.</resultMsg>\r\n\t</header>\r\n</response>\r\n'
In [181]:
requests.utils.urlparse(html.request.url)

org = requests.utils.unquote(param['serviceKey'])
print(param['serviceKey'])
print(org)
print(requests.utils.quote(org))
param['serviceKey'] = org
html = getDownload(url, param)
html.text

# requests.utils.quote()   # quote로 해야 바뀐 servicekey와 같아짐 
# requests.utils.unquote() # unquote 해줘야함
# requests.utils.urlparse(html.request.url)  
sh3rYw7QjwAhsCW88FOOcPwFQ9%2F4E3uFZX6rDHwjtkpu9yFwvVX1fMb%2Bz%2B2n4CSdn50fmS0AbD7IqNL8O4qcAA%3D%3D
sh3rYw7QjwAhsCW88FOOcPwFQ9/4E3uFZX6rDHwjtkpu9yFwvVX1fMb+z+2n4CSdn50fmS0AbD7IqNL8O4qcAA==
sh3rYw7QjwAhsCW88FOOcPwFQ9/4E3uFZX6rDHwjtkpu9yFwvVX1fMb%2Bz%2B2n4CSdn50fmS0AbD7IqNL8O4qcAA%3D%3D
Out[181]:
'{"list":[{"_returnType":"json","coGrade":"1","coValue":"0.5","dataTerm":"","dataTime":"2019-03-08 14:00","khaiGrade":"2","khaiValue":"74","mangName":"도시대기","no2Grade":"2","no2Value":"0.036","numOfRows":"10","o3Grade":"2","o3Value":"0.042","pageNo":"1","pm10Grade":"2","pm10Grade1h":"2","pm10Value":"49","pm10Value24":"48","pm25Grade":"2","pm25Grade1h":"2","pm25Value":"30","pm25Value24":"25","resultCode":"","resultMsg":"","rnum":0,"serviceKey":"","sidoName":"","so2Grade":"1","so2Value":"0.004","stationCode":"","stationName":"중구","totalCount":"","ver":""},{"_returnType":"json","coGrade":"1","coValue":"0.5","dataTerm":"","dataTime":"2019-03-08 14:00","khaiGrade":"2","khaiValue":"83","mangName":"도로변대기","no2Grade":"2","no2Value":"0.050","numOfRows":"10","o3Grade":"1","o3Value":"0.028","pageNo":"1","pm10Grade":"2","pm10Grade1h":"2","pm10Value":"74","pm10Value24":"62","pm25Grade":"2","pm25Grade1h":"3","pm25Value":"41","pm25Value24":"31","resultCode":"","resultMsg":"","rnum":0,"serviceKey":"","sidoName":"","so2Grade":"1","so2Value":"0.005","stationCode":"","stationName":"한강대로","totalCount":"","ver":""},{"_returnType":"json","coGrade":"1","coValue":"0.5","dataTerm":"","dataTime":"2019-03-08 14:00","khaiGrade":"2","khaiValue":"77","mangName":"도시대기","no2Grade":"2","no2Value":"0.037","numOfRows":"10","o3Grade":"2","o3Value":"0.037","pageNo":"1","pm10Grade":"2","pm10Grade1h":"2","pm10Value":"52","pm10Value24":"48","pm25Grade":"2","pm25Grade1h":"2","pm25Value":"28","pm25Value24":"26","resultCode":"","resultMsg":"","rnum":0,"serviceKey":"","sidoName":"","so2Grade":"1","so2Value":"0.005","stationCode":"","stationName":"종로구","totalCount":"","ver":""},{"_returnType":"json","coGrade":"1","coValue":"0.7","dataTerm":"","dataTime":"2019-03-08 14:00","khaiGrade":"2","khaiValue":"82","mangName":"도로변대기","no2Grade":"2","no2Value":"0.042","numOfRows":"10","o3Grade":"2","o3Value":"0.033","pageNo":"1","pm10Grade":"2","pm10Grade1h":"2","pm10Value":"46","pm10Value24":"51","pm25Grade":"2","pm25Grade1h":"2","pm25Value":"31","pm25Value24":"28","resultCode":"","resultMsg":"","rnum":0,"serviceKey":"","sidoName":"","so2Grade":"1","so2Value":"0.005","stationCode":"","stationName":"청계천로","totalCount":"","ver":""},{"_returnType":"json","coGrade":"1","coValue":"0.6","dataTerm":"","dataTime":"2019-03-08 14:00","khaiGrade":"2","khaiValue":"74","mangName":"도로변대기","no2Grade":"2","no2Value":"0.044","numOfRows":"10","o3Grade":"2","o3Value":"0.032","pageNo":"1","pm10Grade":"2","pm10Grade1h":"2","pm10Value":"52","pm10Value24":"54","pm25Grade":"2","pm25Grade1h":"2","pm25Value":"27","pm25Value24":"25","resultCode":"","resultMsg":"","rnum":0,"serviceKey":"","sidoName":"","so2Grade":"1","so2Value":"0.004","stationCode":"","stationName":"종로","totalCount":"","ver":""},{"_returnType":"json","coGrade":"1","coValue":"0.4","dataTerm":"","dataTime":"2019-03-08 14:00","khaiGrade":"2","khaiValue":"79","mangName":"도시대기","no2Grade":"2","no2Value":"0.036","numOfRows":"10","o3Grade":"2","o3Value":"0.034","pageNo":"1","pm10Grade":"2","pm10Grade1h":"2","pm10Value":"42","pm10Value24":"44","pm25Grade":"2","pm25Grade1h":"2","pm25Value":"29","pm25Value24":"27","resultCode":"","resultMsg":"","rnum":0,"serviceKey":"","sidoName":"","so2Grade":"1","so2Value":"0.004","stationCode":"","stationName":"용산구","totalCount":"","ver":""},{"_returnType":"json","coGrade":"1","coValue":"0.8","dataTerm":"","dataTime":"2019-03-08 14:00","khaiGrade":"2","khaiValue":"90","mangName":"도시대기","no2Grade":"2","no2Value":"0.032","numOfRows":"10","o3Grade":"1","o3Value":"0.029","pageNo":"1","pm10Grade":"2","pm10Grade1h":"2","pm10Value":"48","pm10Value24":"57","pm25Grade":"2","pm25Grade1h":"2","pm25Value":"29","pm25Value24":"31","resultCode":"","resultMsg":"","rnum":0,"serviceKey":"","sidoName":"","so2Grade":"1","so2Value":"0.006","stationCode":"","stationName":"광진구","totalCount":"","ver":""},{"_returnType":"json","coGrade":"1","coValue":"0.4","dataTerm":"","dataTime":"2019-03-08 14:00","khaiGrade":"2","khaiValue":"97","mangName":"도시대기","no2Grade":"2","no2Value":"0.042","numOfRows":"10","o3Grade":"1","o3Value":"0.030","pageNo":"1","pm10Grade":"2","pm10Grade1h":"2","pm10Value":"67","pm10Value24":"65","pm25Grade":"2","pm25Grade1h":"2","pm25Value":"34","pm25Value24":"34","resultCode":"","resultMsg":"","rnum":0,"serviceKey":"","sidoName":"","so2Grade":"1","so2Value":"0.004","stationCode":"","stationName":"성동구","totalCount":"","ver":""},{"_returnType":"json","coGrade":"1","coValue":"0.4","dataTerm":"","dataTime":"2019-03-08 14:00","khaiGrade":"3","khaiValue":"103","mangName":"도로변대기","no2Grade":"3","no2Value":"0.063","numOfRows":"10","o3Grade":"1","o3Value":"0.017","pageNo":"1","pm10Grade":"2","pm10Grade1h":"2","pm10Value":"62","pm10Value24":"61","pm25Grade":"2","pm25Grade1h":"2","pm25Value":"34","pm25Value24":"33","resultCode":"","resultMsg":"","rnum":0,"serviceKey":"","sidoName":"","so2Grade":"1","so2Value":"0.005","stationCode":"","stationName":"강변북로","totalCount":"","ver":""},{"_returnType":"json","coGrade":"1","coValue":"0.5","dataTerm":"","dataTime":"2019-03-08 14:00","khaiGrade":"2","khaiValue":"85","mangName":"도시대기","no2Grade":"1","no2Value":"0.029","numOfRows":"10","o3Grade":"1","o3Value":"0.028","pageNo":"1","pm10Grade":"2","pm10Grade1h":"2","pm10Value":"43","pm10Value24":"52","pm25Grade":"2","pm25Grade1h":"2","pm25Value":"27","pm25Value24":"29","resultCode":"","resultMsg":"","rnum":0,"serviceKey":"","sidoName":"","so2Grade":"1","so2Value":"0.007","stationCode":"","stationName":"중랑구","totalCount":"","ver":""}],"parm":{"_returnType":"json","coGrade":"","coValue":"","dataTerm":"","dataTime":"","khaiGrade":"","khaiValue":"","mangName":"","no2Grade":"","no2Value":"","numOfRows":"10","o3Grade":"","o3Value":"","pageNo":"1","pm10Grade":"","pm10Grade1h":"","pm10Value":"","pm10Value24":"","pm25Grade":"","pm25Grade1h":"","pm25Value":"","pm25Value24":"","resultCode":"","resultMsg":"","rnum":0,"serviceKey":"sh3rYw7QjwAhsCW88FOOcPwFQ9/4E3uFZX6rDHwjtkpu9yFwvVX1fMb+z+2n4CSdn50fmS0AbD7IqNL8O4qcAA==","sidoName":"서울","so2Grade":"","so2Value":"","stationCode":"","stationName":"","totalCount":"","ver":"1.3"},"ArpltnInforInqireSvcVo":{"_returnType":"json","coGrade":"","coValue":"","dataTerm":"","dataTime":"","khaiGrade":"","khaiValue":"","mangName":"","no2Grade":"","no2Value":"","numOfRows":"10","o3Grade":"","o3Value":"","pageNo":"1","pm10Grade":"","pm10Grade1h":"","pm10Value":"","pm10Value24":"","pm25Grade":"","pm25Grade1h":"","pm25Value":"","pm25Value24":"","resultCode":"","resultMsg":"","rnum":0,"serviceKey":"sh3rYw7QjwAhsCW88FOOcPwFQ9/4E3uFZX6rDHwjtkpu9yFwvVX1fMb+z+2n4CSdn50fmS0AbD7IqNL8O4qcAA==","sidoName":"서울","so2Grade":"","so2Value":"","stationCode":"","stationName":"","totalCount":"","ver":"1.3"},"totalCount":40}'
In [182]:
import json
In [183]:
result = json.loads(html.text) # 메모리 부터 읽는 것 
result
Out[183]:
{'ArpltnInforInqireSvcVo': {'_returnType': 'json',
  'coGrade': '',
  'coValue': '',
  'dataTerm': '',
  'dataTime': '',
  'khaiGrade': '',
  'khaiValue': '',
  'mangName': '',
  'no2Grade': '',
  'no2Value': '',
  'numOfRows': '10',
  'o3Grade': '',
  'o3Value': '',
  'pageNo': '1',
  'pm10Grade': '',
  'pm10Grade1h': '',
  'pm10Value': '',
  'pm10Value24': '',
  'pm25Grade': '',
  'pm25Grade1h': '',
  'pm25Value': '',
  'pm25Value24': '',
  'resultCode': '',
  'resultMsg': '',
  'rnum': 0,
  'serviceKey': 'sh3rYw7QjwAhsCW88FOOcPwFQ9/4E3uFZX6rDHwjtkpu9yFwvVX1fMb+z+2n4CSdn50fmS0AbD7IqNL8O4qcAA==',
  'sidoName': '서울',
  'so2Grade': '',
  'so2Value': '',
  'stationCode': '',
  'stationName': '',
  'totalCount': '',
  'ver': '1.3'},
 'list': [{'_returnType': 'json',
   'coGrade': '1',
   'coValue': '0.5',
   'dataTerm': '',
   'dataTime': '2019-03-08 14:00',
   'khaiGrade': '2',
   'khaiValue': '74',
   'mangName': '도시대기',
   'no2Grade': '2',
   'no2Value': '0.036',
   'numOfRows': '10',
   'o3Grade': '2',
   'o3Value': '0.042',
   'pageNo': '1',
   'pm10Grade': '2',
   'pm10Grade1h': '2',
   'pm10Value': '49',
   'pm10Value24': '48',
   'pm25Grade': '2',
   'pm25Grade1h': '2',
   'pm25Value': '30',
   'pm25Value24': '25',
   'resultCode': '',
   'resultMsg': '',
   'rnum': 0,
   'serviceKey': '',
   'sidoName': '',
   'so2Grade': '1',
   'so2Value': '0.004',
   'stationCode': '',
   'stationName': '중구',
   'totalCount': '',
   'ver': ''},
  {'_returnType': 'json',
   'coGrade': '1',
   'coValue': '0.5',
   'dataTerm': '',
   'dataTime': '2019-03-08 14:00',
   'khaiGrade': '2',
   'khaiValue': '83',
   'mangName': '도로변대기',
   'no2Grade': '2',
   'no2Value': '0.050',
   'numOfRows': '10',
   'o3Grade': '1',
   'o3Value': '0.028',
   'pageNo': '1',
   'pm10Grade': '2',
   'pm10Grade1h': '2',
   'pm10Value': '74',
   'pm10Value24': '62',
   'pm25Grade': '2',
   'pm25Grade1h': '3',
   'pm25Value': '41',
   'pm25Value24': '31',
   'resultCode': '',
   'resultMsg': '',
   'rnum': 0,
   'serviceKey': '',
   'sidoName': '',
   'so2Grade': '1',
   'so2Value': '0.005',
   'stationCode': '',
   'stationName': '한강대로',
   'totalCount': '',
   'ver': ''},
  {'_returnType': 'json',
   'coGrade': '1',
   'coValue': '0.5',
   'dataTerm': '',
   'dataTime': '2019-03-08 14:00',
   'khaiGrade': '2',
   'khaiValue': '77',
   'mangName': '도시대기',
   'no2Grade': '2',
   'no2Value': '0.037',
   'numOfRows': '10',
   'o3Grade': '2',
   'o3Value': '0.037',
   'pageNo': '1',
   'pm10Grade': '2',
   'pm10Grade1h': '2',
   'pm10Value': '52',
   'pm10Value24': '48',
   'pm25Grade': '2',
   'pm25Grade1h': '2',
   'pm25Value': '28',
   'pm25Value24': '26',
   'resultCode': '',
   'resultMsg': '',
   'rnum': 0,
   'serviceKey': '',
   'sidoName': '',
   'so2Grade': '1',
   'so2Value': '0.005',
   'stationCode': '',
   'stationName': '종로구',
   'totalCount': '',
   'ver': ''},
  {'_returnType': 'json',
   'coGrade': '1',
   'coValue': '0.7',
   'dataTerm': '',
   'dataTime': '2019-03-08 14:00',
   'khaiGrade': '2',
   'khaiValue': '82',
   'mangName': '도로변대기',
   'no2Grade': '2',
   'no2Value': '0.042',
   'numOfRows': '10',
   'o3Grade': '2',
   'o3Value': '0.033',
   'pageNo': '1',
   'pm10Grade': '2',
   'pm10Grade1h': '2',
   'pm10Value': '46',
   'pm10Value24': '51',
   'pm25Grade': '2',
   'pm25Grade1h': '2',
   'pm25Value': '31',
   'pm25Value24': '28',
   'resultCode': '',
   'resultMsg': '',
   'rnum': 0,
   'serviceKey': '',
   'sidoName': '',
   'so2Grade': '1',
   'so2Value': '0.005',
   'stationCode': '',
   'stationName': '청계천로',
   'totalCount': '',
   'ver': ''},
  {'_returnType': 'json',
   'coGrade': '1',
   'coValue': '0.6',
   'dataTerm': '',
   'dataTime': '2019-03-08 14:00',
   'khaiGrade': '2',
   'khaiValue': '74',
   'mangName': '도로변대기',
   'no2Grade': '2',
   'no2Value': '0.044',
   'numOfRows': '10',
   'o3Grade': '2',
   'o3Value': '0.032',
   'pageNo': '1',
   'pm10Grade': '2',
   'pm10Grade1h': '2',
   'pm10Value': '52',
   'pm10Value24': '54',
   'pm25Grade': '2',
   'pm25Grade1h': '2',
   'pm25Value': '27',
   'pm25Value24': '25',
   'resultCode': '',
   'resultMsg': '',
   'rnum': 0,
   'serviceKey': '',
   'sidoName': '',
   'so2Grade': '1',
   'so2Value': '0.004',
   'stationCode': '',
   'stationName': '종로',
   'totalCount': '',
   'ver': ''},
  {'_returnType': 'json',
   'coGrade': '1',
   'coValue': '0.4',
   'dataTerm': '',
   'dataTime': '2019-03-08 14:00',
   'khaiGrade': '2',
   'khaiValue': '79',
   'mangName': '도시대기',
   'no2Grade': '2',
   'no2Value': '0.036',
   'numOfRows': '10',
   'o3Grade': '2',
   'o3Value': '0.034',
   'pageNo': '1',
   'pm10Grade': '2',
   'pm10Grade1h': '2',
   'pm10Value': '42',
   'pm10Value24': '44',
   'pm25Grade': '2',
   'pm25Grade1h': '2',
   'pm25Value': '29',
   'pm25Value24': '27',
   'resultCode': '',
   'resultMsg': '',
   'rnum': 0,
   'serviceKey': '',
   'sidoName': '',
   'so2Grade': '1',
   'so2Value': '0.004',
   'stationCode': '',
   'stationName': '용산구',
   'totalCount': '',
   'ver': ''},
  {'_returnType': 'json',
   'coGrade': '1',
   'coValue': '0.8',
   'dataTerm': '',
   'dataTime': '2019-03-08 14:00',
   'khaiGrade': '2',
   'khaiValue': '90',
   'mangName': '도시대기',
   'no2Grade': '2',
   'no2Value': '0.032',
   'numOfRows': '10',
   'o3Grade': '1',
   'o3Value': '0.029',
   'pageNo': '1',
   'pm10Grade': '2',
   'pm10Grade1h': '2',
   'pm10Value': '48',
   'pm10Value24': '57',
   'pm25Grade': '2',
   'pm25Grade1h': '2',
   'pm25Value': '29',
   'pm25Value24': '31',
   'resultCode': '',
   'resultMsg': '',
   'rnum': 0,
   'serviceKey': '',
   'sidoName': '',
   'so2Grade': '1',
   'so2Value': '0.006',
   'stationCode': '',
   'stationName': '광진구',
   'totalCount': '',
   'ver': ''},
  {'_returnType': 'json',
   'coGrade': '1',
   'coValue': '0.4',
   'dataTerm': '',
   'dataTime': '2019-03-08 14:00',
   'khaiGrade': '2',
   'khaiValue': '97',
   'mangName': '도시대기',
   'no2Grade': '2',
   'no2Value': '0.042',
   'numOfRows': '10',
   'o3Grade': '1',
   'o3Value': '0.030',
   'pageNo': '1',
   'pm10Grade': '2',
   'pm10Grade1h': '2',
   'pm10Value': '67',
   'pm10Value24': '65',
   'pm25Grade': '2',
   'pm25Grade1h': '2',
   'pm25Value': '34',
   'pm25Value24': '34',
   'resultCode': '',
   'resultMsg': '',
   'rnum': 0,
   'serviceKey': '',
   'sidoName': '',
   'so2Grade': '1',
   'so2Value': '0.004',
   'stationCode': '',
   'stationName': '성동구',
   'totalCount': '',
   'ver': ''},
  {'_returnType': 'json',
   'coGrade': '1',
   'coValue': '0.4',
   'dataTerm': '',
   'dataTime': '2019-03-08 14:00',
   'khaiGrade': '3',
   'khaiValue': '103',
   'mangName': '도로변대기',
   'no2Grade': '3',
   'no2Value': '0.063',
   'numOfRows': '10',
   'o3Grade': '1',
   'o3Value': '0.017',
   'pageNo': '1',
   'pm10Grade': '2',
   'pm10Grade1h': '2',
   'pm10Value': '62',
   'pm10Value24': '61',
   'pm25Grade': '2',
   'pm25Grade1h': '2',
   'pm25Value': '34',
   'pm25Value24': '33',
   'resultCode': '',
   'resultMsg': '',
   'rnum': 0,
   'serviceKey': '',
   'sidoName': '',
   'so2Grade': '1',
   'so2Value': '0.005',
   'stationCode': '',
   'stationName': '강변북로',
   'totalCount': '',
   'ver': ''},
  {'_returnType': 'json',
   'coGrade': '1',
   'coValue': '0.5',
   'dataTerm': '',
   'dataTime': '2019-03-08 14:00',
   'khaiGrade': '2',
   'khaiValue': '85',
   'mangName': '도시대기',
   'no2Grade': '1',
   'no2Value': '0.029',
   'numOfRows': '10',
   'o3Grade': '1',
   'o3Value': '0.028',
   'pageNo': '1',
   'pm10Grade': '2',
   'pm10Grade1h': '2',
   'pm10Value': '43',
   'pm10Value24': '52',
   'pm25Grade': '2',
   'pm25Grade1h': '2',
   'pm25Value': '27',
   'pm25Value24': '29',
   'resultCode': '',
   'resultMsg': '',
   'rnum': 0,
   'serviceKey': '',
   'sidoName': '',
   'so2Grade': '1',
   'so2Value': '0.007',
   'stationCode': '',
   'stationName': '중랑구',
   'totalCount': '',
   'ver': ''}],
 'parm': {'_returnType': 'json',
  'coGrade': '',
  'coValue': '',
  'dataTerm': '',
  'dataTime': '',
  'khaiGrade': '',
  'khaiValue': '',
  'mangName': '',
  'no2Grade': '',
  'no2Value': '',
  'numOfRows': '10',
  'o3Grade': '',
  'o3Value': '',
  'pageNo': '1',
  'pm10Grade': '',
  'pm10Grade1h': '',
  'pm10Value': '',
  'pm10Value24': '',
  'pm25Grade': '',
  'pm25Grade1h': '',
  'pm25Value': '',
  'pm25Value24': '',
  'resultCode': '',
  'resultMsg': '',
  'rnum': 0,
  'serviceKey': 'sh3rYw7QjwAhsCW88FOOcPwFQ9/4E3uFZX6rDHwjtkpu9yFwvVX1fMb+z+2n4CSdn50fmS0AbD7IqNL8O4qcAA==',
  'sidoName': '서울',
  'so2Grade': '',
  'so2Value': '',
  'stationCode': '',
  'stationName': '',
  'totalCount': '',
  'ver': '1.3'},
 'totalCount': 40}
In [190]:
for row in result['list']:  # result['list']는 10개임 
    print(row['stationName'],row['pm25Value'])
중구 30
한강대로 41
종로구 28
청계천로 31
종로 27
용산구 29
광진구 29
성동구 34
강변북로 34
중랑구 27
In [ ]:
대기오염정보 조회 서비스 


728x90
반응형