구동환경

1) python 3.6

2) Miniconda3

3) jupyter notebook

4) scrapy


위 그림 설명

1) cmd로 들어가서 activate py27 입력

2) scrapy startproject movie_crawler 입력 (path가 된 폴더에 movie_crawler 폴더가 생성, scrapy 준비 완료)






url 화면.


https://www.rottentomatoes.com/top/bestofrt/?year=2017 <- 스크랩이 될 url





2017년에 개봉한 영화중 순위가 높은 순서대로 스크랩 후 액셀 저장.



작업 순서

1) rt_crawler 폴더안에 rt_spider라는 .py 파일을 만들어서 아래와 같이 입력한다.


#-*- coding: utf-8 -*-

#activate py27 -> cd rt_crawler -> scrapy crawl RottenTomatoes

#1.item.py에서 필드 설정

#2.rt_spider.py에서 코드 입력

#3.pipeline.py에서 코드 입력

#4.setting.py에서 코드 설정


#scrapy 라이브러리

import scrapy

from rt_crawler.items import RTItem


class RTSpider(scrapy.Spider):

    name = "RottenTomatoes" # scrapy crawl 실행 이름

    allowed_domains = ["rottentomatoes.com"] # 허용된 도메인

    start_urls = ["https://www.rottentomatoes.com/top/bestofrt/?year=2017"] # 정보 검색하려는 페이지


#xpath값 삽입.

    def parse(self, response):

        for tr in response.xpath('//*[@id="top_movies_main"]/div/table/tr'): # 정보 검색하려는 페이지의 영화 제목

            href = tr.xpath('./td[3]/a/@href') # href는 속성값

            url = response.urljoin(href[0].extract()) # 허용된 도메인에 서브 URL붙이기

            yield scrapy.Request(url, callback=self.parse_page_contents) # 서브 URL 붙인 최종 URL 반출, 최종URL에서 불러들일 정보 반출


    def parse_page_contents(self, response): #parse_page_contents 함수 작성

        item = RTItem()

        item["title"] = response.xpath('//*[@id="movie-title"]/text()')[0].extract().strip() #타이틀 스크랩

        item["score"] = response.xpath('//*[@id="tomato_meter_link"]/span[2]/span/text()')[0].extract() #평점 스크랩

        item["genres"] = response.xpath('//*[@id="mainColumn"]/section[3]/div/div/ul/li[2]/div[2]/a[1]/text()')[0].extract().strip()    #장르 스크랩

        item["runtime"] = response.xpath('//*[@id="mainColumn"]/section[3]/div/div/ul/li[8]/div[2]/time/text()')[0].extract().strip() #런타임 스크랩

        consensus_list = response.xpath('//*[@id="all-critics-numbers"]/div/div[2]/p//text()').extract()[2:] #설명 스크랩

        item["consensus"] = ' '.join(consensus_list).strip()

        yield item #아이템 반출


2) rt_crawler 폴더에 만들어져있는 item.py에 들어가서 아래와 같이 입력한다.


import scrapy


class RTItem(scrapy.Item) :

    title = scrapy.Field()

    score = scrapy.Field()

    genres = scrapy.Field()

    runtime = scrapy.Field()

    consensus = scrapy.Field()


3)  rt_crawler 폴더에 만들어져있는 pipeline.py에 들어가서 아래와 같이 입력한다.


import csv 


class RTPipeline(object):


    def __init__(self):

        self.csvwriter = csv.writer(open("rt_movies_new.csv", "w"))

        self.csvwriter.writerow(["title", "score", "genres", "runtime", "consensus"])


    def process_item(self, item, spider):

        row = []

        row.append(item["title"])

        row.append(item["score"])

        row.append('|'.join(item["genres"]))

        row.append(item["runtime"])

        row.append(item["consensus"])

        self.csvwriter.writerow(row)

        return item

        


4) rt_crawler 폴더에 만들어져있는 setting.py에 들어가서 코드를 아래와 같이 수정한다.


ITEM_PIPELINES = {

    'rt_crawler.pipelines.RTPipeline': 400,

}


5) cmd창에서 scrapy crawl RottenTomatoes 입력.

6) 엑셀에 스크랩하려는 정보를 저장시킨다.



url을 반복문으로 반출하기

<rt_crawler.py>


    def parse(self, response):

        for tr in response.xpath('//*[@id="top_movies_main"]/div/table/tr'): # 정보 검색하려는 페이지의 영화 제목

            href = tr.xpath('./td[3]/a/@href') # href는 속성값

            url = response.urljoin(href[0].extract()) # 허용된 도메인에 서브 URL붙이기

            yield scrapy.Request(url, callback=self.parse_page_contents) # 서브 URL 붙인 최종 URL 반출, 최종URL에서 불러들일 정보 반출



activate py27 -> scrapy startproject rt_crawler -> scrapy shell ('url1')의 환경에서  (url1 : 스크랩할 페이지)

reponse.xpath('xpath')을 실행시킨다.  


<괄호 안에 들어갈 xpath 예시>




