프날 오토핫키 강좌

[프날 오토핫키] WinHTTP #4: 동적 크롤링 (POST)

728x90

동적 크롤링에 대한 개념은 2강에서 설명 드렸습니다. 이러한 동적 크롤링을 하는 방법에는 몇 가지가 있지만, 주로 "Selenium"과 "WinHTTP POST" 방식을 이용합니다. 우리는 WinHTTP 강좌이기 때문에 WinHTTP POST 방식을 이용하여 동적 크롤링을 해보겠습니다.


 이번 강에서 쓸 웹사이트 

동적 크롤링의 묘미는, 뭐니뭐니 해도 "로그인" 해야 볼 수 있는 정보를 크롤링 하는 것이지요. 예를 들면 특정 웹사이트의 "내 정보" 탭을 크롤링 하는 것 말입니다!

"내 정보" 탭은 로그인 해야만 접근이 되겠지요.

저는 "방개 스페이스" 라는 커뮤니티 사이트의 내용을 크롤링 할 것입니다. 제 사이트거든요. 한달에 16,500원씩 호스팅 비용을 내며 운영하고 있는 사이트인데, 강좌할 때라도 써먹어야죠. 여러분도 이 사이트를 대상으로 연습하셔도 됩니다. 다만 서버에 무리가 가도록 너무 많이 크롤링을 하지는 말아주세요. IP 차단으로 끝날 수도 있지만, 일단 제 돈 주고 운영하는 사이트이기 때문이기 때문에 ㅎㅎ;

진짜 차단할 수 있습니다 ㅡ.,ㅡ

실제 운영하고 있는 사이트이니, 살살 다뤄주시라는 이야기입니다. 제 서버도 아니에요 심지어... 호스팅으로 공간 조금 빌린거입니다 ㅠㅠ

 


 우리가 크롤링하고자 하는 것 

저는 "방개 스페이스"의 "회원 정보"에 있는 "가입일"을 가져오는 일을 해보도록 하겠습니다.

가입일

우선 필요한 건 "회원 정보"의 주소일것입니다. "회원 정보" 주소는 아래와 같이 나오네요. 로그인 후 마이 페이지를 들어가보시면 아래와 같은 주소가 웹브라우저의 주소 표시줄에 노출될것입니다.

한번, WinHTTP를 통해 "정적 크롤링"으로 해당 주소를 크롤링 해보시길 바랍니다.

지난 강에서 배운 정적 크롤링을 이용하면...
크롤링이 되지 않습니다!

크롤링이 되지 않는 이유는 짐작 가실겁니다. 로그인을 하지 않았기 때문에, "회원 정보"에 접근할 권한이 없는 것입니다. 우리가 웹 브라우저에서 로그인을 했어도, 오토핫키 소스에서 새로 통신하는 그 부분은 비로그인 상태인 것입니다.

 

그러면 로그인을 해주어야겠죠. 따라서, 우리가 이번 강에서 해볼것은 아래와 같습니다.

  1. "방개 스페이스"에 로그인
  2. 크롤링!

로그인 또한 WinHTTP로 가능합니다. 특정 COM객체를 가지고 로그인을 해두면, 이 객체로 크롤링을 할 땐 로그인 된 세션이 유지된 상태에서 크롤링을 할 수 있습니다.


 로그인 후 크롤링 하기 

1. COM객체 생성

WinHTTP를 이용하여 로그인 과정을 진행해봅시다. 우선 저번에 해본대로, WinHTTP를 이용하기 위해 COM객체를 하나 만들어둡시다

좋습니다. comObj라는 이름의 COM객체가 만들어졌습니다.

 

2. 통신 방식과, 대상 URL 설정하기

저번에 했었죠? 지난 강의에선 GET 방식으로 https://pnal.kr의 소스코드를 읽어왔죠. 이번엔 좀 다릅니다. 우선, "통신 방식"은  POST를 이용할 것입니다. 그리고 "대상 URL"은 당연히 로그인 대상 페이지겠지요. 그런데, 로그인 페이지가 어디일까요?

 

