웹크롤링을 도와줍니다.


License
MIT
Install
pip install toobuk==0.7.2

Documentation

TOOBUK

beautifulsoup을 이용하여 웹 크롤링을 쉽게할 수 있도록 도와주는 모듈입니다.

차례

  1. 설치
  2. 간단한 설명
  3. 가장 기본적인 사용법
  4. output 설정
    1. output 조정하기
    2. output이 여러개 설정된 경우
    3. output의 특정 그룹 하나 가져오기
    4. output의 여러 그룹 가져오기
    5. output 전체 가져오기
  5. docker 설치 후, 확인
  6. 남은 것들

간단한 설명

beautifulsoup을 이용하여 웹 크롤링을 쉽게할 수 있도록 도와주는 모듈입니다.
test/test.py를 실행하시면 콘솔을 통해 결과값을 확인할 수 있습니다.

설치

python을 설치한 후 아래 명령으로 설치할 수 있습니다.
pip install toobuk

beautifulsoup4가 설치되지 안했다면 설치해주시길 바랍니다.
pip install beautifulsoup4

설치 여부 확인
pip list

아래 설명하는 부분에서 test.py와 test.json을 참고하시면서 보시면 됩니다.
예제는 장고에서 사용해보기 에서도 확인하실 수 있습니다.

가장 기본적인 사용법

아래와 같은 내용이 있습나다. 크롤링할 url과 bs.typ에서 사용하는 parser가 정의되어 있습니다.
output으로 list를 뽑아내는 데, 뽑아내는 데이타는 selector에 정의되어 있습니다.
selector에 대한 설명은 아래 url을 참고 하세요

https://www.crummy.com/software/BeautifulSoup/bs4/doc/#css-selectors

{
"housetrade" : {
            "url" : "https://www.index.go.kr/unity/potal/eNara/sub/showStblGams3.do?stts_cd=124001&idx_cd=1240&freq=Y&period=N",
            "bs.type" : "html.parser",
            "output" : {
                        "date" : {    "type" : "list",
                                   "pattern" : [ 
                                                {
                                                    "selector" : "#t_Table_124001 thead > tr:nth-of-type(1) > th",
                                                    "name" : "DATE"
                                                }
                                               ]
                                     }
                        }
                }
}

일단 위의 설정 파일을 test.json으로 저장합니다.
그리고 test.json이 저장된 디렉토리에 역시 test.py로 아래 소스를 저장합니다.

from toobuk.tb import Toobuk

htb = Toobuk('test') #설정 파일 test.json, .json은 생략
print( htb.get('housetrade') ) 

그리고 콘솔을 열어서 아래 명령을 실행합니다.

python test.py

결과는 아래와 같습니다.

[{'DATE': '\xa0'}, {'DATE': '201802월'}, {'DATE': '201803월'}, {'DATE': '201804월'}, {'DATE': '201805월'}, {'DATE': '201806월'}, {'DATE': '201807월'}, {'DATE': '201808월'}, {'DATE': '201809월'}, {'DATE': '201810월'}, {'DATE': '201811월'}, {'DATE': '201812월'}, {'DATE': '201901월'}]

output 설정

output 조정하기

배열의 첫번째 값이 이상합니다.
아래 그림이 위에서 url로 설정한 사이트를 캡쳐한 내용입니다. 테이블의 첫번째 th값이 비어있네요 저 th값을 빼고 가져와야할 듯 싶습니다.
캡쳐화면 그리고 데이타 형식으로 YYYY-MM으로 나왔으면 하구요.

{
"housetrade" : {
            "url" : "https://www.index.go.kr/unity/potal/eNara/sub/showStblGams3.do?stts_cd=124001&idx_cd=1240&freq=Y&period=N",
            "bs.type" : "html.parser",
            "output" : {
                        "date" : {    "type" : "list",
                                   "pattern" : [ 
                                                {
                                                    "selector" : "#t_Table_124001 thead > tr:nth-of-type(1) > th",
                                                    "name" : "DATE",
                                                    "slice" : {"start": 1 },
                                                    "regx" : { "pattern" : "(?P<YYYY>\\d{4})(?P<MM>\\d{2})." , "replace" : "\\g<YYYY>-\\g<MM>" }
                                                }
                                               ]
                                     }
                        }
            }
}

