파일[데이터] 크롤링시 사소한 팁들 (feat.삽질기)

저는 2019년 DEFCON DEMO LABS에서 안드로이드 앱의 클라우드 백엔드 취약점 분석도구 soFrida를
발표한 바 있습니다.  [링크 바로가기]

발표를 준비하면서 취약점을 증명하기 위해 구글 플레이스토어 160개국에서 가장 인기있는
앱들을 선별하였고, 설치파일(APK)을 수집하여 분석을 수행하였습니다.
물론 대부분의 과정들은 파이썬을 통해 자동화를 시켰으나, 분석에는 엄청난 노가다가 수반되었습니다.
이 부분에 대해서는 나중에 따로 글을 써 볼까 합니다.

[ 함께해서 더러웠고 다시는 만나지 말자? ]

오늘은 파일 또는 데이터를 크롤링할때의 사소한 팁에 대해서 몇가지 소개해볼까 합니다.
제목은 팁이라고 적었지만 사실은 여러번의 삽질끝에 깨달은 “실수방지 팁”에 가깝습니다.

데이터를 좀 수집해보신 분이라면 아니 저런 말도 안되는 실수를 했다고? 라고 생각할 수 있으나
저는 전문적인 개발자도 아니었고, 취약점 분석에만 눈이 먼(?) 나머지
데이터 수집은 대충 빨리-많이하고 보자식으로 하다가 추후에 혹독한 댓가를 치뤘습니다 ㅠㅠ

그럼 지금부터 간단한 팁들에 대해 소개를 시작합니다.

 

[Tip 0x01] 한번에 모든 데이터를 한번에 받는다는 생각을 버리자.

하나의 크롤링 코드를 통해 데이터를 수집하는 것이 일반적인 방법이긴 합니다.
그러나 전체 데이터를 에러없이 한번에 받는것은 굉장히 어렵습니다.

저의 경우 수집해야 할 앱의 갯수가 약 50만개 정도였는데
처음에는 파이썬을 이용해 단순히 루프를 돌면서 받으면 되겠지 하는 안일한 생각으로 코드를 짰습니다.

그러나, 중간에 알수 없는 에러들과 코드상의 버그로 인해
몇번을 코드를 뒤집고 새로 짜야 했습니다.

따라서 대량의 데이터를 수집할 때는
100개 –> 1000개 —> 10000개 이런식으로 수집 데이터 수량을 조금씩 늘려가면서
테스트를 하기를 권장합니다.

이를 통해 Loop상에서 발생할 수 있는 여러 에러들을 수정할 수 있을 것입니다.

 

[Tip 0x02] 수집하는 데이터에 대한 Status 기록을 확실하게 남겨라.

처음에 이걸 안했다가 나중에 몇번을 프로젝트를 갈아 엎어야 했습니다.
예를 들어 다운로드 하는 앱의 국가가 US(미국), 다운로드 받는 앱의 카테고리가 GAME이라고 가정하고
그 안에 있는 앱의 목록이 200개 정도 있다고 가정합시다.

저의 경우 160개국의 60개 카테고리에 있는 앱을 수집했는데
처음에 아무 생각도 없이 그냥 Uniq한 앱만 수집하면 된다는 생각에
국가와 카테고리를 구분하지 않고 그냥 마구잡이로 수집을 했습니다.

나중에 다운로드 되지 않은 앱이 있다는 것을 깨닫고
에러를 추적하려 했으나, 어떤 국가의 어떤 카테고리에서 에러가 난건지 추적이 안되서
결국엔 로그 모듈을 새로 개발하고 다시 첨부터 다운로드를 시작했습니다. ㅠㅠ

따라서 데이터를 수집할 때는
반드시 현재 수집하는 데이터가 몇번째 데이터인지, 그리고 파라미터들이 어떤것인지를
별도의 로그 모듈을 통해 기록하시기를 권장합니다.

제대로된 기록만이 수집된 데이터의 정확성을 보증할 수 있습니다.

 

[Tip 0x03] Abuse Detection을 고려하자.

이 부분도 처음엔 정말 생각지도 못했던 것인데요.
구글 플레이스토어에서 파일을 40만개 정도 받고 난 후, 아 이제 노가다는 끝났구나 생각했습니다.

그런데 제 스마트폰의 안드로이드 앱 업데이트가 안된다는 사실을 알게 되었습니다.
분명히 업데이트 할 앱 목록은 20개가 있는데 업데이트 버튼을 아무리 눌러도
업데이트가 안되고 에러가 나는 현상이 발생했습니다.

구글링을 통해 별 짓을 다 해봤으나 결국에 이 문제는 아직도 해결하지 못했고,
저는 안드로이드 앱 업데이틑 서브 계정을 통해서만 가능한 상태입니다 ㅠㅠ

만약 저처럼 대용량의 파일을 수집해야 할 경우라면
반드시 서브 계정이나 임시 계정을 사용해서 수집하시기 바랍니다.

또한 단시간 내에 여러번 자료를 요청하거나 할 경우
서버측에서 Abuse Detection에 걸릴 수 있으므로, 랜덤한 시간동안 Time Sleep을 준다거나
Single Thread로만 작업을 하는 것도 하나의 방법입니다.
(이 부분은 서버측의 상태에 따라 대응하시면 됩니다)

 

[Tip 0x04] 수집하지 못한 데이터에 대한 기록을 남기자

팁 0x02와 유사한 부분이긴 합니다만, 수집하지 못한 데이터가 있다면
왜 수집하지 못했는지 반드시 Exception 원인을 기록해 놓아야 합니다.

특히 논문을 작성할때는 표현을 조심해야 하는데,
“받지 못한 데이터가 있음에도 불구하고 [전체] 데이터를 수집했다”는 표현을 해서는 안되겠죠.

따라서 데이터 수집상에 있었던 Exception 케이스에 대해
논문 내용중 별도로 언급을 해주는 것이 좋습니다.

해당 논문에 대한 내용은 “수집된 데이터”를 기반으로 하는 것이며
Exception 케이스에 대해서는 추후 보완하거나 한계점으로 남겨두는것이 좋겠습니다.

 

대용량 데이터를 수집하는 방법은 환경에 따라 많은 차이가 있을 것으로 생각됩니다.
제가 언급한 팁들을 일반화 하기는 힘들겠지만,
크롤링 스크립트를 작성하거나 수집된 데이터를 분류할 때 약간의 도움이 될 것이라 생각합니다.

그럼 The End

Site Footer