이럴 때 필요한 것이 2강에서 받아둔 "피들러"입니다. 피들러를 실행해주세요.

 

우선 피들러 설정을 해봅시다. 요즘 웹사이트들은 HTTPS 프로토콜이 기본적으로 장착(?) 되어있는 경우가 많기 때문에, 이에 따른 조치를 해주어야합니다. HTTPS는 암호화 통신이기 때문에, 일반적인 방법으론 분석할 수 없기 때문입니다.

 

피들러 상단 메뉴에 Tools > Options > HTTPS 에 들어가면 아래와 같은 창이 열립니다.

빨간 네모를 쳐 둔 Decrypt HTTPS traffic체크해준 후, 화면 상의 지시를 따릅니다.

그 뒤에 OK 버튼을 눌러서 나와줍니다.

 

이제 POST 통신을 위한 URL을 가져와봅시다.

위 사진과 같은 좌측에 있는 목록은 통신 목록입니다. 일단 방개 스페이스 로그인 화면까지 간 다음에, 이 목록을 전부 삭제해주세요.

 

즉, 아래 사진처럼 대기를 하고 있으면 됩니다.

왼쪽은 방개 로그인 직전의 화면, 오른쪽은 비워진 피들러 화면입니다.

 

그 뒤에 로그인 버튼을 누르면 아래와 같이 로그인 과정 중 발생하는 통신 목록이 나오게 됩니다.

전 4가지의 통신 목록이 뜨는데요, 필요한 정보가 이렇게 수집되었으면 일단 피들러 하단의 Capturing 버튼을 눌러서 피들러가 다른 통신 내역을 가져오는 것을 중지해줍시다. 다른 통신 목록이 들어오면 헷갈리거든요.

 

우리는 저 4가지의 통신 내역 중 "POST"방식의 통신만 필요합니다. 우리는 이 POST 방식을 모방하여 오토핫키 코드를 짤 것이기 때문입니다. 아래 이미지가 POST 방식을 뜻하는 이미지입니다.

 

해당 아이콘이 있는 줄을 눌러서 선택한다음, 피들러 우측에 Inspectors > Raw를 클릭해서 이 트래픽의 통신기록을 봐줍시다.

요 상태일겁니다.

복잡합니다. 우측의 하늘색 영역이 세부 통신 내용인데요, 우리가 하는 일이 "통신 방식"과, "대상 URL"을 설정해주는 일이라고 하였지요.

 

위 사진이 Raw창입니다. (전체가 한 눈에 들어오도록 크기를 조정했습니다.)

맨 위에 POST 라는 글씨가 방식, 그 뒤에가 대상 URL입니다. 방개는 로그인을 메인 페이지 주소에서도 처리할 수 있군요. 그래서 우리는 아래와 같이 코드를 짜주면 되겠지요.

comObj.Open("POST", "https://banggae.space")

정적 크롤링을 할 때와 비슷한 형태이지요? POST라는 글씨가 GET으로만 바뀌면 정적 크롤링을 할 때와 동일합니다.

 

 

3. 로그인 데이터 보내기

POST는 어떤 정보를 웹사이트로 보내는 통신 방식입니다. GET 을 이용한 정적 크롤링과 동일하게 Send() 함수를 이용해 줄 것인데, 이 때 빈 값을 넣었던 GET 방식과 달리 "서버로 전달할 값"이 Send()의 매개변수로 들어가야합니다.

 

전달해 줄 값은 아래 Raw 창에서 맨 마지막 줄, 그러니까 표시해둔 이 줄입니다.

저 줄이 POST를 통해 넘어가는 값이구요, 가려준 부분엔 아마 로그인에 성공한 본인의 아이디와 비밀번호가 있을 것입니다. 그러니까, 우리가 웹 상에서 로그인 버튼을 누르는 순간 저 데이터가 전송된다는 뜻입니다.

 

