[KT AIVLE School 4기] 3주차 - 웹 크롤링(1)

늘보·2023년 8월 26일
0

3주차

이번 주는 미니 프로젝트와 웹 크롤링이 진행되는 주간이었다. 그 중에서 우선은 목요일 금요일 동안 진행되었던 웹 크롤링 강의에 대해서 정리해보고자 한다. 강사님께서 웹의 전체적인 원리와 구조도 같이 설명해주시면서 진행해주셨지만 여기서는 아마도 내가 나중에 다시 크롤링할 때 사용해볼 수 있게 코드 위주로 살펴보자.

웹페이지의 종류

웹페이지의 종류에 따라 크롤링 방식이 달라지기 때문에 웹페이지를 보고 종류를 파악할 줄 알아야 한다. 크게 정적인 페이지, 동적인 페이지로 나눠지고 동적인 페이지가 일반적으로 크롤링이 좀 더 빠르다고 한다.
1. 정적인 페이지 : 웹 브라우저에 화면이 한 번 뜨면 이벤트에 의한 변경이 없는 페이지이다. 즉 새로운 이벤트가 발생한다면 url 주소가 바뀌게 된다. 주로 html을 받아와 크롤링하게 된다.
2. 동적인 페이지 : 웹 브라우저에서 이벤트가 발생하면 서버에서 데이터를 가져와 화면을 변경한다. 새로운 이벤트가 발생해도 url은 바뀌지 않고 네트워크 트래픽에 의해 변경된 페이지를 받아오게 된다. 주로 json 문자열을 받아 크롤링하게 된다.

  • 주로 request를 통해 html 혹은 json을 받아와 크롤링하게 되지만 특정한 이유에 의해서 브라우저를 직접 열어서 데이터를 받아야 하는 경우가 있고, 해당 경우에는 requests가 아닌 selenium을 활용해 크롤링하게 된다. selenium을 통한 크롤링 방법 또한 살펴볼 것이다.

동적 페이지 크롤링

동적 페이지 크롤링의 경우 주로 requests를 통해 json을 받아오고 해당 json을 파싱해서 필요한 부분을 크롤링하게 된다. json의 경우 데이터 프레임 등으로의 변환이 용이해 비교적 쉬운 크롤링에 속하고 속도 또한 가장 빠르다.

url = ''
response = request.get(url)
response

개발자 도구를 통해 더보기 버튼 혹은 내가 원하는 이벤트에서 발생하는 네트워크(개발자 도구 -> network -> fetch)의 url을 찾는다. 사실상 웹크롤링에서 가장 중요한 부분은 개발자 도구를 통한 url 분석이고 이는 많은 경험을 통해서 성장해야 하는 부분인 것 같다. 이렇게 url을 찾았다면 해당 url에서 request를 통해 json을 추출한다. 만약 url에서 특정 부분만 변경하며 데이터를 추출할 수 있도록 함수화 하고 싶다면 f포멧팅을 활용해보자. 이렇게 받아온후 response를 출력하면 숫자가 출력이 되는데 200이 나온다면 제대로 수집이 된 것이고, 그렇지 않은 경우 코드가 잘못 되었거나 수집을 막아놓았을 수도 있으니 header를 설정해보거나 selenium을 통한 직접 수집을 시도해보자.

response.text[:200]
columns = []
data = response.json()
df = pd.DataFrame(data)[columns]

response.text를 통해 필요한 부분의 key값을 확인하고 json()으로 변환 후 원하는 키값에 해당하는 부분들을 데이터 프레임화하여 수집한다. 이후 이 일련의 과정을 함수화 또는 모듈화 하면 해당 코드를 계속 작성하지 않아도 쉽게 크롤링할 수 있다.

header 설정

위의 코드만으로도 수집되는 경우가 있지만, 페이지의 종류의 차이가 아니라 해당 서버에서 코드를 통한 수집을 막아놓은 경우가 있다. 이런 경우 request.get(url)을 통해 수집하면 403등의 에러가 발생한다. 오류 메세지를 확인해 header에서 필요한 부분을 설정해 전송할 수 있다. 강의에서 다루어진 예시에서는 header에서 user-agent와 referer을 미리 설정해 실제 컴퓨터에서 실행하는 경우와 같게 설정한다면 수집이 가능해진다. 해당 네트워크에서 header 부분을 참조한다.(네트워크가 이게 맞는지 헷갈린다면 response탭에서 내가 원하는 정보가 있는지 확인하는 것도 방법이다.)

url = ''
headers = {
	"user-agent": "",
    "referer" : "",
}
response = request.get(url, header = headers)

이렇게 header들을 다시 설정해주면 정상적으로 수집이 되는 것을 볼 수있다.

API 활용

만약 데이터를 수집하고 싶은 해당 서비스에서 api를 제공한다면 가장 수월하게 데이터를 수집 및 이용할 수 있다.
해당 서비스에서 id, key 값들을 배정받고 해당 api를 활용해 사용할 수 있는 것이다. 사용법이 어렵지는 않고 서비스에 따라서 약간 씩 다른 사용법을 document를 통해 제공하니 여기서는 다루지 않도록 하겠다. 대체적으로 앞에서 했던 것 처럼 header와 함께 params를 설정해 활용할 수 있다.

도메인 활용

웹 페이지 내에서의 데이터가 다양한 만큼 도메인에 대한 지식이 필요한 경우들이 있다. 강의 중에서는 직방 데이터를 수집하는 경우를 다뤘는데 지도에서 해당 위치를 경도, 위도로 입력하고 geohash라는 개념을 통해 해당 위도 경도에서 근방 지역을 설정할 수 있는데 이는 geohash가 무엇인지, 그리고 geohash를 어떻게 추출할 수 있는지에 대한 정보가 필요하다.

0개의 댓글