slice속성으로 첫번째 th부분을 제외했으며, regx 속성으로 포맷을 원하는 형태로 바꿨습니다.
regx에서는 정규표현식을 사용하는데요. 정규표현식 관련 내용은 아래 사이트에서 확인할수 있습니다.
https://regexr.com/
더해서 python에서는 하위표현식을 묶어내면서 이름표를 붙일 수 있는데요. 예제에서 보며 YYYY, MM이 그 내용입니다. 관련 내용은 아래에서 확인할 수 있습니다.
https://wikidocs.net/4309#_7

{'date': [{'DATE': '2018-02'}, {'DATE': '2018-03'}, {'DATE': '2018-04'}, {'DATE': '2018-05'}, {'DATE': '2018-06'}, {'DATE': '2018-07'}, {'DATE': '2018-08'}, {'DATE': '2018-09'}, {'DATE': '2018-10'}, {'DATE': '2018-11'}, {'DATE': '2018-12'}, {'DATE': '2019-01'}]}

그 밖에 형식을 지정할 수 있습니다. 지금은 int와 float만 지원됩니다. output이 여러개 설정된 경우에서 확인하실 수 있습니다.

output이 여러개 설정된 경우

웹 페이지를 긁어온 경우, 데이타가 여러개 설정이 될 수 있습니다. list가 하나가 될 수 있고, 두개도 될 수 있죠.
리스트가 아니라 일반 단일 형식이 또 있을 수 있습니다. 그 단일형식을 또 여러개로 나눌 수 있죠.
output에 추가만 해주면 됩니다. 밑에 예제가 있습니다.

{
"housetrade" : {
            "url" : "https://www.index.go.kr/unity/potal/eNara/sub/showStblGams3.do?stts_cd=124001&idx_cd=1240&freq=Y&period=N",
            "bs.type" : "html.parser",
            "output" : {
                        "date" : {    "type" : "list",
                                   "pattern" : [ 
                                                {
                                                    "selector" : "#t_Table_124001 thead > tr:nth-of-type(1) > th",
                                                    "name" : "DATE",
                                                    "slice" : {"start": 1 },
                                                    "regx" : { "pattern" : "(?P<YYYY>\\d{4})(?P<MM>\\d{2})." , "replace" : "\\g<YYYY>-\\g<MM>" }
                                                }
                                               ]
                                     }, 
                "changeRate" : {     "type" : "list", 
                                       "join" : { "ref" : "housecharter/changeRate", "joinKey" : ["DATE", "DATE"] },
                                    "pattern" : [
                                                 {
                                                    "selector" : "#t_Table_124001 thead > tr:nth-of-type(1) > th",
                                                    "name" : "DATE",
                                                    "slice" : {"start": 1 },
                                                    "regx" : { "pattern" : "(?P<YYYY>\\d{4})(?P<MM>\\d{2})." , "replace" : "\\g<YYYY>\\g<MM>" },
                                                    "type" : "int"
                                                }, {
                                                    "selector" : "#t_Table_124001 tbody > tr:nth-of-type(1) > td", 
                                                    "name" : "COUNTRY",
                                                    "type" : "float"
                                                }, {
                                                    "selector" : "#t_Table_124001 tbody > tr:nth-of-type(2) > td", 
                                                    "name" : "CAPATIAL",
                                                    "type" : "float"
                                                }, {
                                                    "selector" : "#t_Table_124001 tbody > tr:nth-of-type(3) > td", 
                                                    "name" : "SEOUL",
                                                    "type" : "float"
                                                }, {
                                                    "selector" : "#t_Table_124001 tbody > tr:nth-of-type(4) > td", 
                                                    "name" : "SOUTH",
                                                    "type" : "float"
                                                }, {
                                                    "selector" : "#t_Table_124001 tbody > tr:nth-of-type(5) > td", 
                                                    "name" : "NORTH",
                                                    "type" : "float"
                                                }
                                                ]

                                }
                        }
            }
    }

위에서는 output으로 date만 있었는데요. changeRate가 하나더 생겼습니다. python코드는 아래와 같습니다.

from toobuk.tb import Toobuk

htb = Toobuk('test') #설정 파일 test.json, .json은 생략

아래는 결과입니다. 그룹명(date, changeRate)을 기준으로 데이타가 만들어졌습니다.