아래와 같이 (이전에도 사용했던) Send()구문을 이용해주어서 저 줄 전체를 넘겨주시면 됩니다.

comObj.Send("전달해 줄 값")

 

 

4. 웹페이지 크롤링하기

이렇게 로그인 된 COM객체를 이용하여 다시 GET 방식으로 크롤링을 하면, 로그인이 된 상태에서 크롤링이 됩니다. "회원 정보" 화면을 볼 수 있는 것이지요.

2~3번째 줄에서 로그인을 하고, 5~6번째 줄에서 크롤링을 합니다.

그런데, 이렇게만 하면 아마 정상적으로 로그인이 되지 않았을 것입니다. "회원 정보"의 소스를 얻어온다 해도, 여전히 접근 권한이 없다는 403 Error만 출력될 것입니다. 로그인이 되지 않은 상황을 의심해 볼 수 있겠지요.

 

 

5. 헤더 설정하기

왜냐하면, 우리가 보낸 POST 방식의 데이터엔 그냥 "보낼 값"만 있기 때문입니다. 우리가 누구인지 신원을 명확하게 밝혀줘야, 서버는 접근을 허용하게 됩니다. 이러한 "신원을 검증하는 요소"로 자주 쓰이는 게 Header인데요, 이 역시 아까 본 Raw 창에 나와있습니다.

빨간 테두리로 친 부분이 헤더인데, Connection부터 해서 Cookie까지 있는 것을 알 수 있습니다. 이 모든게 제 신원을 증명해주는 것이지요.

서버마다 어떤 요소를 이용하여 검증을 할지 다르지만, 방개는 저 헤더 중에서 Content-type과 Referer, User-agent 정도만 이용하여 검증합니다. 

 

WinHTTP에선 이 "헤더"를 설정할 수 있습니다. POST 값을 보내기 전에 헤더를 설정해준 후 값을 보내야 "정상적인 접근"으로 인식하게 됩니다.

 

Raw 창에 적힌 헤더 중 Referer, Content-type, user-agent 헤더만 찾은 후, 아래와 같은 형식으로 적어줍니다.

comObj.SetRequestHeader("헤더명", "헤더 내용")

저는 이렇게 적어주었습니다. Raw창에 다 나와있는 내용입니다. Raw창에 Referer: https://bangae.space이런식으로 적혀있으면, SetRequsetHeader에는 "Referer", "https://banggae.space"처럼 적어주면 되는 것이지요.

 

그 후에 POST 내용을 Send() 시켜주면 정상적인 접근으로 인식되어서, 올바르게 로그인 과정이 되는 걸 볼 수 있습니다.

 

위 사진에서 POST 방식으로 대상 URL이랑 통신하겠다고 설정해주었고 (3번째 줄)

정상적인 접근으로 보이기 위해 헤더를 설정해주었습니다. (4~6번째 줄)

그리고 로그인 아이디와 비밀번호가 담긴 부분을 Send 해주었습니다. (7번째 줄)

로그인이 된 후, "마이페이지" 주소의 소스를 읽어옵니다. (9~10번째 줄)


 파싱은 자유롭게 하시면 됩니다. 

우리의 목표가 기억나는지 모르겠습니다. 우리는 "회원 정보"의 "가입일"을 가져오려고 합니다.

크롤링된 소스코드에서 "가입일" 부분을 파악하여, 요령껏 정규식이나 기타 파싱 구문을 사용해주세요.

소스코드를 가공하는 "파싱"은 본인의 몫입니다.

저는 정규식을 이용해보았습니다.

너무 난이도가 갑자기 올라갔지요. 자세한 내용을 설명드리기엔 사실 너무 어려운 작업이긴 합니다. 

그렇지만 쓰다 보면 느는건 맞습니다.

 

예제.ahk
0.00MB

 

다음 강에서는 지금까지의 내용을 간단하게 정리해보도록 하겠습니다.

 

 

 

반응형