본문 바로가기
Back-end/Python

[크롤링] 무작정 시작하기 (6) - 파일 다운로드

by 허도치 2019. 11. 24.

2019/11/19 - [Back-end/Python] - [크롤링] 무작정 시작하기 (1) - 패키지 선택

2019/11/19 - [Back-end/Python] - [크롤링] 무작정 시작하기 (2) - 프로젝트 준비

2019/11/19 - [Back-end/Python] - [크롤링] 무작정 시작하기 (3) - Spider

2019/11/20 - [Back-end/Python] - [크롤링] 무작정 시작하기 (4) - Selenium + Scrapy

2019/11/21 - [Back-end/Python] - [크롤링] 무작정 시작하기 (5) - Item

 

이번 포스트에서는 파일을 다운로드하는 Spider를 생성하여 볼 것이다. 파일을 허락없이 다운받아서 사용하는 것은 위법의 소지가 있으므로 현재 블로그에 있는 예제를 대상으로 학습해보도록 하자.

 

참고로 Tistory에서는 File, Image는 다운로드 받을 수 있는데, Video는 KakaoTV로 연결되어서 받을 수 없음.

 

 

1. 패키지 설치.

   1-1. pillow 설치

1
pip install pillow
cs

         - Scrapy에서는 MediaPipeline을 상속받는 FilesPipeline, ImagesPipeline을 제공하는데, 이 Pipeline들은 pillow 패키지를 사용함.

 

2. Spider 생성.

    2-1. 파일을 다운받는 Spider생성.

1
scrapy genspider tistory heodolf.tistory.com
cs

           - 현재 블로그를 크롤링하는 Spider.

 

   2-2. Spider 작성. [ ./spiders/tistory.py ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# -*- coding: utf-8 -*-
import scrapy
 
from crawler.items import TistoryFileItem
 
class TistorySpider(scrapy.Spider):
    name = 'tistory'
    allowed_domains = [ 'heodolf.tistory.com' ]
    custom_settings= {
        'ITEM_PIPELINES': {
            'scrapy.piplines.files.FilesPipeline'100,
        }
    }
 
    def __init__(self, *args, **kargs):
        self.start_urls = [
            'https://heodolf.tistory.com/18'
        ]
 
    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request( url=url, dont_filter=False, method='GET' )
 
    def parse(self, response):
        from pprint import pprint
 
        contents = response.xpath('//figure[contains(@class,"imageblock")]//img/@src|//figure[contains(@class,"fileblock")]//a/@href')
 
        file_urls = []
        for content in contents:
            src = content.extract()
            if src:
                file_urls.append( src.strip() )
 
        item = TistoryFileItem()
        item['file_urls'= file_urls
        
        yield item
cs

           - 10~11 ln: 파일 다운로드를 위해 Scrapy에서 지원하는 Pipeline을 지정.

           - 27 ln: 다운로드 받을 파일의 URL을 추출.

           - 29~33 ln: 추출한 파일의 URL을 list에 저장.

           - 35~36 ln: FilesPipeline에서는 [ 'files', 'file_urls' ] 두개의 Field를 갖는 Item을 반환해야 함.

 

   2-3. TistoryFileItem 추가. [ ./items.py ]

1
2
3
class TistoryFileItem(scrapy.Item):
    file_urls = scrapy.Field()
    files = scrapy.Field()
cs

           - 특별한거 없이 Field만 선언해줌.

 

   2-4. 기본 옵션 추가. [ ./settings.py ]

1
2
3
4
FILES_STORE = 'donwloads'
 
DEFAULT_FILES_URLS_FIELD = 'file_urls'
DEFAULT_FILES_RESULT_FIELD = 'files'
cs

           - 1 ln: 다운로드 받은 파일이 저장될 root 폴더 지정, 필수값으로 입력해주어야 함.

           - 2~3 ln: TistoryFileItem에서 정의한 field명.

 

   2-5. 실행.

1
scrapy crawl tistory
cs

           - 정상적으로 실행이 된다면, [ downloads/full ] 폴더가 생성되며 다운로드 받은 파일들이 저장됨.

           - 파일명이 일정한 규칙없이 저장됨.

 

 

3. 다운로드 폴더 및 파일명 변경.

    3-1. TistoryFilePipeline 추가.

1
2
3
4
5
6
7
8
import os
from urllib.request import urlparse
 
from scrapy.pipelines.files import FilesPipeline
 
class TistoryFilePipeline( FilesPipeline ):
    def file_path(self, request, response=None, info=None):
        return 'files/' + os.path.basename(urlparse(request.url).path)
cs

           - 4 ln: 파일 다운로드를 처리하는 Pipeline으로 최상위 Pipeline으로 MediaPiepline을 사용함.

           - 7~8 ln: FilesPipeline에서 파일을 다운로드 받고 저장하는 경로를 지정하는 함수를 Override.

 

   3-2. Spider 수정.

1
2
3
4
5
6
7
8
9
class TistorySpider(scrapy.Spider):
    name = 'tistory'
    allowed_domains = [ 'heodolf.tistory.com' ]
    custom_settings= {
        'ITEM_PIPELINES': {
            'crawler.pipelines.TistoryFilePipeline'100,
        }
    }
...
cs

           - 6 ln: Pipeline을 위에서 작성한 TistoryFilePipeline으로 변경.

 

   3-3. 실행.

1
scrapy crawl tistory
cs

           - 정상적으로 실행이 된다면, [ downloads/files ] 폴더가 생성되며 다운로드 받은 파일들이 보여짐.

           - 파일명을 URL에서 추출하여 보기좋게 저장됨.

 

 

 

이상으로 파일을 크롤링하는 Spider를 생성하여 보았다. File을 다운로드하는 로직을 직접 구현하면 아무래도 손이 많이 가는데 Scrapy를 사용하면 쉽게 구현할 수 있다. 단, 파일 다운로드를 남용하여서는 안된다. 저작물을 허락없이 다운로드 받는 것은 위법이기 때문에 각별한 주의를 요한다.

댓글