About Scrapy

 

Scrapy at a glance

  • 보기 힘들어서 만드는 Scrapy 개발 일지

What is Scrapy

  1. Scrapy는 웹 사이트를 크롤링하고 구조화 된 데이터를 추출하기 위한 프레임워크이다.
  2. 데이터 마이닝, 정보 처리 또는 기록 보관과 같은 광범위한 유용한 애플리케이션에 사용될 수 있다.

Walk-through of an example spider

  1. Scrapy는 Spider라는 Class를 통해 특정 사이트를 추출하는 방법을 정의한다.
  2. 다음은 http://quotes.toscrape.com 에서 인용문을 긁어내는 스파이더에 대한 코드이다.
  import scrapy
  
  class QuotesSpider(scrapy.Spider):
  	name = 'quotes'
  	start_urls = [
  		'http://quotes.toscrape.com/tag/humor/',
  	]
  	
      def parse(self, response):
  		for quote in response.css('div.quote'):
  		    yield {
      			'author': quote.xpath('span/small/text()').get(),
  		    	'text': quote.css('span.text::text').get(),
  		    }
  
  		next_page = response.css('li.next a::attr("href")').get()
  		if next_page is not None:
  			yield response.follow(next_page, self.parse)

Components Scrapy는 아래와 같은 component들로 구성되어 있다.

Scrapy Engine 각 component들에 데이터(Request, Response, Item)를 전달(Controller)하고 액션이 발생 했을 때 이벤트를 발생시키는 역활을 함.

Scheduler 엔진으로 부터 Request을 전달 받고 이 Request을 queue에 추가한 후 나중에 엔진이 Request를 요청할 때 다시 엔진에 전달.

Downloader Request에 포함된 URL에서 웹 페이지를 가져와서 Response 오브젝트를 만들어 엔진에게 전달하는 역활을 한다. 엔진은 전달 받은 이 웹 페이지를 다시 스파이더에게 전달.

Spider 요청할 URL을 사용하여 Request 오브젝트를 만들고, callback 메서드를 사용하여 Response에서 원하는 데이터를 추출하거나 Response에 포함된 URL을 사용하여 새로운 Request를 만드는 역활을 함.

Item Pipeline 스파이더로 부터 추출된 아이템을 처리하는 역활을 함(정확히는 Item 오브젝트가 전달됨). 일반적으로 아이템을 cleansing, 검증 그리고 데이터베이스 같은 곳에 저장하는 일을 함.

Downloader middleware 엔진과 다운로더 사이에 위치한 hook으로 엔진으로 부터 다운로더로 전달되는 Request를 처리하고, 다운로더로 부터 엔진으로 전달 되는 Response를 처리. 아래와 같은 것이 필요할 경우 다운로더 미들웨어를 사용한다. Request가 다운로더로 전달되기 전에 처리하기 위해. 예를 들어 웹사이트로 request를 보내기 전에 문제가 없는지 확인하기 위해. Response를 스파이더로 전달되기 전에 변경하기 위해. Response를 스파이더로 전달하는 대신 새로운 Request를 요청하기 위해. 웹 페이지를 가져오지 않고 스파이더에 Response를 전달하기 위해. 몇몇 Request를 drop하기 위해.

Spider middleware 엔진과 스파이더 사이에 위치한 hook으로 스파이더의 input(Reponse)와 output(아이템과 Request)를 처리할 수 있다. 아래와 같은 경우가 필요할 때 사용 스파이더 콜백의 아웃풋인 Request와 아이템를 변경하거나 추가, 삭제. start_requests의 후처리

스파이터의 예외 처리 Response을 기반으로 Request들 중 일부에 callback을 호출하는 대신 errback를 호출(예를들어 response가 정상(200)이 아닌 경우 callback을 호출하지 않고 errback를 호출하여 처리)