임신 육아 종합포털 아이사랑(https://www.childcare.go.kr/cpin/main1.jsp) > 어린이집 찾기 > 경상남도에 있는 모든 어린이집 정보 크롤링하기

 

크롤링할 정보: 기관명 / 설립유형 / 주소 / 제공서비스

 

 

 

1. 크롤링하려면 사이트의 주소가 필요

확인해야하는 사이트는 '요약'과 '기본현황' 두 개의 사이트이며 각 사이트의 주소는

>요약: http://info.childcare.go.kr/info/pnis/search/preview/SummaryInfoSlPu.jsp?flag=YJ&STCODE_POP='유치원코드'
>기본현황: http://info.childcare.go.kr/info/pnis/search/preview/BasisPresentConditionSlPu.jsp?flag=GH&STCODE_POP='유치원코드'

 

이며 유치원코드는 지역코드(5자리)+고유번호(6자리)로 이루어짐

# 시군구 코드: [48120,48121,48123,48125,48127,48129,48170,48220,48240,48250,48270,48310,48330,48720,48730,48740,48820,48840,48850,48860,48870,48880,48890]

# 고유번호는 규칙도 모르겠고 중간에 폐지된 시설도 있지만 세자리를 넘어가는 코드는 없는 것으로 보임

 

 

 

2. 해당 규칙에 따라 다음과 같이 url을 얻는 코드 작성

# 경상남도의 모든 시군구 코드 리스트
gn_cd_list=['48120','48121','48123','48125','48127','48129','48170','48220','48240','48250','48270','48310',
            '48330','48720','48730','48740','48820','48840','48850','48860','48870','48880','48890']

# 각 시군구 코드를 주소에 적용
for gn_cd in range(gn_cd_list):
    # 주소가 문자형이므로 세자리의 고유번호를 000~999 형태로 넣고 싶었지만 000을 0으로 자동으로 바꾸기에
    # 자리수에 따라 0~9, 10~99, 100~999 세번의 for문 사용
    
    for i in range(10):
        # 기관명과 주소를 확인할 수 있는 '요약' 사이트의 url
        name_juso_url = 'http://info.childcare.go.kr/info/pnis/search/preview/SummaryInfoSlPu.jsp?flag=YJ&STCODE_POP=%s00000%d'%(gn_cd,i)
        # 설립유형과 제공 서비스를 확인할 수 있는 '기본현황' 사이트의 url
        type_service_url='http://info.childcare.go.kr/info/pnis/search/preview/BasisPresentConditionSlPu.jsp?flag=GH&STCODE_POP=%s00000%d'%(gn_cd,i)
    
    for i in range(10,100):
        name_juso_url = 'http://info.childcare.go.kr/info/pnis/search/preview/SummaryInfoSlPu.jsp?flag=YJ&STCODE_POP=%s0000%d'%(gn_cd,i)
        type_service_url='http://info.childcare.go.kr/info/pnis/search/preview/BasisPresentConditionSlPu.jsp?flag=GH&STCODE_POP=%s0000%d'%(gn_cd,i)
    
    for i in range(100,1000):
        name_juso_url = 'http://info.childcare.go.kr/info/pnis/search/preview/SummaryInfoSlPu.jsp?flag=YJ&STCODE_POP=%s000%d'%(gn_cd,i)
        type_service_url='http://info.childcare.go.kr/info/pnis/search/preview/BasisPresentConditionSlPu.jsp?flag=GH&STCODE_POP=%s000%d'%(gn_cd,i)
 

 

 

3. 사이트에서 f12를 눌러 개발자 도구 확인

오른쪽 마우스 사용이 불가능한 사이트라 직접 화살표를 눌러가며 기관명, 주소, 설립유형, 제공서비스의 경로를 찾아 XPath를 복사

 

복사한 XPath를 fromstring(request.get(url).text).xpath('XPath')문에 적용하여 해당 정보 크롤링

참고로, 복사한 XPath문 맨 뒤에 '/text()'를 붙여줘야 XPath 주소에 해당하는 부분의 텍스트를 출력할 수 있음

 

import requests
import lxml.html
from lxml.html import fromstring

# 기관명의 XPath를 통해 사이트 내의 기관명 크롤링
name_li= fromstring(requests.get(name_juso_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table/tbody/tr[1]/td[1]/text()')

# 주소의 XPath를 통해 사이트 내의 주소 크롤링
juso_li = fromstring(requests.get(name_juso_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table/tbody/tr[10]/td/text()')

# 설립유형의 XPath를 통해 사이트 내의 설립유형 크롤링
type_li=fromstring(requests.get(type_service_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table[1]/tbody/tr[1]/td[2]/text()')

# 제공 서비스의 XPath를 통해 사이트 내의 제공 서비스 크롤링
service_li=fromstring(requests.get(type_service_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table[1]/tbody/tr[3]/td[1]/text()')

print(name_li)
print(juso_li)
print(type_li)
print(service_li)

### 실행 결과 ###
['\n              BNK창원어린이집\n              \n            ']
['\n                    \t(51366)\n                    \t경상남도 창원시 마산회원구 양덕로 135\xa0(양덕동)\n\t\t\t\t\t\t']
['직장']
['일반']

이름과 주소에서 필요없는 띄어쓰기와 '\n', '\t', '\xa0' 등의 문자가 나타나므로 replace(' ' ,''), replace('\n','') 등으로 없애기

 

 

4. 전체 코드

import requests
from lxml.html import fromstring
import pandas as pd

# 각 정보를 크롤링해와서 넣어 놓을 리스트
name=[]    # 기관명
juso=[]    # 주소
type=[]    # 설립유형
service=[] # 제공서비스

# 경상남도 시군구 코드
gn_cd_list=['48120','48121','48123','48125','48127','48129','48170','48220','48240','48250','48270','48310',
            '48330','48720','48730','48740','48820','48840','48850','48860','48870','48880','48890']

# 경상남도의 각 시군구 코드+한 자리수 코드(000~009)/두 자리수 코드(010~099)/세 자리수 코드(100~999)의 주소 크롤링
for gn_cd in gn_cd_list:
    # 한 자리수 코드(000~009)
    for i in range(10):
        name_juso_url = 'http://info.childcare.go.kr/info/pnis/search/preview/SummaryInfoSlPu.jsp?flag=YJ&STCODE_POP=%s00000%d'%(gn_cd,i)
        type_service_url='http://info.childcare.go.kr/info/pnis/search/preview/BasisPresentConditionSlPu.jsp?flag=GH&STCODE_POP=%s00000%d'%(gn_cd,i)
        name_li= fromstring(requests.get(name_juso_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table/tbody/tr[1]/td[1]')
        juso_li = fromstring(requests.get(name_juso_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table/tbody/tr[10]/td/text()')
        type_li=fromstring(requests.get(type_service_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table[1]/tbody/tr[1]/td[2]')
        service_li=fromstring(requests.get(type_service_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table[1]/tbody/tr[3]/td[1]')
        name.append(name_li[0].text.replace('\xa0','').replace('\t','').replace('\n','').replace('  ',''))  # 필요없는 단어 제외후 리스트에 추가하여 저장
        juso.append(juso_li[0].replace('\xa0','').replace('\t','').replace('\n','').replace('  ',''))       # 필요없는 단어 제외후 리스트에 추가하여 저장
        type.append(type_li[0].text)                                                                        # 리스트에 추가하여 저장
        service.append(service_li[0].text)                                                                  # 리스트에 추가하여 저장

    # 두 자리수 코드(010~099)
    for j in range(10,100):
        name_juso_url = 'http://info.childcare.go.kr/info/pnis/search/preview/SummaryInfoSlPu.jsp?flag=YJ&STCODE_POP=%s0000%d'%(gn_cd,j)
        type_service_url='http://info.childcare.go.kr/info/pnis/search/preview/BasisPresentConditionSlPu.jsp?flag=GH&STCODE_POP=%s0000%d'%(gn_cd,j)
        name_li= fromstring(requests.get(name_juso_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table/tbody/tr[1]/td[1]')
        juso_li = fromstring(requests.get(name_juso_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table/tbody/tr[10]/td/text()')
        type_li=fromstring(requests.get(type_service_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table[1]/tbody/tr[1]/td[2]')
        service_li=fromstring(requests.get(type_service_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table[1]/tbody/tr[3]/td[1]')
        name.append(name_li[0].text.replace('\xa0','').replace('\t','').replace('\n','').replace('  ',''))  # 필요없는 단어 제외후 리스트에 추가하여 저장
        juso.append(juso_li[0].replace('\xa0','').replace('\t','').replace('\n','').replace('  ',''))       # 필요없는 단어 제외후 리스트에 추가하여 저장
        type.append(type_li[0].text)                                                                        # 리스트에 추가하여 저장
        service.append(service_li[0].text)                                                                  # 리스트에 추가하여 저장

    # 세 자리수 코드(100~999)
    for k in range(100,1000):
        name_juso_url = 'http://info.childcare.go.kr/info/pnis/search/preview/SummaryInfoSlPu.jsp?flag=YJ&STCODE_POP=%s000%d'%(gn_cd,k)
        type_service_url='http://info.childcare.go.kr/info/pnis/search/preview/BasisPresentConditionSlPu.jsp?flag=GH&STCODE_POP=%s000%d'%(gn_cd,k)
        name_li= fromstring(requests.get(name_juso_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table/tbody/tr[1]/td[1]')
        juso_li = fromstring(requests.get(name_juso_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table/tbody/tr[10]/td/text()')
        type_li=fromstring(requests.get(type_service_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table[1]/tbody/tr[1]/td[2]')
        service_li=fromstring(requests.get(type_service_url).text).xpath('//*[@id="popWrap2"]/div/div/div/table[1]/tbody/tr[3]/td[1]')
        name.append(name_li[0].text.replace('\xa0','').replace('\t','').replace('\n','').replace('  ',''))  # 필요없는 단어 제외후 리스트에 추가하여 저장
        juso.append(juso_li[0].replace('\xa0','').replace('\t','').replace('\n','').replace('  ',''))       # 필요없는 단어 제외후 리스트에 추가하여 저장
        type.append(type_li[0].text)                                                                        # 리스트에 추가하여 저장
        service.append(service_li[0].text)                                                                  # 리스트에 추가하여 저장
    print(gn_cd) # 몇번째 시군구까지 작업을 완료했는지 알아보기 위함

# 각 리스트를 하나의 데이터프레임으로 생성
df=pd.DataFrame({'기관명':name,'주소':juso,'설립유형':type,'제공서비스':service})
df.drop(df[df['기관명']==''].index,inplace=True)  # 위에서 고유코드가 없었던 경우도 빈 행으로 데이터 프레임에 포함되었기 때문에 빈 행 제거
df.reset_index().iloc[:,1:]

# 마지막으로 생성한 데이터프레임을 csv파일로 저장
df.to_csv('어린이집_크롤링.csv',encoding='cp949')

 

각 어린이집의 고유코드에 대한 정보를 알지 못해서 무작정 000~999까지 넣어 크롤링하여 실제 어린이집 보다 많은 수의 어린이집이 크롤링됨(임신육아종합포털에 올라와있지 않은 어린이집도 있는 듯)

+ Recent posts