HTTP

크롤링을 하기위한 HTTP 기본 지식을 설명한다.

HTTP(Hypertext Transfer Protocol)

브라우저는 HTTP라는 프로토콜을 사용해 웹 서버와 통신한다. 크롤러는 브라우저처럼 웹서버와 통신해서 콘텐츠를 수집하므로 당연히 웹 브라우저와 같은 HTTP를 사용해 웹 서버와 통신해야 한다.

What is HTTP?

www(World Wide Web)의 기초이며 하이퍼 텍스트 링크를 사용하여 웹 페이지를 로드하는데 사용된다. HTTP는 네트워크로 연결된 장치간에 정보를 전송하도록 설계된 애플리케이션 계층 프로토콜이며, 네트워크 프로토콜 스택의 다른 계층에서 실행된다.

HTTP는 브라우저가 어떤 URL에 요청을 전송하면, 웹 서버가 해당 URL에 대응하는 콘텐츠로 응답하는 것일 뿐이다.

HTTP 메서드

HTTP에는 여러 request 메서드가 있다. 참고로 버전마다 지원되는 메서드가 다르며, 웹 애플리케이션의 처리는 대부분 GET, POST, PUT, DELETE로 이루어져있다.

  • POST - create

  • GET - read

  • PUT - update

  • DELETE - delete

참고로 HTML 입력 양식에는 GETPOST 메서드만 사용할 수 있다.

<form method="PUT" action="/posts">
...
</form>

또한 환경에 따라 GETPOST 이외의 요청은 방화벽에 의해 막힐 수 있다. 그래서 실제로 GETPOST 메서드로만 구축된 웹 사이트가 많다.

크롤러는 HTML 등의 리소스를 다운로드하는 것이므로 기본적으로 GET 메서드를 사용하지만, 다른 메서드를 사용해야 하는 경우도 존재한다. 물론 크롤링하려는 사이트가 기본 규칙을 준수해서 사이트를 구성했을 수도 있지만, 안 지킨 경우도 많아 주의해야 한다.

일부 메서드가 지원되지 않는 경우

웹 사이트에 따라 HTTP에서 정의하는 메서드 중 일부를 지원하지 않는 경우가 있다. 특히 크롤링할 때는 HEAD 메서드를 지원하지 않는 웹 사이트이다.

HEAD 메서드는 response body를 반환하지 않는다. 따라서 변경됐을 가능성이 낮은 콘텐츠의 경우 일단 HEAD 메서드를 사용해 Last-Modified 헤더를 확인하고 이 값이 변경된 경우에만 GET 메서드를 사용해 다운로드하게 구현하면 통신량을 크게 줄일 수 있다.

HEAD 메서드를 지원하지 않는 경우 요청된 메서드를 지원하지 않는다는 것을 나타내는 405 Method Not Allowed, 501 Not Implemented를 응답하는 것이 기본이지만, HEAD 요청에 404 Not Found를 응답하는 잘못 구현된 웹 사이트도 있다.

또한 서버로부터 응답받은 상태 코드가 원래 의미를 나타내는지 확인하기 힘든 경우도 있다. 이런한 경우 curl 명령어 등으로 요청을 보내서 응답을 확인해 판단해야 한다.

메서드의 사용 방법이 적절하지 않은 경우

메서드는 지원되지만 해당 메서드가 원래 의미로 사용되지 않는 경우도 있다.

메서드는 지원되지만 부득이하게 메서드가 원래 의미로 사용되지 않는 경우도 있다. 아래와 같은 케이스가 있음을 인지하고 대응할 수 있도록 하자.

GET이 아니라 POST 메서드로 화면 이동

오래된 웹 사이트에서 나타날 수 있는 상황이다. 이렇게 구현되었던 이유는 화면 이동시 필요한 매개 변수가 너무 많아서 쿼리 문자열로 이를 처리하기 힘든 경우, 캐시를 강제로 막고 페이지에 접근할 때마다 새로운 콘텐츠를 출력하게 하고 싶을 때 등이 있다.

