스크래핑이란?
웹 스크래핑은 인터넷에서 필요한 정보를 자동으로 가져오는 방법입니다. 마치 우리가 웹사이트를 돌아다니면서 필요한 정보를 복사해서 저장하는 것처럼, 컴퓨터 프로그램이 자동으로 이 작업을 수행하는 것이죠.
예를 들어, 온라인 쇼핑몰에서 상품 가격을 비교하고 싶을 때, 일일이 각 사이트를 방문해서 가격을 확인하는 대신 스크래핑 프로그램이 자동으로 여러 쇼핑몰의 가격 정보를 수집할 수 있습니다.
이런 스크래핑 기술을 사용하면 수작업으로 하기 힘든 많은 양의 데이터를 빠르고 정확하게 수집할 수 있어서, 데이터 분석이나 연구에 매우 유용하게 활용됩니다.
스크래핑(Scraping)과 크롤링(Crawling)의 차이:
- 스크래핑: 특정 웹페이지에서 원하는 데이터를 추출하는 작업
- 크롤링: 여러 웹페이지를 자동으로 탐색하며 링크를 따라다니는 작업
쉽게 말해, 크롤링은 웹을 '돌아다니는' 것이고, 스크래핑은 원하는 정보를 '가져오는' 것입니다.
스크래핑 방법 2가지
스크래핑 방법은 브라우저 원래의 역할인 url요청방식을 추상화하여 프로그램적으로 다루는 requests방식과 크롬이나 safari같은 브라우저 자체를 자동화하는 방식 두가지가 있습니다.
requests
Requests는 Python에서 가장 널리 사용되는 HTTP 라이브러리입니다. 웹 브라우저처럼 작동하여 웹 페이지에 요청을 보내고 응답을 받아올 수 있습니다.
주요 특징:
•
간단한 문법으로 GET, POST 등의 HTTP 요청을 보낼 수 있음
•
헤더, 쿠키, 세션 등의 HTTP 요소를 쉽게 다룰 수 있음
•
JSON, XML 등 다양한 형식의 데이터를 처리할 수 있음
•
응답 상태, 내용 등을 쉽게 확인할 수 있음
Requests를 사용하면 마치 웹 브라우저로 웹사이트를 방문하는 것처럼 프로그래밍적으로 웹 페이지에 접근하여 데이터를 수집할 수 있습니다.
브라우저 자동화
브라우저 자동화는 Selenium과 같은 도구를 사용하여 웹 브라우저를 프로그래밍적으로 제어하는 방법입니다. 실제 브라우저를 열어 사용자의 행동을 모방하면서 데이터를 수집할 수 있습니다. 이 방식은 JavaScript로 동적으로 생성되는 콘텐츠나 사용자 상호작용이 필요한 웹사이트를 스크래핑할 때 특히 유용합니다.
브라우저 자동화 도구로는 Selenium 외에도 Playwright, Puppeteer, Cypress, Mechanize, RoboBrowser 등이 있습니다. 각각의 도구는 고유한 특징과 장단점을 가지고 있어 상황에 맞게 선택하여 사용할 수 있습니다. 추후에 순차적으로 학습을 진행할 예정입니다.
먼저 선행학습?? 해보고싶다면 제 블로그내용을 참고 하세요! 몇년전에 작성해서 당장 실행은 불가능하지만 개념자체를 설명했던것이기 때문에 이해는 가능 할겁니다. (블로그 홍보아님)
학습 목표
KIND 기업공시채널에서 "상장법인목록" 데이터를 requests방식으로 스크래핑할 예정입니다. 이를 통해 상장사의 종목코드, 회사명, 주요제품 등의 데이터를 수집할 수 있습니다. 특히 회사의 주요제품 정보는 투자 결정에 활용할 수 있는 유용한 데이터입니다.
KIND(Korea Investor's Network for Disclosure)는 한국거래소(KRX)가 운영하는 상장법인 공시 시스템입니다. 이 시스템은 상장기업들의 주요 경영정보와 재무정보를 투자자들에게 신속하고 정확하게 제공하는 것을 목적으로 합니다.
주요 기능으로는
•
상장기업의 공시정보 실시간 제공
•
기업 재무제표 및 경영실적 정보 공개
•
주요 경영사항 및 이벤트(증자, 배당, 합병 등) 공시
•
기업지배구조 관련 정보 제공
KIND는 투자자들이 투자 의사결정에 필요한 기업정보를 투명하게 확인할 수 있도록 하여, 한국 자본시장의 신뢰성과 투명성 향상에 기여하고 있습니다.
스크래핑의 시작: URL 이해하기
웹사이트의 데이터를 가져오기 위해서는 먼저 해당 데이터가 있는 페이지의 정확한 URL을 알아야 합니다. URL은 마치 웹사이트의 주소와 같아서, 이를 통해 스크래핑 프로그램이 어디서 데이터를 수집할지 알 수 있죠. 특히 KIND와 같은 공시 시스템의 경우, URL 구조를 이해하면 원하는 정보가 있는 페이지에 직접 접근할 수 있습니다.
위의 화면에서는 URL이 https://kind.krx.co.kr/corpgeneral/corpList.do로 되어 있습니다. 하지만 이 URL에 직접 접속하면 아래 이미지와 같이 "서비스 이용에 불편을 드려 죄송합니다"라는 메시지가 표시됩니다.
개발자도구 : 네트워크
브라우저의 개발자 도구에서 네트워크 탭은 웹페이지와 서버 간의 모든 통신을 모니터링하고 분석할 수 있는 강력한 도구입니다.
실시간 요청 확인: 웹페이지가 서버에 보내는 모든 HTTP 요청과 응답을 실시간으로 확인할 수 있습니다.
데이터 분석: 요청의 헤더, 파라미터, 응답 데이터 등 상세한 정보를 검사할 수 있습니다.
성능 모니터링: 각 요청의 로딩 시간, 크기 등을 확인하여 성능 병목현상을 파악할 수 있습니다.
스크래핑 관점에서 네트워크 탭은 특히 중요한데, 웹사이트가 데이터를 어떻게 주고받는지 이해하고 필요한 데이터가 정확히 어디에서 오는지 파악할 수 있게 해줍니다. 예를 들어, KIND 사이트에서 상장법인 목록을 가져올 때 실제로 어떤 API가 호출되는지 확인할 수 있습니다.
필수정보1. URL과 Method
네트워크 탭에서 스크래핑을 위해 반드시 확인해야 할 두 가지가 있습니다. 바로 URL과 Method입니다. Method에는 GET 방식과 POST 방식이 있으며, 각각의 방식으로 요청을 보내야 합니다.
GET 방식:
•
URL에 데이터를 포함하여 요청
•
데이터가 주소창에 노출됨
•
주로 데이터 조회할 때 사용
•
북마크 가능, 캐시 가능
POST 방식:
•
요청 본문에 데이터를 포함
•
데이터가 주소창에 노출되지 않음
•
주로 데이터 생성/수정할 때 사용
•
더 많은 데이터 전송 가능
필수정보2. Payload
Payload(페이로드)는 POST 요청에서 서버로 전송되는 실제 데이터를 의미합니다. KIND 사이트에서 상장법인 목록을 요청할 때도 특정 Payload가 필요한데, 이는 데이터를 필터링하고 원하는 형식으로 받기 위한 중요한 정보를 담고 있습니다. 개발자 도구의 네트워크 탭에서는 이 Payload 정보를 쉽게 확인할 수 있습니다.
이 Payload는 서버가 이해할 수 있는 특정 형식으로 데이터를 전송해야 합니다. 예를 들어, KIND 사이트에서는 다음과 같은 옵션들을 Payload에 포함시켜야 합니다
currentPageSize: 한 페이지에 표시할 기업 수
pageIndex: 현재 페이지 번호
marketType: 시장구분 (코스피/코스닥 등)
이러한 옵션들을 올바른 형식으로 전송해야만 서버가 우리가 원하는 데이터를 정확하게 반환할 수 있습니다. 마치 주문서를 작성할 때 필요한 항목들을 정확히 기입하는 것과 같다고 볼 수 있죠.
아래 영상을 보면 검색 조건에 따라 payload 값이 달라지는 것을 알 수 있습니다. 이는 payload에 전송하는 조건에 따라 서버가 다른 데이터를 반환한다는 의미입니다.
전체 데이터를 받으려면?
앞서 검색 조건에 따라 payload가 달라지는 것을 살펴봤습니다. 하지만 한 가지 불편한 점이 있죠. 이 방식으로는 회사 데이터를 한 번에 받을 수 없다는 것입니다. 반복문으로 조건을 바꿔가며 모두 수집할 수도 있지만, 더 효율적인 방법이 있습니다. 화면 좌측의 Excel 버튼을 보셨나요? 이 버튼을 클릭하면 상장사 목록을 한 번에 엑셀로 다운로드할 수 있습니다. 이제 이 버튼을 클릭했을 때 payload가 어떻게 변하는지 확인해 보겠습니다.
보셨나요? method가 검색 조건에서 다운로드 조건으로 변경된 것을 확인할 수 있습니다. 모든 데이터를 한 번에 다운로드할 수 있는 조건이 있었던 것이죠! 이제 본격적으로 코드를 작성해 보겠습니다.
스크래핑 코드
1. 참고지식
2. 코드스니펫
코드 스니펫의 각 주석은 필요한 학습페이지가 모두 링크로 연결 되어 있습니다.
import requests # import 참고
import pandas as pd
def getCorpList(): # 함수 참고
# 변수참고
url = 'https://kind.krx.co.kr/corpgeneral/corpList.do'
# 딕셔너리 참고 : 자료형 내부의 매핑형
data = {
'method': 'download',
'orderMode': '1',
'orderStat': 'D',
'searchType': '13',
'fiscalYearEnd': 'all',
'location': 'all',
}
r = requests.post(url, data=data) # requests 참고
df = pd.read_html(r.content, header=0) # pandas 참고
df = df[0]
return df
getCorpList()
Python
복사
3. 코드분해
코딩 공부를 가장 빠르게 이해하는 방법은 누군가가 만든 코드를 직접 하나씩 실행해보는 것입니다. 코드가 왜 실행되는지, 왜 실행되지 않는지, 어디에서 오류가 발생하는지, 왜 이런 방식으로 작성했는지를 직접 확인하면서 이해할 수 있습니다.
1) import
import requests # requests http 브라우저를 추상화 해서 url에 요청
import pandas as pd # 데이터프레임으로 생성
Python
복사
2) 함수선언
def로 함수를 선언합니다. def 함수 페이지에서 설명했듯이, def 예약어로 함수 선언을 시작하고 원하는 함수명을 지정합니다. getCorpList는 상장법인 목록을 가져온다는 의미를 카멜 표기법으로 작성한 것입니다. 스네이크 표기법을 선호하신다면 get_corplist처럼 작성해도 됩니다.
def getCorpList():
# 실행코드
return 결과
Python
복사
3) URL정의
변수 'url'에 KIND 사이트의 상장법인목록을 가져오는 URL 주소를 저장합니다.
def getCorpList():
url = 'https://kind.krx.co.kr/corpgeneral/corpList.do'
Python
복사
4) 데이터 형태 옵션 설정
def getCorpList():
url = 'https://kind.krx.co.kr/corpgeneral/corpList.do'
data = {
'method': 'download',
'orderMode': '1',
'orderStat': 'D',
'searchType': '13',
'fiscalYearEnd': 'all',
'location': 'all',
}
Python
복사
5) requests.post
KIND 상장법인목록 URL은 POST 방식으로 데이터를 요청해야 합니다. requests 라이브러리의 POST 함수를 사용하여 URL에 데이터를 전송하겠습니다. 그리고 그 결과를 “r”에 받고 출력해보겠습니다.
def getCorpList():
url = 'https://kind.krx.co.kr/corpgeneral/corpList.do'
data = {
'method': 'download',
'orderMode': '1',
'orderStat': 'D',
'searchType': '13',
'fiscalYearEnd': 'all',
'location': 'all',
}
r = requests.post(url, data=data)
Python
복사
HTTP 상태 코드 200의 의미
- 200은 HTTP 요청이 성공적으로 처리되었다는 것을 나타냅니다
- "<Response [200]>"가 출력되면 서버가 요청을 정상적으로 받아들이고 응답했다는 의미입니다
- 주요 상태 코드
• 200: 성공
• 404: 페이지를 찾을 수 없음
• 403: 접근 권한 없음
• 500: 서버 내부 오류
6) r.text
r.text는 requests로 받아온 컨텐츠인 r을 텍스트로 변환하는 작업을 합니다. 이를 출력 해보면 <tr> <td>태그가 보입니다. tr과 td는 HTML 테이블을 구성하는 기본적인 태그입니다
tr (Table Row): 테이블의 행을 나타내는 태그로, 가로줄을 만듭니다
td (Table Data): 테이블의 셀을 나타내는 태그로, 실제 데이터가 들어가는 칸을 만듭니다
즉, 스크래핑한 데이터가 테이블 형태로 구성되어 있다는 것을 의미합니다.
7) pd.read_html
판다스의 read_html은 HTML 구조에서 table 태그를 찾아 데이터프레임으로 변환하는 기능입니다. 이 함수는 페이지 내의 모든 table을 찾아 순서대로 리스트 형태로 반환합니다.
8) 리스트에서 요소 추출
마지막 df = df[0]은 read_html에서 추출된 데이터프레임들의 리스트에서 첫 번째 데이터프레임을 가져오는 과정입니다. 리스트 다루는 방법은 추후에 자세히 설명하겠습니다. 설명을 추가한 후에 관련 링크를 연결해드리겠습니다.
import requests
import pandas as pd
def getCorpList():
url = 'https://kind.krx.co.kr/corpgeneral/corpList.do'
data = {
'method': 'download',
'orderMode': '1',
'orderStat': 'D',
'searchType': '13',
'fiscalYearEnd': 'all',
'location': 'all',
}
r = requests.post(url, data=data)
df = pd.read_html(r.content, header=0)
df = df[0] # 리스트 내부 요소 추출
return df
getCorpList()
Python
복사
4. 실행 영상
Google Colab의 기본 기능으로 가져온 데이터를 다양하게 분석할 수 있습니다. 현재 소개한 코드는 기본적인 스크래핑 방법을 보여주는 예시이며, 오류 처리나 예외 상황을 고려하여 더욱 개선할 수 있습니다. 계속 공부하면서 더 효율적인 코드를 만들어 보세요.
5. 주의사항
무분별한 스크래핑은 삼가해 주세요. 상장법인목록이 무단 배포가 우려될 정도의 민감한 데이터는 아니지만, 반복문 테스트를 이유로 연속적인 요청을 보내는 것은 절대 안 됩니다.
6. 실습하기
colab으로 실습하세요!!