Back to Posts

파이썬 크롤링 튜토리얼 - 8 : Scrapy 사용법, 네이버 뉴스 크롤링해서 CSV로 내보내기

Posted in crawl

Scrapy 란?

최근 웹에는 수억개의 웹페이지가 있으며, 대부분의 페이지들은 수많은 정보를 가지고 있습니다. 최근 빅데이터가 대두되면서 이전에 작성되었던 페이지들의 정보를 모아 유의미한 정보를 도출하기 위한 여러가지 방법들이 논의되고 있고, 이를 Scraping(혹은 Crawling)이라고 합니다. Scrapy는 Scraping을 도와주기위한 파이썬 기반 라이브러리입니다. Scrapy를 이용하여 필요한 페이지로 접속하여 원하는 형태로 데이터를 가공하여 데이터를 저장할수 있도록 도와줍니다. (출처)

Scrapy 첫 코드 작성하기

설치하기

터미널에 아래 명령어를 입력해 Scrapy를 설치합니다.

pip install scrapy

Scrapy Shell 사용해보기

Scrapy Shell을 사용함으로써, 프로젝트를 생성하지 않고 간단하게 Scrapy를 체험할 수 있습니다. 아래 명령어를 입력해서 Shell을 실행시킵니다.

scrapy shell

네이버 뉴스 페이지를 크롤링하려고 합니다. Scrapy 크롤러는 starting point를 필요로 합니다. 말 그대로, 크롤링을 시작할 위치를 정하는 겁니다. 아래 명령어를 통해 Starting Point를 설정합시다.

fetch('http://news.naver.com/main/list.nhn?mode=LSD&mid=sec&sid1=001')

그럼, Response Code가 출력됩니다. image 이제 크롤러가 무엇을 다운로드했는지 확인해봅시다.

view(response)

이 명령어는 크롤러가 다운로드한 페이지를 기본 브라우저를 통해 실행합니다. image 경로를 보면 아시겠지만, 로컬에 저장이 됬습니다. 이제 소스를 확인해볼겁니다.

print(response.text)

다운로드 된, 웹 사이트의 소스가 출력됩니다. image 오늘 크롤링 할 것은 세 가지 입니다.

  • 제목
  • 올린 뉴스 사이트
  • 미리보기

제목

그러면 제목을 먼저 크롤링 해보겠습니다. 개발자 도구에 들어가서 제목 부분의 XPath를 복사합니다. 두번째 뉴스의 XPath와 맨 아랫줄에있는 뉴스의 XPath도 비교해봅니다.

  1. 첫번째 뉴스 : //*[@id=”main_content”]/div[2]/ul[1]/li[1]/dl/dt[2]/a
  2. 두번째 뉴스 : //*[@id=”main_content”]/div[2]/ul[1]/li[2]/dl/dt[2]/a
  3. 마지막 뉴스 : //*[@id=”main_content”]/div[2]/ul[2]/li[10]/dl/dt[2]/a

여기서 어떤 정보를 얻을 수 있을까요?

첫번째로는, 포스트는 li[1]~li[10]로 구성됬다는 것 입니다.
두번째로는, ul로 두 파트가 나뉜다는 것 입니다. 아래 사진 참고. image

결국 모든 포스트를 list에 저장하기 위해서는 태그[숫자]의 숫자 부분을 삭제해주면 됩니다.

//*[@id="main_content"]/div[2]/ul/li/dl/dt[2]/a/

XPath를 얻었으니 이제 크롤링을 해봅니다.

response.xpath('//*[@id="main_content"]/div[2]/ul/li/dl/dt[2]/a/text()').extract()

image 포스트 제목들이 출력됩니다. \n\t\r 이 지저분해 보이지만, 이 부분은 다음에 Project를 생성하고 CSV를 만들어 내보낼 때 제거하도록 합시다.

올린 뉴스 사이트

올린 뉴스 사이트는 CSS Selector를 통해 크롤링 했습니다.

response.css('.writing::text').extract()

뉴스 회사들이 출력되는게 보일겁니다.

미리보기

미리보기도 마찬가지로 CSS Selector를 통해 크롤링 했습니다.

response.css('.lede::text').extract()

계속 CSS Selector인 Class로 크롤링 하는 이유는 .writing이나 .lede같은 의미가 있는 Class들은 대체로 같은 요소에만 쓰입니다. 꼭 그런것만은 아니니 결과를 꼭 확인해 봐야 합니다. 확인해 봤을 때 같은 요소에서만 쓰인다면, 훨씬 간결하고 유연한 코드를 완성할 수 있습니다.

Spider 작성하기

기본적인 scrapy 프로젝트의 구조는 이렇습니다. 참고하고 프로젝트를 만들어봅시다. image

Hello Scrapy World!

아래 명령어를 통해 scrapy project를 생성해줍니다.

scrapy startproject naverscraper

그리고 프로젝트 안에 있는 spiders폴더에 들어갑니다.

Spider 생성하기

genspider 명령어를 통해서 newsbot을 생성합니다.

scrapy genspider newsbot news.naver.com/main/list.nhn?mode=LSD&mid=sec&sid1=001

생성된 newsbot.py 에 소스를 입력합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import scrapy

class NewsbotSpider(scrapy.Spider):
	name = 'newsbot'
	start_urls = ['http://news.naver.com/main/list.nhn?mode=LSD&mid=sec&sid1=001']

	def parse(self, response):
		titles = response.xpath('//*[@id="main_content"]/div[2]/ul/li/dl/dt[2]/a/text()').extract()
		authors = response.css('.writing::text').extract()
		previews = response.css('.lede::text').extract()

		for item in zip(titles, authors, previews):
			scraped_info = {
				'title' : item[0].strip(),
				'author' : item[1].strip(),
				'preview' : item[2].strip(),
			}
			yield scraped_info

8~10: 크롤링 한 데이터를 list로 저장
12: zip 함수는 아래 사진 참고
13: scraped_info 에 zip으로 slice 한 데이터들을 저장
14~16: strip 함수를 이용해 문자열에 필요없는 공백을 제거
image

Spider 실행하고 결과 확인하기

newsbot을 실행시켜봅니다.

scrapy crawl newsbot

image

CSV로 내보내기

프로젝트 폴더에있는 settings.py에 입력합니다:

FEED_FORMAT = "csv"
FEED_URI = "naver_news.csv"

그리고 다시 Spider을 실행합니다.

scrapy crawl newsbot

그럼 같은 디렉토리에 뉴스 내용들이 크롤링되어 csv에 저장됩니다. image

최종 소스 :
newsbot.py

import scrapy

class NewsbotSpider(scrapy.Spider):
	name = 'newsbot'
	start_urls = ['http://news.naver.com/main/list.nhn?mode=LSD&mid=sec&sid1=001']

	def parse(self, response):
		titles = response.xpath('//*[@id="main_content"]/div[2]/ul/li/dl/dt[2]/a/text()').extract()
		authors = response.css('.writing::text').extract()
		previews = response.css('.lede::text').extract()

		for item in zip(titles, authors, previews):
			scraped_info = {
				'title' : item[0].strip(),
				'author' : item[1].strip(),
				'preview' : item[2].strip(),
			}
			yield scraped_info

수고하셨습니다, 이것으로 scrapy의 기본적인 사용방법에 대해 알아봤습니다.

Read Next

웹 페이지에 맨 위로 이동하는 버튼을 만들어주는 라이브러리