스크래핑 실습

파도·2022년 9월 15일
0

내가 짜집기한 코드 (feat.구글링)

📌 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개 도출

해결😄

Solution 코드

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)
profile
우당탕탕 / 블로그 이사 중

0개의 댓글