Scrapy로 애니메이션 데이터를 스크래핑 ②

이 기사에서는 무엇을 알 수 있습니까?



· scrapy에 의한 기본적인 크롤러 만드는 법
· scrapy와 MongoDB의 연결 방법

이것은 무엇을하는 기사?



spider(크롤러)의 소개를 합니다.
마지막 기사의 연속입니다. 지난번에는 xpath로 스크래핑을 할 수 있게 되었습니다. 이번에는 여러 웹 페이지에 자동으로 스크래핑을 할 수 있습니다.
코드는 github에 있습니다.

spider 개요



spider는 웹을 건너면서 스크래핑을 합니다.

spider의 기능은
①웹페이지를 스크래핑하는 것
②Web페이지를 이동하는 것
두 가지입니다.
이제 코드 을 살펴 보겠습니다.
def parse(self, response):
        if self.num == self.limit_id: 
            pass
        else:
            url = 'http://anikore.jp/anime/' + str(self.num) +  '/'


            anime_id = self.num
            title = response.xpath('//*[@id="clm24"]//h2/a[@class="blk_lnk"]/text()').extract_first()
            point = response.xpath('//*[@id="main"]/div[2]/div[2]/div[1]/div[1]/span[2]/text()').extract()
            point_story = response.xpath('//*[@id="main"]/div[2]/div[2]/div[1]/div[2]/span[2]/text()').extract()
            point_animation = response.xpath('//*[@id="main"]/div[2]/div[2]/div[1]/div[3]/span[2]/text()').extract()
            point_vc = response.xpath('//*[@id="main"]/div[2]/div[2]/div[1]/div[4]/span[2]/text()').extract()
            point_music = response.xpath('//*[@id="main"]/div[2]/div[2]/div[1]/div[5]/span[2]/text()').extract()
            point_chara = response.xpath('//*[@id="main"]/div[2]/div[2]/div[1]/div[6]/span[2]/text()').extract()
            total_point = response.xpath('//*[@id="main"]/div[2]/div[2]/div[2]/div[1]/span[2]/text()').extract()
            review_num = response.xpath('//*[@id="main"]/div[2]/div[2]/div[2]/div[2]/span[2]/text()').extract()
            fav_num = response.xpath('//*[@id="main"]/div[2]/div[2]/div[2]/div[3]/span[2]/text()').extract()
            ranking = response.xpath('//*[@id="main"]/div[2]/div[2]/div[2]/div[4]/span[2]/text()').extract()
            summary = response.xpath('//*[@id="main"]/div[2]/div[3]/blockquote/text()').extract()

            print("____________________________________________________")
            print(self.num)

            self.num += 1


            # if anime page exist
            if title is not None:


                #output 
                yield {"anime_id":anime_id,"title":title,"point":point,"point_story":point_story,"point_animation":point_animation, \
                "point_vc":point_vc,"point_music":point_music,"point_chara":point_chara, \
                "total_point":total_point, "review_num":review_num, "fav_num":fav_num, \
                "ranking":ranking, "summary":summary}

                # crawl next anime page
                next_url = 'http://anikore.jp/anime/' + str(self.num) +  '/'
                yield Request(next_url, callback=self.parse, dont_filter=True)
            # If animepage does not exist, redirect to homepage. So, title is None.
            else:

                #crawl next anime page
                next_url = 'http://anikore.jp/anime/' + str(self.num) +  '/'
                yield Request(next_url, callback=self.parse, dont_filter=True)

코드의 요점
①이번 URL은 https://www.anikore.jp/anime/[애니메이션의 id]/라는 규칙이 있기 때문에
애니메이션의 id를 인크리먼트 해 가는 것으로 모든 애니메이션의 페이지에 액세스하는 방법을 취하고 있습니다.
②response.xpath()로 여러가지 스크래핑하고 있습니다.
③yield {yield {"anime_id":anime_id,"title":title,...,}로 스크래핑한 것을 출력
④yield Request(next_url, callback=self.parse, dont_filter=True)로 다음 애니메이션 페이지로 이동

MongoDB와의 연결



scrapy에는 pipeline이라는 구조가 있습니다. scrapy의 구조에 관해서는 @checkpoint 님의 이 기사 가 매우 알기 쉽기 때문에 꼭 배견하겠습니다.
pipeline.py는 다음과 같습니다.

from pymongo import MongoClient  # mongoDB との接続
import datetime
from scrapy.conf import settings


class MongoDBPipeline(object):

    def __init__(self):
        # インスタンス生成時に渡された引数で、変数初期化
        connection = MongoClient(
            settings['MONGODB_SERVER'],
            settings['MONGODB_PORT'])
        db = connection[settings['MONGODB_DB']]
        self.collection = db[settings['MONGODB_COLLECTION']]



    def process_item(self, item, spider):
        self.collection.insert(dict(item))
        return item

MONGODB_*라는 변수가 4개 있지만 setting.py에 설명되어 있습니다.



#mongoDB settings
MONGODB_SERVER = 'localhost'
MONGODB_PORT = 27017
#db name
MONGODB_DB = 'anikore'
#collection name
MONGODB_COLLECTION = "users"


이 경우 anikore라는 데이터베이스 안에 user라는 컬렉션이 만들어져 그 안에 데이터가 들어갑니다.

실행 결과



다음 명령으로 스파이더가 실행됩니다.
scrapy crawl anime

동시에 csv 파일로 내보낼 수도 있습니다.
scrapy crawl anime -o anime.csv

그러면 터미널에서 스파이더가 돌아다니는 것을 느낄 수 있습니다.
그런 다음 MongoDB 데이터가 저장되면 성공합니다. 했어.

또한



이번에 소개한 스파이더를 쓰는 방법을 전용하면 어떤 사이트에 대해서도 임의의 데이터를 수집할 수 있는 것 같습니다. 그러나 그렇게 쉽지 않은 것이 현실. 예를 들어, 사용자의 데이터는 로그인하지 않았다고 볼 수 없습니다. 즉, 스파이더의 기능으로 로그인 페이지로 로그인해야 합니다. 이것은 Scrapy의 FormRequest에서 가능합니다.

읽어 주셔서 감사합니다.

좋은 웹페이지 즐겨찾기