본문 바로가기

프로그래밍/python

스크래피 scrapy 이거 하나로 익숙해지기..1

반응형

스크래피 scrapy 이거 하나로 익숙해지기

 

-본 포스팅은 스크래피 공식 문서에 있는 튜토리얼을 다시 한국어로 정리한 포스팅입니다.
-pycharm 을 이용하여 진행합니다.
-이 튜토리얼 하나로 스크래피의 기본 사용 방법을 알 수가 있습니다.

 

quotes.toscrape.com 유명 작가들의 글귀가 담겨져 있는 사이트를 스크랩할려고 합니다.

 

이 튜토리얼의 진행순서입니다.

1.새로운 scrapy project 생성

2.spider를 작성하여 크롤링과 데이터 추출

3.command line을 이용하여 스크랩된 data 추출하기

4.작성된 spider를 재귀적으로 가져오도록 변형시키기

5.spider의 argument 이용하기

 

scrapy에 대한 기본적인 구조 및 정보를 알고 싶다면 아래의 이전포스트글을 확인하세요.


프로젝트 생성하기

 

1.먼저 pycharm의 새로운 프로젝트를 생성합니다.

 

 

 

2.File->Setttings.. 에서 scrapy와 pywin32 패키지를 프로젝트환경에 설치합니다.

 

File->Setttings.. 메뉴를 선택해서 Settings 창에서 +버튼을 누릅니다.

 

 

3.pycharm의 터미널창에서 scrapy 커맨드의 startproject 를 이용하여 프로젝트를 생성합니다.

 

 

다음과 같이 기본 구조의 프로젝트가 생성되었습니다.

tutorial/
    scrapy.cfg            # deploy configuration file

    tutorial/             # project's Python module, you'll import your code from here
        __init__.py

        items.py          # project items definition file

        middlewares.py    # project middlewares file

        pipelines.py      # project pipelines file

        settings.py       # project settings file

        spiders/          # a directory where you'll later put your spiders
            __init__.py

 

 


첫번째 스파이더 완성하기

 

이제 스파이더 클래스를 만들고 이를 이용해서  Scrapy가 웹사이트에서 정보들을 스크랩하도록 할것입니다.

스카이더 클래스는 Spider라는 클래스를 상속해야하고, initial request 를 만들어야합니다. 때에 따라서는 옵션적으로 페이지 안에서 어떻게 링크를 따라 갈것인지(재귀적으로) 그리고 어떻게 다운로드한 페이지 컨텐츠들을 이용해서 데이터를 추출할 것인지를 정의 해야할 것입니다.

 

아래의 코드는 첫번재 스파이더 코드이며

quotes_spider.py 라는 파일네임으로 tutorial/spiders 디렉토리 안에 두도록 합니다.

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"

    def start_requests(self):
        urls = [
            'http://quotes.toscrape.com/page/1/',
            'http://quotes.toscrape.com/page/2/',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        page = response.url.split("/")[-2]
        filename = f'quotes-{page}.html'
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log(f'Saved file {filename}')

보시다시피, 스파이더 클래스는 scrapy.Spider를 상속하고 있으며 어트리뷰트와 메소드등을 정의 하고 있습니다.

 

  • name : 스파이더를 정의합니다. scrapy 프로젝트 안에서는 무조건 유일해야하며 중복된 이름을 가진 스파이더가 존재하면 안됩니다.
  • start_requests() : 무조건 Requests의 iterable 형을(requests의 리스트나 generator 함수도 가능) 리턴시켜야 합니다. 그렇게 해야 스파이더는 데이터를 크롤할 수 있기 때문입니다.
  • parse() : requests 로부터 다운로드된 response 데이터들을 이용할 콜백 메쏘드 함수입니다. 여기서 response 파라미터는 TextResponse의 인스턴스로 TextResponse 는 페이지의 컨텐츠를 좀 더 활용하기 쉽게 만들어주는 기능을 담당합니다. 여기서 parse 메쏘는 보통 response를 파싱하거나 스크랩된 데이터를 dicts 형으로 추출시켜주며 또한 새로운 requests를 생성시킬 새로운 URL을 찾기도 합니다. 

 


스파이더 실행 시키기

tutorial 디렉토리로 이동 후 명령어를 실행합니다.

스파이더를 실행시키기 위해 프로젝트의 top level 디렉토리로 이동 후 명령어를 실행 합니다.

scrapy crawl quotes

이 커맨드는 quotes라는 이름의 스파이더를 실행 시키며 quotes.toscrape.com 도메인에 request를 send 합니다.

이제 아래와같은 결과가 나올 것입니다.

 

현재 디렉토리에서 파일을 체크해보면 두개의 quotes-1.html, quotes-2.html 이 생성된 것을 알 수가 있습니다.

 

 

Note: HTML을 아직 파싱이 안한 것 같지만 밑에서 다시 다루겠습니다.

자, 그렇다면 지금까지 스크래피는 무엇을 한것일까요?  다시 정리하자면, 스파이더의 start_requests 메쏘드에서 리턴된 오브젝트(scrapy.Request)들을 스케쥴링합니다. 각각의 request 에서 받은 response들을 Response 오브젝트로 인스턴스화 한 후 콜백 메쏘드를 호출 시킨 것이지요(parse method).

 


start_requests 메소드대시 간단하게 실행시켜보는 방법 

스파이더 클래스에 start_requests() 메소드를 정의하지 않고 간단하게 실행시킬 수 있습니다.

스파이더 클래스 안에 start_urls 리스트 어트리뷰트를 이용하면 됩니다.

 

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'http://quotes.toscrape.com/page/1/',
        'http://quotes.toscrape.com/page/2/',
    ]

    def parse(self, response):
        page = response.url.split("/")[-2]
        filename = f'quotes-{page}.html'
        with open(filename, 'wb') as f:
            f.write(response.body)

 

위의 코드와 같이 start_urls 기본 어트리뷰트에 있는 URL에 따라 parse 메소드가 호출되며 간단하게 실해을 할 수가 있습니다.

 

 

 

참고: docs.scrapy.org/en/latest/intro/tutorial.html

반응형