개발자도구 (컨트롤+쉬프트+i) -> 엘리먼트 선택(컨트롤+쉬프트+c)

영화 Get out에 마우스 커서를 갖다대면 사진의 오른쪽과 같이 (a herf ~) 파란색 박스가 뜨게 된다.






해당 박스에 오른쪽 마우스를 누르면 Copy Xpath가 뜨게 된다.

클릭하여 실행창에 붙여넣으면 //*[@id="top_movies_main"]/div/table/tbody/tr[1]/td[3]/a 와 같은 문장이 나오게 된다.

이 문장을 위에 설명한 환경에서 reponse.xpath('//*[@id="top_movies_main"]/div/table/tbody/tr[1]/td[3]/a') 이런 식으로 넣게되면 

copy xpath에 해당하는 element가 무엇인지 출력하게 된다.



위 그림은 //*[@id="top_movies_main"]/div/table/tbody/tr[1]/td[3]/a 를 조금씩 수정하면서 출력값을 얻어낸 화면이다.


최종적으로 맨밑에줄에 

response.xpath('//*[@id="top_movies_main"]/div/table/tr[1]/td[3]/a/@href')[0].extract 을 실행하면 get out이라는 엘리먼트가 출력된다.

(href는 엘리먼트의 속성값)


get out이외의 다른 엘리먼트의 xpath를 복사하면 tr[1], tr[2], tr[3],.. 이런식으로 1위 ~ n위까지 path가 생성된다.

따라서 아래의 코드를 입력하여 반복적으로 url을 스크랩해온다.


 for tr in response.xpath('//*[@id="top_movies_main"]/div/table/tr'): # 정보 검색하려는 페이지의 영화 제목

            href = tr.xpath('./td[3]/a/@href') # href는 속성값

            url = response.urljoin(href[0].extract()) # 허용된 도메인에 서브 URL붙이기

            yield scrapy.Request(url, callback=self.parse_page_contents) # 서브 URL 붙인 최종 URL 반출, 최종URL에서 불러들일 정보 반출


정리해서 위의 코드를 해석하면,

xpath를 불러옴 -> href로 속성값을 따옴 -> 허용된 도메인에 href가 포함된 url 붙이기 -> 최종 url 반출.



contents를 xpath로 불어들이기


평점, 줄거리에 대한 엘리먼트값 확인

    

def parse_page_contents(self, response): #parse_page_contents 함수 작성

        item = RTItem()

        item["title"] = response.xpath('//*[@id="movie-title"]/text()')[0].extract().strip() #타이틀 스크랩

        item["score"] = response.xpath('//*[@id="tomato_meter_link"]/span[2]/span/text()')[0].extract() #평점 스크랩

        item["genres"] = response.xpath('//*[@id="mainColumn"]/section[3]/div/div/ul/li[2]/div[2]/a[1]/text()')[0].extract().strip()    #장르 스크랩

        item["runtime"] = response.xpath('//*[@id="mainColumn"]/section[3]/div/div/ul/li[8]/div[2]/time/text()')[0].extract().strip() #런타임 스크랩

        consensus_list = response.xpath('//*[@id="all-critics-numbers"]/div/div[2]/p//text()').extract()[2:] #설명 스크랩

        item["consensus"] = ' '.join(consensus_list).strip()

        yield item #아이템 반출


위 코드는 url에서 했던 내용과 일치한다.

각 아이템의 제목을 명시하고 response.xpath('')로 엘리먼트를 불러들인다.

+ xpath복사 후 /text() 추가 : 글자만 스크랩한다.

+ .strip()을 추가하여 해당 내용 외의 불필요한 소스들 제거




pipeline.py을 이용하여 엑셀에 저장하기

import csv 


class RTPipeline(object):


    def __init__(self):

        self.csvwriter = csv.writer(open("rt_movies_new.csv", "w"))

        self.csvwriter.writerow(["title", "score", "genres", "runtime", "consensus"])


    def process_item(self, item, spider):

        row = []

        row.append(item["title"])

        row.append(item["score"])

        row.append(item["genres"])

        row.append(item["runtime"])

        row.append(item["consensus"])

        self.csvwriter.writerow(row)

        return item


item.py을 이용하여 변수 설정하기


import scrapy


class RTItem(scrapy.Item) :

    title = scrapy.Field()

    score = scrapy.Field()

    genres = scrapy.Field()

    runtime = scrapy.Field()

    consensus = scrapy.Field()


이 상태에서 실행창에 scrapy crawl RottenTomatoes를 입력하면 엑셀에 스크랩한 정보가 저장된다.

'코딩이것저것' 카테고리의 다른 글

키움증권 API를 이용한 자동매매  (0) 2018.04.18
동적 웹 페이지에서 데이터 추출하고 수집하기  (0) 2017.09.02
CNN_deep CNN mnist  (0) 2017.08.07
CNN_drop out, ensemble  (0) 2017.08.06
CNN_weight initialization  (0) 2017.08.06

+ Recent posts