안녕하세요. 몇일동안 본업(?)에 매진하느라 소홀했던 튜토리얼을 다시 작성하려 합니다. 간혹 메일로 문의를 주시는 분이 계신데, (메일은 어떻게 아셨지 -_-a) 그냥 여기에 댓글을 다셔도 가능하면 답을 달아 드립니다. 긴급한(!) 일이 아니라면 메일은 삼가해 주셨으면 합니다^^;. 서두가 길었네요. 시작해 보겠습니다.
이번 시간에는 인터넷 상에 있는 자료(데이터: 글 + 이미지 + 파일 등등) 들을 파이썬을 이용해서 긁어오는 것을 하겠습니다. 우리가 잘 알고 있는 구글의 검색 시스템도 시시각각 인터넷상에 올라오는 글들을 크롤러(로봇)가 링크를 타고 타고해서 DB(데이터 베이스)에 잘 저장을 해 둔것을 사용자들이 찾는 시스템입니다. 여타 검색엔진과 다르게 구글이 크게 성장할 수 있었던 요인 중 하나는 사람의 손을 별로 타지 않은, 양질의 검색 결과를 보여주었기 때문입니다. (한국의 몇몇 검색 포털과는 다르게....). 이번에는 이렇게 크롤러(로봇)들이 웹을 돌아 스크랩(긁어오기)을 하는 것을 특정 사이트만을 크롤링 해 보도록 하겠습니다.
엉뚱한 사이트를 크롤링하는 것 보다 본 사이트의 글 제목과, 본문을 파이썬으로 가져오는 것을 구현해 보겠습니다. 이를 각 개개인이 원하는 형태로 응용을 하면 꽤(?) 유용한 자신만의 AP(Applications)을 만들어 사용하실 수 있을 겁니다.
1. Coding
웹의 언어는 HTML, CSS, JavaScript 등 웹언어를 기반으로 하고 있는데, 이를 사람이 보기 좋게 가독성을 높여줄 수 있는 모듈인 BeautifulSoup 를 불러오도록 합니다. ▼
어떤 특정 웹 페이지를 크롤할 수 있게 하는 함수를 정의 합니다. parameter는 최대 크롤할 페이지 수를 받습니다.▼
크롤링 할 첫 페이지를 1부터 하게 변수 page에 1을 저장합니다. 그리고 초기 입력해 줄 페이지가 최대 크롤할 페이지 보다 작을 동안 계속 크롤할 수 있게 while 반복문을 사용하였습니다.▼
그리고, 크롤할 사이트를 본 블로그로 하고 그 뒤에 페이지 번호를 합쳐 저장한 값을 변수 url 에 저장하도록 하였습니다.▼
타겟 url의 데이터를 파이썬으로 처리하기 위해 데이터를 불러오려고 하는데, 이 때 아래와 같이 requests.get(url)으로 데이터를 가져옵니다. 이렇게 받은 데이터를 source_code 라고 하는 임의의 변수에 저장하도록 하였습니다.▼
이렇게 저장된 source_code의 텍스트 부분만을 처리하여 plain_text에 저장을 하겠습니다.▼
그런데 이렇게 저장된 plain_text 는 아래 그림처럼 가독성이 엉망인 상태입니다.▼
위 그림처럼 무슨 내용이 있는지 잘 알수가 없는 데이터를 사람이 읽기 쉽게 해주는 파이썬 모듈이 초기에 불러온 BeautifulSoup 이라는 모듈입니다.
아래와 같이 가독성을 높여주기 위해 BeautifulSoup( 타겟, parser ) 를 처리하여 임의의 변수인 soup에 저장을 하도록 하였습니다.▼
그런데 위 그림에서 'lxml'이라고 하는 parser를 사용하였는데, 이는 파이썬 기본 내장 파서인 html.parser보다 처리속도가 월등히 빠르기 때문이다. 추후에 여러 parser의 장단점을 비교하는 글을 따로 올리도록 하겠습니다.
여기까지 결과를 터미널을 띄워서 따로 결과 확인을 해보도록 하겠습니다.▼
첫 번째 터미널 결과보다 훨씬 가독성이 좋은 html 코드가 되었네요.
위 그림에서 각 페이지에서 타이틀(제목)에 해당하는 HTML 태그가 h2 아래에 있는 a 태그안의 값이므로 아래와 같이 soup.select('h2 > a') 값으로 찾을 수 있습니다. ▼
보다 자세한 BeautifulSoup 사용법을 확인하시면 다양한 방법으로 데이터를 가져올 수 있습니다. ▼
이렇게 찾은 타이틀의 HTML 값에서 href 값을 추출하여 기본 URL 과 합쳐줍니다. 그런 후에 href 변수로 저장을 하였습니다.▼
그리고 타이틀(제목)을 변수 title 에 저장을 하게 아래 코드처럼 만들었습니다.▼
이제 확인을 위해 프린트 함수를 사용하여 여기까지 잘 진행이 되었는지 출력해봅니다.▼
위와 마찬가지로 터미널로 여기까지의 진행상황을 확인해 보았습니다. 결과값이 잘 나오고 있군요. 첫번째 페이지의 URL 값과 타이틀이 출력이 되었습니다.▼
이제 이렇게 처리된 사항에서 while 반복문이 무한반복이 되지 않게 하기 위해 page += 1 을 주었습니다. 이렇게 함으로 인해, 초기 페이지부터 지정한 특정 페이지 범위의 모든 타이틀과 URL 값을 출력하게 하였습니다.▼
함수를 만들었으니 이제 함수 호출 및 실행을 해봐야겠죠? 아래와 같이 함수를 호출하였습니다. 이렇게 하면 1페이지만 실행이 될 것입니다.▼
위 코드의 결과값입니다. 첫 페이지의 URL , 타이틀(제목)이 잘 출력이 되었습니다. ▼
초기 스크롤 할 페이지는 1로 그대로 두고, 9 페이지 까지 스크롤하게 max_pages 값을 변경하였습니다.▼
그 결과 아래 그림처럼 1~9페이지까지 URL, Title 이 잘 출력이 되었습니다.▼
2. Comments
위의 결과를 보다 효율적으로 사용하기 위해서는 다음시간에 다룰 본문 내용을 크롤링하게 하여 URL, TITLE, 본문내용, etc. 를 파일의 형태롤 저장을 해두면 보다 효율적이고 효과적인 데이터 활용이 될 것입니다.
이제는 2번째로 본문을 크롤링하러 가 보겠습니다. 아래 링크를 누르시면 됩니다.
[PYTHON 3] Tutorials 25. 웹 크롤러(like Google) 만들기 2 - How to build a web crawler