본문 바로가기

개발/연구

[python3, 크롤링, deep web] http로 특정 사이트의 원하는 정보를 가져오기

※ 미리 말씀드리지만 모든 웹에 해당하는 방법이 아닙니다. 해당 웹을 잘 조회해보시고 대강 어떤 방식인지 파악 후 해보시길 권고드립니다.

 

특정 사이트의 특정 데이터를 조회하고 싶었기에 여러 시도를 하였습니다.

저는 우리 학교의 역대 강의 리스트를 조회하고 싶었고, 우리 학교의 Database의 권한도, API도 없기에 조회할 수 있는 방법은 학교 홈페이지를 통한 조회 뿐이었습니다.

그러다 문득, 사람이 볼 수 있는데 컴퓨터로도 이 정보를 빼올 수 있지 않을까 생각이 들었습니다.

그림[1]웹 사이트에서 본 강의 리스트

저에게 알 수 있는 것. 그리고 활용할 수 있는 것은 클라이언트의 정보(브라우저로 볼 수 있는 웹 구조와 코드)입니다.

 

그림[2]조회 할 강의를 설정하는 form

위의 입력을 통하여 그림 [1]의 결과를 가지고 오는 것을 보니, 어떤 구조인지 대강 예상이 가능합니다. 

"내가 그림[2]의 정보를 서버로 전송/요청하여 그림[1]의 정보를 가지고 와서 화면에 출력한다."

 

여기서 저는 이 데이터를 활용하려면 "내가" 일일히 정보를 가지고 와서 데이터화 시키는 방법도 있겠지만, 수 천개 이상의 데이터를 일일히 작업한다면, 시간 효율성이나 데이터 정확성이 떨어질 것입니다.

 

따라서 이 작업을 수행하는 주체를 "내가"가 아닌, "컴퓨터가"로 바꾸어 일을 수행시키고 싶었습니다.

 

그렇다면

1. 서버의 위치를 알아야 하고.

2. 서버에 요청하는 데이터 폼을 알아야 합니다.

 

위의 두 정보만 있다면 데이터를 가지고 올 수 있겠지요. 간단하게 크롬 브라우저에서 지원해주는 개발자 도구로 쉽게 알 수 있습니다.

 

개발자 도구 Network 탭

새로고침이 될 수 있으니 preserver를 켜놓고(네트워크 탭을 갱신시키지 않고 누적시킴) 조회를 해봅니다.

그리고 해당 페이지에서 데이터를 불러오는 이벤트를 작동시키고(예를 들면, 입력/조회를 클릭하고 데이터가 출력되는 방식이라면 "클릭"이 되겠지요) 이 웹 페이지에서 어떠한 통신과정이 있었는지 확인합니다.

 

위에서는 모든 png 파일을 제외한 .do라는 의심되는 코드 확장자가 있네요.

 

그림[3] 응답 데이터 확인

내용을 확인해보니 제가 얻고 싶은 정보인 "강의"와 관련된 내용이 틀림 없는 것 같습니다.

서버에 어떤 요청을 보냈는지 확인해봅니다. 예를 들어, "2018년1학기 메카트로닉스과의 정보를 알고 싶다." 라면, 2018, 1, 메카트로닉스과(또는 과의 코드명)이 있겠지요. 또한 어떠한 방식으로 보낼 것인지도 필요할 것입니다(위의 경우 application/xml 방식으로 보냈군요.)

로그인이 필요하다면 세션에 담겨있는 쿠키의 내용 또한 요청 데이터에 포함이 되어있을 것입니다.

가장 간단한 방법은 쿠키 내용 그대로 전송해주면 됩니다.

 

이제 어디에 보낼지(위치), 어떤 것을 보낼지(요청 데이터), 어떤 방식으로 보낼지(데이터 전송 방식)를 모두 알았으니, 컴퓨터에 그대로 시켜주기만 하면 됩니다.

크롤링을 지원하는 언어는 많지만, 제 기준 가장 간단하면서 가벼운 파이썬으로 예시를 들겠습니다.

# 데이터 전송
cookie = "쿠키 내용을 그대로 넣어줍니다 !"
# cookie
url = "서버의 ip 또는 dns"
# url
data = '페이로드 데이터'
# payload
headers = {'Content-Type' : 'text/xml',
          'Cookie' : cookie
          }
데이터를 전송할 방식
# headers / cookie

responseText = (requests.post(url, headers=headers, data=data)).text

 

위와 같은 설정을 마치고 http로 전송하여 얻은 정보를 response에 대입하여 확인해봅시다.

 

활용하기 좋게 하기 위해서 정규표현식으로 다듬은 텍스트 데이터입니다.

받은 데이터를 확인해보니 데이터를 알맞게 요청하였네요.

 

다듬지 않았다면 그림[3]과 같은 데이터가 그대로 출력됩니다.

 

git : https://github.com/kiJu2/python-crawling-by-http/blob/master/crawling.py