Programming Language/Python

[Python] 크롤링(Crawling)

LeeJaeJun 2023. 12. 29. 10:24
728x90
반응형

- 크롤링 주의 사항

특정 웹사이트의 페이지를 쉬지 않고 크롤링하는 행위를 무한 크롤링이라고 하는데, 이는 해당 웹사이트의 자원을 독점하게 되어 타인의 사용을 막게 되며 웹사이트에 부하를 줍니다.

일부 웹사이트의 경우 동일한 IP로 무한 크롤링을 할 경우 해당 IP의 접속을 막아버리기도 합니다.

그렇기에 하나의 페이지를 크롤링한 후 1~2초 가량 정지하고 다시 다음 페이지를 크롤링하는 것이 바람직합니다.

신문기사나 책, 논문, 사진 등 저작권이 있는 자료를 통해 부당이득을 얻는다는 등의 행위를 할 경우 법적 제재를 받을 수 있습니다.

 

서버에 데이터를 요청하는 형태는 다양하지만 크롤링에서는 주로 GET과 POST 방식을 사용합니다.

 

- GET 방식

  • 인터넷 주소를 기준으로 이에 해당하는 데이터나 파일을 요청하는 것
  • 주로 클라이언트가 요청하는 쿼리를 &(앰퍼샌드) 혹은 ?(물음표) 형식으로 결합해서 서버에 전달합니다.
  • 입력 항목에 따라 웹페이지 주소가 변경됩니다.

 

- POST 방식

  • 사용자가 필요한 값을 추가해서 요청하는 것
  • GET방식과 달리 클라이언트가 요청하는 쿼리를 body넣어서 전송합니다. 따라서 요청 내역을 직접 볼 수 없습니다.
  • 입력 항목이 달라져도 웹페이지 주소가 변경되지 않습니다.
  • POST방식의 데이터 요청 과정을 살펴보려면 개발자도구를 이용해야 합니다.(개발자도구의 Network 탭에서 브라우저와 서버 간의 통신과정을 살펴볼 수 있음)

 

- 크롤링 과정

  1. HTML 정보 받기: request 패키지의 get() 혹은 post() 함수를 이용해 데이터 요청 후 HTML 정보를 찾습니다.
  2. 태그 및 속성 찾기: bs4 패키지 등을 이용하여 원하는 데이터를 찾습니다.
  3. 클렌징
import requests as rq
from bs4 import BeautifulSoup
# Get방식 크롤링
url = 'https://quotes.toscrape.com'
quote = rq.get(url) #해당 사이트의 HTML 정보을 긁어옴

# quote.content는 text형태로

quote_html = BeautifulSoup(quote.content) # 개발자 도구에서 확인했던 것처럼 줄바꿈 등을 다 해줌. HTML요소에 접근하기 쉬운 BeautifulSoup 객체로 변경하는 것임

# class가 quote인 div 태그 안에 class가 Text인 span 태그 추출
quote_div = quote_html.find_all('div', class_ = 'quote')
# quote_div[0].find_all('span', class_= 'text')[0].text  텍스트 내용만 추출

[i.find_all('span', class_ = 'text')[0].text for i in quote_div]

# 데이터가 존재하는 곳의 태그를 여러 번 찾아 내려가야할 경우에는 find_all 보다는 select

quote_text = quote_html.select('div.quote > span.text') #  class가 div인 애의 하위에서 class가 text인 span을 찾아라
[i.text for i in quote_text]


# 테이블 형태로 크롤링을 해야할 때는 pandas를 사용. pd.read_html(url) -> 테이블을 데이터 프레임 형태로 불러옴

b

 

# POST 방식 크롤링
# POST 방식은 요청하는 데이터에 대한 쿼리가 body의 형태를 통해 전송되므로 개발자도구 화면을 통해 해당 쿼리에 대한 내용을 확인해야 합니다.
# 이는 개발자도구의 network에서 확인가능

import requests as rq
form bs4 import BeautifulSoup
import pandas as pd

url = 'https://kind.krx.co.kr/disclosure/todaydisclosure.do'

payload = {
	'method' = 'searchTodayDislosureSub',
    'currentPageSize': '15',
    'pageIndex': '1',
    'orderMode': '0',
    'orderStat': 'D',
    'forward': 'todaydisclosure_sub',
    'chose': 'S',
    'todayFlag': 'N',
    'selDate': '2023-01-10' #이 부분을 바꾸면 다른 날짜를 볼 수 있음
}

data = rq.post(url, data = payload)
html = BeautifulSoup(data.content) # 엑셀형식을 html로 불러온거라 안예쁨
html_unicode = html.prettify() # prettify()함수를 이용해 BeautifulSoup에서 파싱한 파서 트리를 다시 유니코드 형태로 돌려줍니다.

tdl = pd.read_html(html_unicode) # 테이블을 데이터 프레임 형태로
728x90
반응형