{
    'date': [{'DATE': '2018-02'}, {'DATE': '2018-03'}, {'DATE': '2018-04'}, {'DATE': '2018-05'}, {'DATE': '2018-06'}, {'DATE': '2018-07'}, {'DATE': '2018-08'}, {'DATE': '2018-09'}, {'DATE': '2018-10'}, {'DATE': '2018-11'}, {'DATE': '2018-12'}, {'DATE': '2019-01'}], 

    'changeRate': [{'DATE': 201802, 'COUNTRY': 0.2, 'CAPATIAL': 0.5, 'SEOUL': 0.9, 'SOUTH': 1.2, 'NORTH': 0.7}, {'DATE': 201803, 'COUNTRY': 0.1, 'CAPATIAL': 0.3, 'SEOUL': 0.6, 'SOUTH': 0.6, 'NORTH': 0.6}, {'DATE': 201804, 'COUNTRY': 0.1, 'CAPATIAL': 0.2, 'SEOUL': 0.3, 'SOUTH': 0.3, 'NORTH': 0.3}, {'DATE': 201805, 'COUNTRY': 0.0, 'CAPATIAL': 0.1, 'SEOUL': 0.2, 'SOUTH': 0.2, 'NORTH': 0.3}, {'DATE': 201806, 'COUNTRY': 0.0, 'CAPATIAL': 0.1, 'SEOUL': 0.2, 'SOUTH': 0.1, 'NORTH': 0.4}, {'DATE': 201807, 'COUNTRY': 0.0, 'CAPATIAL': 0.1, 'SEOUL': 0.3, 'SOUTH': 0.3, 'NORTH': 0.4}, {'DATE': 201808, 'COUNTRY': 0.0, 'CAPATIAL': 0.2, 'SEOUL': 0.6, 'SOUTH': 0.6, 'NORTH': 0.6}, {'DATE': 201809, 'COUNTRY': 0.3, 'CAPATIAL': 0.7, 'SEOUL': 1.3, 'SOUTH': 1.5, 'NORTH': 1.0}, {'DATE': 201810, 'COUNTRY': 0.2, 'CAPATIAL': 0.4, 'SEOUL': 0.5, 'SOUTH': 0.5, 'NORTH': 0.6}, {'DATE': 201811, 'COUNTRY': 0.1, 'CAPATIAL': 0.3, 'SEOUL': 0.2, 'SOUTH': 0.1, 'NORTH': 0.3}, {'DATE': 201812, 'COUNTRY': 0.0, 'CAPATIAL': 0.1, 'SEOUL': 0.0, 'SOUTH': -0.1, 'NORTH': 0.2}, {'DATE': 201901, 'COUNTRY': -0.1, 'CAPATIAL': -0.1, 'SEOUL': -0.2, 'SOUTH': -0.3, 'NORTH': -0.1}]
}

output의 특정 그룹 하나 가져오기

#output에서 설정한 값 중 date만 가져옵니다.
print( htb.get('housetrade/date') ) 

output의 여러 그룹 가져오기

output에서 설정한 그룹들을 여러개 가져올 수 있습니다.

#&로 엮어서 가져오면 됩니다.
print( htb.get('housetrade/date&changeRate') ) 

output 전체 가져오기

#output 전체를 가져옵니다.
print( htb.get('housetrade') ) 

docker 설치 후, 확인

이렇게 되니 기왕 한 번 완전한 놈으로 한 번 만들어 보고픈 욕심에 장고와 연동시켜봤습니다.
https://github.com/ramoi/toobuk_vued3

위 내용은 docker를 설치하신 후에 확인할 수 있습니다.

콘솔에서 아래 명령어로 확인할 수 있습니다.

PS D:> docker pull ramoi/toobuk:0.1 PS D:> docker run -d -p 8000:5000 ramoi/toobuk:0.1

브라우져 접속 http://127.0.0.1:8000

실제 업무에서느 이렇게 쓰진 않겠지요. 빅데이타의 최전방 보명으로 쓰던지, 아니면 데이타베이스에 저장하겠지요.
그리고 더 중요한 것은 이 놈 보다 더 좋은 라이브러리가 많을 겁니다. 제가 자바를 주력 언어로 사용해서 파이썬 생태계를 잘 모르지만 pandas가 많이 쓰이는 것 같네요..

남은 것들

처음에는 python을 공부하면서, 무언가를 하나 만들어보면서 다지려는 마음이었습니다.
그런데 여기까지 왔네요. 테스트도 부족합니다. 하지만 누군가에게 조금이라도 도움이 되었다면 하는 바램입니다.