크롤링 막아놓은 사이트 - keulolling mag-anoh-eun saiteu

크롤링이 안될 때

Table of contents
  1. 크롤링이 막혀있는 경우

크롤링이 막혀있는 경우

간혹 웹사이트 중에서 크롤링을 막아 놓은 사이트들이 있다. 개인적으로 크롤링 연습을 위해 멜론 사이트를 크롤링하는데 계속 되지 않아서 requests로 url을 가져오자 <Response [406]> 상태코드를 확인할 수 있었다. HTTP 상태코드를 확인해보면 406은 Not Acceptable로 사용자 에이전트에서 정해준 규격에 따르지 않아 사이트에 접근할 수 없는 경우이다. 따라서 이 경우에 크롤링을 하기 위해서는 User-agent 헤더를 보내야 한다. 나는 로봇이 아니라 유저정보를 갖고 있는 사람일껄? 이라고 알려주는 역할을 한다.

headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'} url ='url 주소' html = requests.get(url, headers = headers).text

  • url를 입력하기 전에 미리 헤더를 보내야 한다
  • requests로 url을 가져올 때 url 주소 외에도 headers = headers 를 써야 한다

간혹 requests.get으로가져가게막아놓은사이트가있다.

그런경우크롬 개발자 도구의 network탭으로 가면 페이지 변환이 일어나거나 데이터 전송이 일어나는 경우에 네트워크에서 전송되는 파일의 목록을 확인할 수 있다. 

이런 경우에 해당 내용을 보면서 데이터가 어떻게 전송되는지 확인하면 json파일로 쉽게 정보를 가져올 수도 있고,

간혹 일반 url만으로 정보가 오지 않는 경우 해당 url 뒤에 쿼리스트링으로 Request Headers나온것을객체로만들어서 함께 전달하면 정보를 받을 수 있는 경우가 있다.

동일 사이트 : 정보 가져오지 못함

import requests import re from bs4 import BeautifulSoup url = "//www.jolse.com/category/moisturizer/1017/?page=2" html = requests.get(url) print(html.text)

(결과값)

동일 사이트 : headers 첨부로 정보 가져옴

import requests import re from bs4 import BeautifulSoup url = "//www.jolse.com/category/moisturizer/1017/?page=2" headers = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"} html = requests.get(url,headers=headers) print(html.text)

(결과값)

사이트마다 정보를 가져오는 방법은 다양하다.

  • requests.get( ) 으로 정보를 주는 경우
  • json 이나 xml 파일로 데이터를 전송하는 경우
  • headers에 정보를 가지고 가야 정보를 주는 경우
  • 크롤러로 다수 정보를 요청하는 경우 막는 경우 등

웹 크롤러를 만들기 위해서는 기본적으로 사이트에 대한 분석이 제대로 되어야 하며, 네트워크를 통해 전송되는 데이터 타입과 데이터 전송 방법에 대한 이해를 하고 있는 것이 좋다.

우리가 보통 컴퓨터로 들어가는 사이트의 화면과 휴대폰으로 들어가는 사이트의 화면은 다르다.

pc에서의 네이버 화면과, 휴대폰에서의 네이버 화면이 다르다.

이는 우리가 웹사이트에 접속할 때, 우리의 정보를 가지고 웹사이트에서 스마트폰인지 데스크탑인지

판단해서 보여주는 그런 정보를 담고 있다.

더보기

더보기

더보기

소프트웨어 에이전트가 네트워크 프로토콜 안에서 동작할 때, 문자적 식별 문자열을 피어(peer)에 제출함으로써 종종 자기 자신과 애플리케이션 유형, 운영 체제, 소프트웨어 업체, 소프트웨어 리비전을 식별한다. HTTP,[2] SIP,[1], NNTP[3] 프로토콜에서 이러한 식별 정보는 User-Agent라는 헤더 필드를 통해 전달된다. 웹 크롤러와 같은 은 종종 URL이나 이메일 주소를 포함하기도 하며 이로 말미암아 웹마스터가 봇의 운영자와 연락을 취할 수 있다.

라고 한다.

즉, 나에 대한 정보라고 쉽게 생각하면 될 것 같다.

