brunch

You can make anything
by writing

C.S.Lewis

by 아무나 Jul 25. 2019

Python - 10. 다시 웹 크롤러로

*Udacity - Intro to Computer Science 를 따라가고 있습니다.

https://classroom.udacity.com/courses/cs101



1. 다시 웹 크롤러로


지난번에는 url 하나에 있는 모든 하이퍼링크를 만드는 웹크롤러를 만들었다. (get_next_target(page) - 참고: https://brunch.co.kr/@writeraaa/135) 이제 그것을 이어가 보자.


이번에는 get_all_links 를 통해 모든 파이퍼링크된 url을 [리스트]로 만들고, 이 크롤링된 [리스트]를 다시 크롤링해오는 업그레이드된 크롤러를 만들 것이다. (이를 위해 우리가 여태까지 리스트와 loop에 대해 공부하였다.





2. 먼저 웹페이지에 있는 하이퍼링크 url을 뽑아 리스트에 담아보자


먼저 빈 리스트가 하나 필요하다


links = []


우리는 이제 여기다가 페이지에서 검색해온 링크들을 담을 것이다. 그리고 최종으로 우리가 리턴할 값은 여기다가 찾은 url을 차곡차곡 추가하는 것이다. 이 개념으로 우리는 코드를 짤 것이다.


return links.append(url)


자, 코딩의 시작과 끝이 정리되었다.






3. 본격적으로 크롤링해오자!


목표 - 크롤링한 페이지를 다시 크롤링하여 모든 웹페이지를 크롤링 해온다.


연습용 페이지는 다음과 같다.(https://udacity.github.io/cs101x/index.html / 연습용으로 만들어진 링크가 유한한 페이지이다. 실제 인터넷 페이지를 넣으면 전 세계 웹페이지를 다 연결해 올지도 모른다. 그리고 컴퓨터가 이 동작을 수행하는 동안 우리는 손가락만 빨고 있어야 한다.)

 

1) 이를 구현하기 위해 우리는 두 가지를 리스트를 만든다 

:크롤링할 페이지 / 크롤링된 페이지(tocrawl / crawled)


코드를 짜기 전에 글로 개념을 정리해보자면


tocrawl = []//크롤링할 페이지 리스트

crawled = [] //일단 빈 '크롤링 완료된 페이지'를 생성


while tocrawl 크롤링할 페이지가 있는 동안에는:

    tocrawl에서 페이지를 하나 뽑아서

    crawled 페이지로 그 페이지는 옮기고

    이 페이지 크롤링된 모든 페이지를 tocrawl에 넣는다.

return crawled //크롤링 완료된 페이지를 리턴



하지만 여기에 함정이 있다.

이 동작은 완벽하지 않다. 누군가가 자기 자신으로 돌아오는 1페이지->2페이지->1페이지->2페이지.... 같은 무한 루프 페이지를 만들어 놓았다면 위의 동작은 무한 반복될 것이다. 그렇기 때문에, crawled 페이지에 이미 그 페이지가 있는지(검색한 적이 있는 페이지 인지) 검사하는 단계가 추가로 필요하다. 






4. 그렇다면 차근차근 시작한다


def crawl_web(seed):

    tocrawl = [seed]

    crawled = []


요런 설정으로 한 번 시작해보자. 웹페이지를 크롤링할 것인데 시드가 되는 페이지는 그 서막이 될 페이지가 들어갈 것이다. 그리고 이제 크롤링할 예정인 리스트에 시드 페이지를 넣고 크롤링 완료된 리스트에는 아직 완료된 것이 없으니 초기값으로 빈 리스트[]를 넣어주자.





5. 리스트에서 하나를 뽑아서 크롤링한다


while tocrawl:    //tocrawl 리스트가 있다면

    page=tocrawl.pop()     //맨 뒤에 것 하나를 꺼내!


여기서 바로 팝을 사용한다. 리스트에 있는 마지막 걸 하나를 제거하면서 동시에 그것을 사용할 수 있다

이런 걸 Depth-first search 라고 한다. 꼭 효율적이지는 않지만 일단 이걸 사용해보자.





6. 무한 반복하는 크롤링을 막기 위해 체크를 추가 


def crawl_web(seed):

    tocrawl = [seed]

    crawled = []

    while tocrawl:

        page=tocrawl.pop() 

        if page not in crawled: // 만약 크롤링 된 적이 없다면 (이미 크롤링된 페이지 리스트에 있겠지) 

            crawled.append(page)

            union(tocrawl, get_all_links(get_page(page)))

    return crawled


자 바로 앞 포스팅에서 짜 놓은 union 코드(리스트 두 개를 결합하는 코드)를 가져와 새로 찾은 링크를 크롤링할 리스트에 예쁘게 추가해주고, 크롤링 한 페이지는 [크롤링된 페이지 리스트]에 추가해준다. 그리고 마지막으로 이 [크롤링된 페이지]를 뽑아오면 끝. 휴 애썼다.





7. 이 다음에는... 


웹 크롤링은 이제 그만, 우리는 이제 검색을 통해 웹페이지의 컨텐츠를 뽑아오는 것을 배워볼 것이다. 마치 검색엔진처럼! 이를 위해 우리는 쿼리를 통해 인덱스를 만드는 방법을 배워볼 것이다!


매거진의 이전글 Python - 9. loop의 변주
작품 선택
키워드 선택 0 / 3 0
댓글여부
afliean
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari