Akashic Records

Scrapy, CrawlSpider 본문

Web Crawling for Beginners

Scrapy, CrawlSpider

Andrew's Akashic Records 2024. 7. 5. 14:03
728x90

 

CrawlSpider

CrawlSpider는 Scrapy 프레임워크 내에서 링크를 따라가며 데이터를 수집하는 고급 스파이더 유형입니다. CrawlSpider를 사용하면, 복잡한 웹사이트에서 링크를 따라 자동으로 페이지를 탐색하고, 특정 데이터를 추출하는 크롤링 작업을 손쉽게 설정할 수 있습니다.

CrawlSpider의 주요 특징

  • 규칙 기반 링크 추적: CrawlSpiderRule 객체를 사용하여 어떤 링크를 따라갈 것인지, 그리고 각 링크에서 어떤 처리를 할 것인지를 정의합니다. 이 규칙들은 웹사이트의 구조에 따라 맞춤화할 수 있으며, 매우 유연한 크롤링이 가능합니다.
  • LinkExtractor 사용: LinkExtractor는 특정 조건에 맞는 링크를 추출하는데 사용됩니다. 예를 들어, 특정 패턴을 가진 URL, 특정 태그의 링크 등을 지정할 수 있습니다.
  • 다양한 콜백 함수: 각 Rule은 콜백 함수를 가질 수 있으며, 이 콜백 함수는 링크를 따라가서 수집된 페이지에 대해 실행됩니다. 데이터 파싱 또는 추가적인 요청을 처리할 때 사용됩니다.

CrawlSpider의 구성요소

  1. name: 스파이더의 이름을 지정합니다.
  2. allowed_domains: 스파이더가 크롤링할 도메인의 리스트입니다.
  3. start_urls: 스파이더가 크롤링을 시작할 URL의 리스트입니다.
  4. rules: Rule 객체의 튜플이며, 스파이더가 어떤 링크를 따라갈 것인지, 각 링크에서 어떤 메소드를 호출할 것인지를 정의합니다.

Rule 객체

Rule 객체는 CrawlSpider에서 사용되며, 웹사이트의 크롤링 방식을 정의할 때 매우 중요한 역할을 합니다. Rule을 이해하고 사용하기 위해 각 매개변수의 역할과 의미를 알아보겠습니다.

Rule의 주요 매개변수

  1. link_extractor:
    • 역할: 페이지에서 링크를 추출하는 방법을 정의합니다.
    • 타입: LinkExtractor 객체입니다. LinkExtractor는 링크를 추출할 때 사용할 규칙을 정의하며, 주로 allow, deny, allow_domains, deny_domains, restrict_xpaths, restrict_css 등의 매개변수를 통해 구체적인 링크 추출 조건을 설정합니다.
  2. callback:
    • 역할: 링크를 따라가서 수집된 응답에 대해 실행할 함수를 지정합니다.
    • 타입: 문자열이거나 호출 가능한 함수 이름입니다. 이 함수는 링크에서 수집된 응답을 처리하고, 일반적으로 아이템을 반환하거나 추가 요청을 만듭니다.
  3. follow:
    • 역할: 링크를 따라 이동한 후에 추가로 그 페이지에서 링크를 추출하여 계속 따라갈지 결정합니다.
    • 타입: True 또는 False (기본값은 False). True로 설정하면 LinkExtractor에 의해 추출된 모든 링크를 따라 계속 크롤링합니다.
  4. process_links:
    • 역할: link_extractor에 의해 추출된 링크들을 처리하기 위한 함수를 지정합니다.
    • 타입: 링크 리스트를 받아서 처리한 후 리스트로 반환하는 함수입니다. 예를 들어, 특정 링크를 제거하거나 수정할 때 사용할 수 있습니다.
  5. process_request:
    • 역할: 크롤링할 각 요청을 처리하기 전에 요청을 수정할 수 있는 기능을 제공합니다.
    • 타입: 요청 객체를 받아 수정한 후 요청 객체를 반환하는 함수입니다. 예를 들어, 헤더를 추가하거나 쿠키를 변경할 때 사용할 수 있습니다.

Rule 매개변수 예제코드

아래의 예제 코드에서 Rule의 사용 방법을 보여줍니다. 이 코드는 특정 도메인의 모든 페이지를 방문하고, 각 페이지의 링크를 따라가며 제목을 수집합니다:

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule

class MySpider(CrawlSpider):
    name = 'example_spider'
    allowed_domains = ['example.com']
    start_urls = ['http://example.com']

    rules = (
        Rule(
            LinkExtractor(allow=('category/', )),
            callback='parse_page',
            follow=True,
            process_links='filter_links'
        ),
    )

    def parse_page(self, response):
        yield {'title': response.css('title::text').get()}

    def filter_links(self, links):
        # 특정 조건을 만족하는 링크만 필터링
        return [link for link in links if 'important' in link.url]

이 코드는 category/ 경로를 포함하는 링크를 추출하고, 해당 링크를 따라가서 각 페이지의 제목을 수집합니다. 또한, process_links 매개변수를 사용하여 'important'라는 단어가 URL에 포함된 링크만 추출하도록 필터링합니다.

 

Rule을 사용함으로써 CrawlSpider를 더욱 강력하고 유연하게 만들 수 있으며, 복잡한 웹사이트 구조에서도 효과적으로 데이터를 수집할 수 있습니다.

예제 코드 설명

  • 도메인 제한: 크롤링을 허용할 도메인을 지정합니다.
  • 시작 URL: 크롤링을 시작할 URL입니다.
  • 규칙:
    • 첫 번째 규칙은 기사 목록 페이지에서 개별 기사로 링크를 추적합니다.
    • 두 번째 규칙은 각 기사 페이지에서 관련 기사 링크를 추적합니다.
  • 콜백 함수: 각 기사 페이지에서 데이터를 추출합니다.
  • 페이지네이션: 기사 목록의 다음 페이지 링크를 따라가는 기능도 포함합니다.

CrawlSpider 예제 코드

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule

class NewsSpider(CrawlSpider):
    name = 'news_spider'
    allowed_domains = ['example-news.com']
    start_urls = ['http://example-news.com/archive']

    rules = (
        # 규칙 1: 기사 목록에서 각 기사 링크를 추적
        Rule(LinkExtractor(allow=r'/articles/'), callback='parse_article', follow=True),

        # 규칙 2: 기사 페이지에서 관련 기사 링크를 추적
        Rule(LinkExtractor(allow=r'/related_articles/'), follow=True),

        # 규칙 3: 페이지네이션 링크 추적
        Rule(LinkExtractor(allow=r'/archive\?page=\d+'), follow=True)
    )

    def parse_article(self, response):
        yield {
            'title': response.css('h1.article-title::text').get(),
            'publication_date': response.css('span.pub-date::text').get(),
            'content': ''.join(response.css('div.article-content p::text').getall())
        }

코드의 기능

  1. 규칙 1: /articles/ URL 패턴을 가진 링크를 찾아 각 기사 페이지로 이동하고 parse_article 메소드를 호출합니다.
  2. 규칙 2: 기사 페이지 내에서 /related_articles/ 패턴을 가진 링크를 따라 관련 기사를 계속해서 추적합니다.
  3. 규칙 3: /archive?page= 패턴을 사용해 기사 목록의 다음 페이지로 이동합니다.

사용 시 고려할 점

  • 실제로 웹사이트를 크롤링할 때는 해당 웹사이트의 robots.txt 정책을 확인하고, 웹사이트에 과부하를 주지 않도록 크롤링 빈도를 조절해야 합니다.
  • 특정 웹사이트의 구조에 따라 CSS 선택자는 변경될 수 있으므로, 웹사이트의 HTML 구조를 분석하여 적절한 선택자를 사용해야 합니다.

이 예제는 CrawlSpider의 다양한 기능을 활용하여 복잡한 웹사이트에서 효과적으로 데이터를 수집하는 방법을 보여줍니다. 데이터 수집을 위해 추가적으로 필요한 사항이 있으면 언제든지 질문해주세요.

 

CrawlSpider 파일 저장

Scrapy를 사용하여 CrawlSpider의 크롤링 결과를 CSV, JSON, XML 파일로 저장하는 방법은 몇 가지 단계로 나눌 수 있습니다. Scrapy의 내장 기능을 활용하여 이러한 작업을 쉽게 수행할 수 있습니다. 각 파일 형식에 대한 저장 방법을 구체적으로 설명하고 예제 코드를 제공하겠습니다.

예제 코드 구조

  • items.py: 추출할 데이터를 정의하는 아이템 클래스를 포함합니다.
  • spiders/your_spider.py: CrawlSpider를 사용하여 데이터를 추출하는 스파이더를 정의합니다.
  • 실행 명령어: 각 파일 형식에 맞는 출력을 설정하는 Scrapy 명령어입니다.

1. items.py 설정

import scrapy

class ArticleItem(scrapy.Item):
    title = scrapy.Field()
    url = scrapy.Field()
    last_updated = scrapy.Field()

2. your_spider.py 설정

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from your_project.items import ArticleItem

class ArticleSpider(CrawlSpider):
    name = 'article_spider'
    allowed_domains = ['example.com']
    start_urls = ['http://www.example.com']

    rules = (
        Rule(LinkExtractor(allow=r'/articles/'), callback='parse_article', follow=True),
    )

    def parse_article(self, response):
        item = ArticleItem()
        item['title'] = response.css('h1::text').get()
        item['url'] = response.url
        item['last_updated'] = response.css('#last-updated::text').get()
        return item

3. Scrapy 실행 명령어

각 파일 형식에 대한 데이터 저장을 위해 다음과 같은 Scrapy 명령어를 사용할 수 있습니다. 이 명령어들은 프로젝트 디렉토리의 루트에서 실행해야 합니다.

CSV 파일로 저장

scrapy crawl article_spider -o articles.csv

JSON 파일로 저장

scrapy crawl article_spider -o articles.json

XML 파일로 저장

scrapy crawl article_spider -o articles.xml

추가 설정

각 파일 형식에 대한 출력 설정을 settings.py에서 세부적으로 조정할 수 있습니다. 예를 들어, JSON 파일의 경우, 인코딩, 들여쓰기 등을 설정할 수 있습니다.

# settings.py
FEED_EXPORT_ENCODING = 'utf-8'
FEED_EXPORT_INDENT = 2  # JSON 파일을 위해 설정, XML에는 적용되지 않음

이 설정을 통해, CrawlSpider로부터 추출한 데이터를 다양한 형식의 파일로 저장할 수 있으며, 이 파일들은 데이터 분석, 보고서 작성, 혹은 다른 시스템으로의 데이터 이전 등에 사용될 수 있습니다. 이 예제 코드는 Scrapy의 강력한 데이터 추출 및 저장 기능을 활용하여, 웹 크롤링 결과를 효과적으로 관리하는 방법을 보여줍니다.

728x90

'Web Crawling for Beginners' 카테고리의 다른 글

Scrapy, Pipelines  (0) 2024.07.10
Python Visualization 라이브러리  (0) 2024.05.24
Scrapy, logging  (0) 2024.05.16
Scrapy, A multi-page website into An Excel file  (0) 2024.05.16
Scrapy 프레임워크  (0) 2024.05.16
Comments