물론 설계로 위 문제를 해결하거나, meta 태그를 통해 캐시 여부를 제어할 수는 있지만, 분명 그렇게 작성되어야 했던 이유가 있었을 것이다.

GET 메서드로 데이터 변경 처리를 하는 경

원래는 POST 메서드로 처리를 하는게 맞지만, 이런 경우도 존재하긴 하다.

<a href="/delete/post/1">delete</a>

크롤러가 이러한 페이지를 순회하면 데이터가 모두 제거될 수 있어, 유의해야 한다. 만약 웹 사이트를 만들때 꼭 GET 메서드로 데이터 변경 처리를 해야한다면, rel="nofollow"를 추가해 주자.

<a href="/delete/post/1" rel="nofollow">delete</a>

URL 인코드 방식의 차이에 따른 문제

URL에 사용할 수 없는 문자(기호나 한국어, 공백 등)가 포함된 경우 및 URL에서 다른 의미를 갖는 일부 문자가 있는 경우, URL-encoding 또는 percent-encoding 이라고 부르는 일종의 이스케이프 처리를 해야한다.

URL 인코딩이란, 문자를 바이트 단위로 변환하게 되며 일반적으로 %16진수 로 변환하게 된다. 그러다보니, 어떤 문자 코드(EUC-KR, UTF-8)로 인코딩할지에 따라 결과가 달라진다. 서버쪽에서는 인코딩된 문자열을 받으면 당연히 같은 문자 코드로 디코드해야 한다. 다른 문자로 디코드하면 문자 깨짐이 발생한다.

공백(space) 인코드 방법 차이

실제로 자주 문제가 되는 부분이다. RFC3986에서 정의한 URL에 사용하는 인코딩 방식은 공백을 %20으로 인코딩하지만, POST 메서드에서 사용하는 application/x-www-form-urlencoded에서는 공백을 +로 인코딩한다.

HTTP/2

2015년 나온 HTTP의 새버전이다. HTTP/2는 기존 HTTP와 호환성을 가지면서도 빠른 통신을 가능하게 해주는 차세대 프로토콜이다.

HTTP/1.1은 기본적으로 하나의 커넥션으로 하나의 요청만 처리했다. 물론 이 버전에서도 HTTP 파이프라인이라는 기능을 통해 하나의 커넥션으로 병렬 처리를 할 수 있지만, "서버는 반드시 요청을 받은 순서대로 응답해야 한다"라는 규칙이 있어 어떤 요청 처리에 시간이 걸리는 경우 후속 요청 모두 늦어지는 문제가 있다. 또한 HTTP 파이프라인은 웹 브라우저와 프록시 서버가 모두 지원해야 하는 문제가 있어 한계가 존재했다(2018년부터는 여러 문제로 인해 최신 브라우저에서 기본 활성화가 되어있지 않다).

HTTP/2는 하나의 커넥션으로 여러 요청을 병렬 처리할 수 있다. 또한 헤더 부분까지 압축을 지원하며, 하나의 스트림이 자원을 독점하지 않게 만드는 흐름 제어와 클라이언트에서 다운로드 우선순위를 지정할 수 있게 하는 구조도 제공한다. 더 자세한 내용은 위키를 참고하자.

HTTP/3

HTTP/3는 아직 모던 브라우저에서 모두 지원되진 않으나, 지원을 위한 개발이 진행되고 있거나, 사파리의 경우 지원은 하나 개발자 메뉴에서 실험적 기능으로만 제공되고 있다. 현재 아직 초안인 것을 감안하면 표준이 되기 위한 순조로운 출발이라고 생각된다.

기존 프로토콜과의 차이점은 기본 전송을 매핑하는데 있다. HTTP/1.1HTTP/2는 모두 TCP를 전송으로 사용한다. 그에 반해 HTTP/3는 사용자 데이터그램 프로토콜(UDP)에 대한 사용자 공간 혼잡 제어를 사용하는 전송 계층 네트워크 프로토콜인 QUIC를 사용한다. QUIC 로의 전환은 "head-of-line blocking"이라는 HTTP/2의 주요 문제를 해결하는 것을 목표로 한다. 더 자세한 내용은 위키를 참고하자.

Last updated