📌 OPEN API를 이용하여 공공데이터 스크래핑
# 라이브러리 import
import requests
import json
import pandas as pd
from pandas.io.json import json_normalize
import sqlite3 as sq3
# DB 파일 생성 및 연결
con = sq3.connect('경로 설정')
# 990개의 행, pageNo에 a 변수값 대입
url = 'https://apis.data.go.kr/1230000/ScsbidInfoService/getScsbidListSttusServc?serviceKey='서비스키'numOfRows=990&pageNo=a&inqryDiv=1&inqryBgnDt=201605010000&inqryEndDt=201605052359&bidNtceNo=20160325648&type=json'
# 한 페이지 결과 수 990으로 했을 때, 2페이지가 마지막이라는 것을 알고 반복문 실행
for a in range(1,3):
response = requests.get(url, verify=False)
contents = response.text
json_ob = json.loads(contents)
body = json_ob['response']['body']['items']
df = json_normalize(body)
df.to_sql('stock', con, if_exists='append',index = False)
# 결과값: 1980개 데이터 도츨
DB 파일 확인해보면 중복존재 (SQL문: GRUOP BY사용)
1 Page의 990개의 값이 2번 저장 된 걸로 추정
똑같은 페이지를 2번 response했나,,?
📌 변수 설정하기 쉽게하려고 파라미터를 url에서 분리
url = 'http://apis.data.go.kr/1230000/ScsbidInfoService/getScsbidListSttusServc'
params ={'serviceKey' : '서비스키', 'numOfRows' : '990', 'pageNo' : 'a', 'inqryDiv' : '1', 'inqryBgnDt' : '201605010000', 'inqryEndDt' : '201605052359', 'bidNtceNo' : '20160439522', 'type' : 'json' }
for a in range(1,3):
response = requests.get(url, params=params,verify=False)
contents = response.text
json_ob = json.loads(contents)
body = json_ob['response']['body']['items']
df = json_normalize(body)
df.to_sql('stock', con, if_exists='append',index = False)
# 결과 값: 에러발생
JSONDecodeError: Expecting value: line 1 column 1 (char 0)
위에서 for in문 제외하면 잘 실행 됨
반복문 문제,,인가,,,,,,,,하던 도중 a가 변수가 아니라면, 저 url로 스크래핑이 되었던 것이 이상하다고 느낌(첫번째 코드)
혹시 몰라 pageNo=a로 넣은 url로 들어가보니 기존 1page와 동일한 page가 도출됨
처음 코드에 a를 변수로 추가한 줄 알았지만!! 알고보니 그냥 1페이지 url과 동일 했던 것!!!!!!
url에 a변수 대신 page 변수로 변경하여 실행하니깐 2번째와 동일한 오류가 발생!!
변수 설정이 제대로 안 됨
📌 a에 ''를 제거, url을 for문 안에 넣음
for a in range(1,3):
url = 'http://apis.data.go.kr/1230000/ScsbidInfoService/getScsbidListSttusServc'
params ={'serviceKey' : '서비스키',
'numOfRows' : '990', 'pageNo' : a, 'inqryDiv' : '1', 'inqryBgnDt' : '201605010000', 'inqryEndDt' : '201605052359',
'bidNtceNo' : '20160439522', 'type' : 'json' }
response = requests.get(url, params=params,verify=False)
contents = response.content
json_ob = json.loads(contents)
body = json_ob['response']['body']['items']
df = json_normalize(body)
df.to_sql('stock', con, if_exists='append',index = False)
# 결과 값: 원래 데이터의 개수인 1047개 도출
해결😄
import numpy as np
import pandas as pd
import requests
import sqlite3
import time
def 함수명(pageNo, beginDate, endDate):
url = 'url'
params = {'numOfRows' : '990',
'pageNo' : str(pageNo),
'serviceKey' : '서비스키,
'inqryBgnDt' : beginDate,
'inqryEndDt' : endDate,
'type' : 'json' }
response = requests.get(url, params=params)
return response.json()
year = 년도
beginDate = str(year) + 시작일
endDate = str(year) + 종료일
numOfRows = 990
data = pd.DataFrame()
maxCnt = 0
pageNo = 1
while True:
j = 함수명(pageNo, beginDate, endDate)
tempdf = pd.DataFrame(j['response']['body']['items'])
data = pd.concat([data, tempdf])
if maxCnt == 0:
maxCnt = int(np.ceil(j['response']['body']['totalCount'] / numOfRows))
print('Number of Data: ', j['response']['body']['totalCount'])
print('Max Count: ', maxCnt)
print('PageNo: ', pageNo)
pageNo += 1
time.sleep(5)
if pageNo <= maxCnt:
continue
break
print('End of Requests '+'-'*50)