내가 직접 접속을 하는 것과, requests를 통해 접속을 하는 것 또한 user-agent가 다르다.

2. 왜 알아야 하는가?

무분별한 크롤링과 서버 과부하를 막기 위해 사람이 직접 접속한게 아니라 프로그램을 통하여 접속하는 것을 차단하는 사이트들이 있다.

내가 직접 검색을 해서 들어가면 상관이 없지만, requests를 통해서 접속을 하려고 하면 막아 놓는 사이트가 있다.

예를 들어서 "//www.melon.com"이다. 멜론 같은 경우에는 옆의 링크를 통해 접속하면 정상적으로 접속이 된다.

하지만, requests를 통해서 접속을 하려고 하면??

'406' 코드와 함께 아무것도 가져 오지 않는다.

다른 예로 response.stauts_code가 아닌 raise_for_status()를 사용해보자

와우

이렇게 오류가 떠버린다.

즉, 멜론 사이트는 내가 직접 접속한 것은 허용하지만, requests를 통해 크롤링하려는 것은 차단한다.
(아마 순위 조작 이런 이유가 아닐까???)

하여튼 이럴 때 써야 하는 것이 User-Agent이다. 내가 순위 조작 이런 이유가 아니라 뭐 다른 이유에 의해서

멜론 사이트를 크롤링 해야할 때, User-Agent를 바꿔서 내가

"requests를 통해 HTTP를 요청한게 아니라 내가 직접 사이트에 들어가서 HTTP를 요청하는거야 "

라고 속일 수가 있다.

3. 나의 User-Agent

What is my user agent?

Every request your web browser makes includes your User Agent; find out what your browser is sending and what this identifies your system as.

www.whatismybrowser.com

위의 사이트에 들어가면

저기에 있는 Your User Agent is: 에 있는 이상한 값이 나의 User-Agent이다.

그리고, 내가 크롬에서 접속할 때와 인터넷 익스플로러에서 접속했을 때의 User-Agent는 또 다르다.

4. 사용법

User-Agent가 뭐하는 정보인지, 그리고 내가 직접 접속했을 때의 나의 User-Agent는 무엇인지 알았으니 이제 써먹을 일만 남았다.

일단 저기 User-Agent의 정보를 복사하자.

복사를 한 후 내가 쓴 코드처럼 똑같이 한 번 써보자.

header = {"User-Agent": "나의 User-Agent"} response = requests.get(url, headers=header)

똑같이 쓰지는 말고, 나의 User-Agent에 나의 User-Agent를 복사해서 넣으면 된다.

그리고 나서 requests.get 파라미터에 'headers=' 에 내가 위에서 만든 header를 넣어주면 된다.

그러면 이 requests는 내가 직접 접속하는 것과 같은 효과?를 가질 수 있게 된다.

한 번 실행해보자.

단순히 User-Agent만 바꿔줬을 뿐인데, 다른 결과가 나왔다. 아까는 '406' 코드가 왔지만 지금은 '200' 코드, 즉, 정상 응답 코드가 나왔다.

또한 response.text를 출력하면,

정상적으로 값이 나온다.

따라서 User-Agent를 바꿔줌으로써 크롬에서 가져온 것과 똑같은 웹사이트를 가져올 수가 있다.

이렇게 해서 제대로된 HTML 문서를 가지고 웹 스크래핑을 할 수가 있다.

5. 요약

쉽게 말해서 User-Agent는 나의 정보를 담은 것이다.

크롬으로 직접 접속한 것과 requests를 통해 접속한 것은 다른 User-Agent를 갖는다.

하지만 몇몇 웹사이트는 requests를 통해 접속하는 것을 막는 사이트가 있다.

따라서 requests를 통해 접속을 할건데, 크롬에서 접속하는 것과 똑같이 받아오고 싶다면,

나의 User-Agent를 크롬에서 접속하는 것과 똑같이 만들어 주면 된다.

header = {"User-Agent": "나의 User-Agent"} response = requests.get(url, headers= header)

를 통해 requests를 통해 접속하는 것이, 크롬에서 접속하는 것과 동일한 User-Agent를 만들어 주었다.

참고 : 나도 코딩

Toplist

최신 우편물

태그