본문 바로가기

Python

파이썬으로 웹 크롤러(Web Crawler) 만들기 (3)

본격적으로 파이썬을 이용하여 웹 크롤러를 개발해보도록 하겠습니다.


우선 PyCharm을 실행해서 프로젝트를 생성해줍니다. 프로젝트명은 WebCrawler로 하도록 하겠습니다. 프로젝트 생성후에는 프로젝트 내에 Python 파일을 생성해줍니다. 파일명도 동일하게 WebCrawler로 해줍니다.



이런 화면이 나온다면 개발을 위한 환경이 준비된 것입니다.


먼저 개발을 위해 사용할 라이브러리들을 import해주도록 하겠습니다. requests, bs4, pandas 세 개의 라이브러를 import 해줍니다. 만일 import에 실패했다면 정상적으로 설치가 안된 것입니다. PyCharm을 통해 설치가 가능하므로 설치가 안된 라이브러리는 설치해주시고 제대로 설치가 안되신다면 1번 글을 참고하셔서 마저 설치해주시기 바랍니다.


import requests
from bs4 import BeautifulSoup
import pandas


설치가 완료되었다면 크롤링을 실제로 작업해주는 crawling 함수를 정의하도록 하겠습니다. crawling 함수는 총 두개의 인자값을 사용할 것입니다. 하나는 검색어에 해당하는 code라는 인자이고, 다른 하나는 몇개 페이지를 탐색할지 결정하는 page_count 입니다. 두 개 인자를 이용해서 url을 만들어준 뒤 request를 날릴 것이므로 url을 만들어주는 것이 가장 처음해야할 작업입니다. 2번 글에서 말씀드린대로 Daum 뉴스에서 검색어를 통해 검색된 결과의 제목만 가져오는 웹 크롤러를 만들 것이기 때문에 앞의 글에서 얻을 url을 사용하겠습니다. url에 인자값을 넣기 편하도록 두 개로 쪼개주고 인자값을 포함시켜서 url을 완성시키도록 하겠습니다. 그리고 결과를 저장해줄 배열도 하나 선언하도록 하겠습니다. 배열은 result라는 이름으로 선언했습니다. 그 다음 페이지를 넘겨가면서 탐색할 수 있도록 for문을 이용하여 page_count 숫자만큼의 url이 선언되도록 코드를 작성합니다.


# 웹 크롤링 작업을 실행해주는 함수
def crawling(code, page_count):
    # url 조합
    front_url = "http://search.daum.net/search?w=news&nil_search=btn&DA=PGD&enc=utf8&cluster=y&cluster_page=1&q="
    back_url = "&p="

    # 결과를 저장해줄 result 배열 선언
    result = []
    # page_count까지 페이지를 넘겨가면서 탐색할 수 있도록 for문으로 반복
    for i in range(1, page_count + 1):
        url = front_url + code + back_url + str(i)
        # 실제로 구성된 url이 어떻게 나오는지 확인할 수 있도록 print
        print(url)


우리가 원하는 모양의 url이 정상적으로 출력된다면 이제 이 url을 이용하여 페이지의 결과를 받아와야합니다. 페이지 결과값을 받아오는 역할은 앞에서 말씀드린대로 requests 라이브러리가 해줄 것입니다. requests의 get함수에 url을 인자로해서 실행해주면 페이지 내용을 모두 가져오게됩니다. 하지만 여기에는 우리가 원하는 정보외에 쓸데없는 내용도 포함되어 있습니다. 원하는 정보만 정확히 가져오기 위해서 결과를 구조화할 필요가 있고 이때 BeautifulSoup이 사용됩니다. BeautifulSoup('request 결과', '구조화할 형식')의 형식으로 선언하게 되면, 구조화된 결과물이 return되게 되고 우리는 그중에서 원하는 태그와 class를 선택해서 정보를 추출해주면 됩니다. 저는 앞에서 말씀드린대로 a태그중 class가 f_link_b인 값들을 추출하도록 하겠습니다. 마지막으로 나온 결과값을 확인하고 결과값에 공백이 포함되어 있으면 제거해주도록 하겠습니다. 공백을 제거한 후에는 result 배열에다 append해줍니다. 모든 작업이 끝나면 결과를 result를 return 해줍니다.


        # requests 라이브러리의 get함수에 url을 인자값으로 하여 실행해주면 페이지 결과를 쉽게 가져올 수 있습니다.
        temp_result = requests.get(url)
        # 페이지 결과에서 우리가 원하는 결과만 손쉽게 가져올 수 있도록 BeautifulSoup을 이용하여 xml형태로 구조화해줍니다.
        print(temp_result.text)
        soup = BeautifulSoup(temp_result.text, "lxml")
        # 구조화된 결과에서 우리가 원하는 a태그, 그리고 그중에서 class가 f_link_b인 결과만 select로 가져옵니다.
        titles = soup.select('a.f_link_b')

        for j in range(len(titles)):
            # 결과가 잘 나오고 있는지 print 해봅니다.
            print(titles[j].text.strip())
            # 결과를 result 배열에 추가해줍니다.
            result.append(titles[j].text.strip())

    return result


이제 작동하는지 확인해보겠습니다. crawling함수를 실행해줄 main 함수를 정의해주고 마지막에 main 함수를 호출해주도록 합니다.


def main():
    # code 값과 page_count를 정해줍니다.
    code = "비트코인"
    page_count = 2

    # 위 두 변수를 인자로 하여 crawling를 실행합니다.
    result = crawling(code, page_count)
    # 결과를 출력합니다.
    print(result)

# main함수를 실행해줍니다.
main()


결과값은 아래와 같이 정상적으로 나오는 것을 확인하였습니다.



마지막으로 나온 결과를 엑셀이나 기타 다른 프로그램에서 사용할 수 있도록 csv 파일로 만들어주도록 하겠습니다. 배열로 나온 결과를 DataFrame구조로 전환해주면 파일 out이 굉장히 편해지는데 그 역할을 하는 것이 pandas 라이브러리입니다. pandas 라이브러리를 통해 구조화된 결과물을 편하게 변형, 가공할 수 있습니다. 코드 구현은 매우 간단합니다. crawling 함수에서 return된 result 배열을 pandas의 DataFrame함수에 넣어주기만 하면 됩니다. 그리고 데이터프레임에서 to_csv 함수를 사용하여 파일로 추출할 수 있습니다.


    # result를 pandas.DataFrame() 함수의 인자로 넣어줍니다.
    df = pandas.DataFrame(result)
    # df에서 to_csv 함수를 이용하여 쉽게 파일로 추출할 수 있습니다.
    # 파일명은 news_result.csv 로 하겠습니다.
    df.to_csv('news_result.csv')



news_result.csv라는 파일이 경로에 정상적으로 생성되었습니다.


웹 크롤러 기능 자체는 여기서 개발이 끝납니다. 비교적 짧고 간단한 코드로 쉽게 구현이 가능하니 웹 크롤러 개발이 필요한 경우 참고하여 개발해보시기 바랍니다. 다음글에서는 추가기능으로 크롤링된 결과를 메일로 발송해보겠습니다.