Mean Stack 으로 만드는 만화 사이트 #9

하하하하하하하하하하하하하하……

git commit 9-1까지 썻는데 지워졌네요 하하….

워드프레스 자동저장은 슬슬 믿을 수가 없네요…. 하….

다시 처음 부터 쓰고 싶은데 기억이 안나요.

적당히 기억나는 것만 쓰겠습니다. 혹시 이상한 점이 있으면 말씀해주세요.


일단 우리는 marumaru.in이라는 사이트를 크롤링 하고 싶습니다.  이 만화사이트는 목록은 marumaru.in 이라는 사이트에 실제 만화를 보는 창은 http://www.mangaumaru.com/ 에 있습니다. 그런데 이 mangaumaru.com 이라는 사이트는 noscript 태그가 들어있습니다.  noscript태그란 javascript가 실행되지 않는 사이트에서는 다른 화면을 표시하는 태그입니다. 예를들어 어떠한 사이트가 자바스크립트에 의해 동적으로 만들어 지는 사이트라고 가정합시다(우리 사이트도 단순 html은 사이트가 없고 대부분 angular.js로 인해 만들어 지는 사이트 이지요) 이런사이트에 javascipt를 활성화하지 않는 유저가 들어올 경우 정상적이지 않은 사이트를 표시하게 됩니다. 그럴경우에 대비하여 noscript태그를 만들어서 다른 화면을 표시하게 하는 것이지요. (자세한 설명은 검색) . 이러한 사이트를 일반적인 request 요청을 하게 된다면 서버는 request요청은 javascript를 실행시킬수 없는 환경이기때문에 noscript태그가 있는 html을 보여줍니다.

스크린샷 2015-12-12 오전 2.43.40

이런식으로 말이죠.  이 html에서는 우리가 원하는 정보를 가져 올 수 없습니다. 우리는 결국 이 사이트를 scrap하기 위해서는 특별한 방법을 써야 합니다. 여러가지 방법이 있지만 2가지 방법이 가장 많을텐데요.

  1. 실제 웹브라우져를 구동하여 정보를 가져온다.
  2. 프록시를 구동하여 정보를 가져온다.

1은 실제로 웹브라우저를 구동하는 방법입니다(selenium등이 여기에 해당하죠) 그리고 2는 프록시를 구현하여 다른 컴퓨터에서 서버에 요청한뒤(javascript가 실행될수 있는 환경) 그걸 가지고 오는 방법입니다. 2는 야후등에서 실제로 서비스를 하고 있습니다. 하지만 2보다는 1의 방법이 더 간단하기 때문에 1의 방법을 사용하겠습니다. 하지만 1의 방법에서도 실제로 웹브라우저를 전부다 구동하는건 자원상으로  큰 문제입니다. 우리는 단순하게 자바스크립트만 구동될 정도의 웹브라우저면 되지만 실제 웹브라우저는 그보다 훨씬 많은 기능을 제공 하기 때문이죠. 그래서 우리는 phantomJS라는 것을 이용하기로 합니다. phantomJS는

PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast andnative support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.

이라고 설명되어 있습니다. 여기서 headless는 화면이 없는것을 뜻합니다. 이 phantomJS을 통해 우리는 우리가 원하는 정보를 가져 올 수 있습니다.

스크린샷 2015-12-12 오전 3.03.26

이 파일은 testDirectory의 phantomtest 입니다. phantomJS는 생각보다 별로 쓸일도 없고 중요하지 않기 때문에 지금은 전부다 구현할려고는 하지 마시고 읽으면서 이렇구나 정도로만 넘어 가면 됩니다. 아무튼 이걸 실행하면 우리가 원하는 이미지 배열들만을 가져 올수 있습니다. 이제 이걸 통해서 실제로 만화를 저장해 보겠습니다. 여기까지가 git commit ‘9-1’입니다.


 

이제 저 코드를 가지고 적당히 PostSave_Maru를 만들어 주고 실행을 해 봅시다.

그러면

에러가 파바바바바박. 일어납니다. 뭐가 문제 일까요? 이유는 너무 많은 웹브라우저를 구동하였기 때문입니다. 아무리 phantomJS가 가볍다고 해도 50개가 넘는 만화를 한번에 저장하려고 한다면 50개의 phantomJS가 실행되고 문제가 일어나게 되지요. 그렇기 때문에 우리는 좀 더 다르게 해야합니다.

문제 해결을 위해 어떻게 하면 좋을지를 생각 합시다.

  1. 문제가 무엇인가? phantom이 너무 많이 실행된다.
  2. 왜 그런 문제가 발생하는가? node가 비동기 이기 때문에 모든 요청을 보내고 나중에 결과값을 받기 때문에.
  3. 어디서 문제가 발생한다고 생각하는가? for문으로 phantom이 들어있는 postsave_maru를 실행할때
  4. 어떻게 해결 할 수 있을 것으로 생각하는가? phantom을 1개씩 실행하는 동기식방식으로 1개 불러오고 1개 저장하고 다시 1개 불러오고 1개 저장하는 방법으로
  5. 어떻게 그런 방법을 비동기에서 구현할수 있나? 비동기의 동기식방법인 콜백과 for문을 재귀로 바꾼다면 할 수 있을 것으로 생각됨.

그러면 일단 재귀 함수로 적당히 틀을 잡아보자

스크린샷 2015-12-13 오후 6.43.18

이렇게 하고 saveFuntion을 적당히 하면 될듯하다. 한번 해보자.

몬가 넘겨주는 인자가 많아진것 같지만 맞다. 생각보다 필요한 인자가 많았다.

스크린샷 2015-12-13 오후 7.03.17.png스크린샷 2015-12-13 오후 7.03.26.png

분명 이런생각을 할 수 있다. (어? 그러면 그 전에 했던것도 그냥 이런식으로 하면 되는거 아니야? 왜 귀찮게 index를 주니 마니 했던거야?  맞다. 전에도 이런식으로 재귀를 만들어서 할 수 있다. 하지만 이 방법은 좋은 방법이 아니다. 실제로 나중에 node를 쓰다보면 비동기식의 잇점을 살리는 경우가 훨씬 많다. 그냥 간단하게만 생각해도 이 방법이 시간이 훨씬 오래 걸린다. 그전에는 1개일때와 2개 일때 3개일때 시간차이가 크게 나지는 않지만 이 방법은 n개 일때는 n배의 시간 또는 더 걸리기 때문이다. 되도록이면 이러한 방법은 안쓰는 편이 좋은것 같다. 물론 주관적인 견해이다)

스크린샷 2015-12-13 오후 7.09.12.png

아무튼 우리는 이렇게 하여 결국 3번째 만화사이트까지 전부다 저장이 가능하도록 만들었다.  그러면 이제 다시 frontEnd로 돌아가서 maru사이트에 대한 만화리스트와 뷰를 만든다면 거의 모든 작업이 끝난것이다. #10에서는 프론트를 만들고 그외 작업들을 해보자.

Advertisements

One Comment Add yours

  1. 김세준 댓글:

    urlToJsonList_Zang.js 제발 이 코드좀보고싶어요 ㅠ

    좋아요

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

w

%s에 연결하는 중