Scrapy is a fast high-level screen scraping and web crawling framework, used to crawl websites and extract structured data from their pages. It can be used for a wide range of purposes, from data mining to monitoring and automated testing.
Scrapy documentation : http://doc.scrapy.org/en/0.20/
공식 페이지의 설명에서 볼 수 있듯이 Scrapy는 python 기반의 파싱 프레임워크다.
Scrapy를 알기 전에는 urllib2와 beatifulsoup로 파싱을 해 왔으나, Scrapy를 쓰면 훨씬 빠른 속도로 crawling을 할 수 있었다.
자세한 정보는 공식 튜토리얼을 통해서 얻을 수 있으며, Scrapy를 사용하기 위해서는 lxml, OpenSSL이 필요하다.
Installation : http://doc.scrapy.org/en/latest/intro/install.html
Tutorial : http://doc.scrapy.org/en/latest/intro/tutorial.html#crawling
간단하게 프로젝트를 시작하는 방법을 설명해 보면,
scrapy startproject scrapy_sample
cd scrapy_sample
vi scrapy_sample/spiders/spider.py
로 새로운 프로젝트를 하나 만들고, spider.py 파일을 만든다.
Scrapy 공식 홈페이지에 나와있는 example 소스는 아래와 같다.
from scrapy.spider import BaseSpider from scrapy.selector import HtmlXPathSelector from scrapy.item import Item, Field class Website(Item): // parse 된 정보를 저장할 class name = Field() // Field()에는 숫자와 string 모두 저장할 수 있음 description = Field() url = Field() class DmozSpider(BaseSpider): name = "dmoz" // spider의 이름을 나타낸다 allowed_domains = ["dmoz.org"] // dmoz.org 이외의 redirect는 무시된다. start_urls = [ "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/", "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/", ] // start_urls 안에 들어있는 url이 parse 된다 def parse(self, response): hxs = HtmlXPathSelector(response) // css selector 문법을 통해 dom element 를 찾을 수 있다. sites = hxs.select('//ul[@class="directory-url"]/li') items = [] for site in sites: item = Website() item['name'] = site.select('a/text()').extract() item['url'] = site.select('a/@href').extract() item['description'] = site.select('text()').re('-\s([^\n]*?)\\n') items.append(item) return items
이후 project 의 root 디렉토리에서 아래와 같은 명령어를 입력하면 된다.
selector 에 대한 정보는
http://doc.scrapy.org/en/latest/topics/selectors.html
여기서 찾을 수 있다.
Scrapy에 대한 한국어 문서가 없어서 제대로된 사용법을 찾는데 시간이 조금 걸렸지만,
다른분들은 이 글을 읽으시고 시간낭비를 하지 않으시길 바란다.
아래의 예제는 네이버 영화 정보를 파싱하는 spider다.
영화 제목과 개봉시기, 장르 등의 정보를 파싱하며 위에 나온 명령어들을 사용하면 쉽게 json 파일을 얻을 수 있을 것이다.
scrapy crwal dmoz // spiders 폴더 내에 있는 소스 코드 중 dmoz를 이름으로 가지고 있는 spider를 실행
scrapy crawl dmoz -o some.json -t json 2> result.txt // item을 json형태로 txt 파일에 저장
rm result.txt // 크롤 하기 전에 result.txt는 매번 지워주어야 함
scrapy shell spider.py // scrapy를 shell 형태로 실행
scrapy shell "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/"
selector 에 대한 정보는
http://doc.scrapy.org/en/latest/topics/selectors.html
여기서 찾을 수 있다.
Scrapy에 대한 한국어 문서가 없어서 제대로된 사용법을 찾는데 시간이 조금 걸렸지만,
다른분들은 이 글을 읽으시고 시간낭비를 하지 않으시길 바란다.
아래의 예제는 네이버 영화 정보를 파싱하는 spider다.
영화 제목과 개봉시기, 장르 등의 정보를 파싱하며 위에 나온 명령어들을 사용하면 쉽게 json 파일을 얻을 수 있을 것이다.
__author__ = 'carpedm20' __date__ = '2013.11.14' from scrapy.spider import BaseSpider from scrapy.selector import HtmlXPathSelector from scrapy.http.request import Request from scrapy.item import Item, Field import sys, os class ScrapyItem(Item): title = Field() url = Field() year = Field() open1 = Field() # 2013 open2 = Field() # 06.12 country = Field() genre = Field() form = Field() grade = Field() YEAR = "2015" START_PAGE = 10 # 0 START_PAGE = 0 # 0 MAX_LOOP = 4 #-1 MAX_LOOP = -1 #-1 PMOD = True PMOD = False print "===================" print YEAR print "===================" url = "http://movie.naver.com/movie/sdb/browsing/bmovie.nhn?year="+YEAR+"&page=" + str(START_PAGE) index = start_page = START_PAGE old_index = -1 old_title = "" loop = 0 pmod = PMOD max_loop = MAX_LOOP class ScrapyOrgSpider(BaseSpider): name = "naver" allowed_domains = ["movie.naver.com"] start_urls = [url] def parse(self, response): global start_page, index, loop, old_title, pmod, max_loop hxs = HtmlXPathSelector(response) items = [] loop += 1 next_page = ["http://movie.naver.com/movie/sdb/browsing/bmovie.nhn?year="+YEAR+"&page="+str(loop + start_page)] if max_loop != -1: if loop >= max_loop: next_page = [] posts = hxs.select("//ul[@class='directory_list']/li") title = posts[0].select("a/text()")[0].extract() if old_title == title and loop > 2: next_page = [] else: old_title = title if not not next_page: yield Request(next_page[0], self.parse) #posts = hxs.select("//tr") count = 0 print "[ " + str(loop) + " ] index : " + str(index) + ", len(posts) : " + str(len(posts)) for post in posts: try: title = post.select("a/text()")[0].extract() if pmod: print " [ " + str(count) + " ] TITLE : " + title url = post.select("a/@href")[0].extract() if pmod: print " [ " + str(count) + " ] URL : " + url year = post.select("ul[@class='detail']/li/a")[0].select("b/text()")[0].extract() if pmod: print " [ " + str(count) + " ] YEAR : " + year open1 = "" open2 = "" country = "" genre = "" form = "" grade = "" open_count = 0 lis = post.select("ul[@class='detail']/li/a") for li in lis: h = li.select('@href')[0].extract() href = h[h.find('&')+1:h.rfind('=')] if pmod: print " [*] HREF : " + href if href == '?year': if pmod: print " [-] HREF SKIP : " + h continue if href == 'open' and open_count == 0: open1 = li.select('text()')[0].extract() open_count += 1 if pmod: print " [*] open1 : " + open1 elif href == 'open' and open_count == 1: try: open2 = li.select('text()')[0].extract() if pmod: print " [*] open2 : " + open2 except: z = 123 elif href == 'nation': country = li.select('text()')[0].extract() if pmod: print " [*] country : " + country elif href == 'genre': genre = li.select('text()')[0].extract() if pmod: print " [*] genre : " + genre elif href == 'form': form = li.select('text()')[0].extract() if pmod: print " [*] form : " + form elif href == 'grade': grade = li.select('text()')[0].extract() if pmod: print " [*] grade : " + grade else: print " [^] Found NEW href : " + h return count += 1 except Exception as e: #for frame in traceback.extract_tb(sys.exc_info()[2]): # fname,lineno,fn,text = frame # print "Error in %s on line %d" % (fname, lineno) exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno) #for e in sys.exc_info(): # print e continue item = ScrapyItem() item["title"] = title item["url"] = url item["year"] = year item["open1"] = open1 item["open2"] = open2 item["country"] = country item["genre"] = genre item["form"] = form item["grade"] = grade items.append(item) for item in items: yield item old_index = index index += count
ps.
실행 안되는데요? @@ scrapy 에 요즘 빠져있는 1인입니다. 혹시 시간되시면 도움 주실수 있나요? 한국에서는 님이 고수인듯... ㅠ.ㅠ 도와주세요~
답글삭제얼마전에 메일 드렸었는데... 바쁜신가봐요~ ^^;
삭제Carpedm20: [Python] Scrapy - 네이버 영화 파싱 >>>>> Download Now
삭제>>>>> Download Full
Carpedm20: [Python] Scrapy - 네이버 영화 파싱 >>>>> Download LINK
>>>>> Download Now
Carpedm20: [Python] Scrapy - 네이버 영화 파싱 >>>>> Download Full
>>>>> Download LINK FA
파싱한 내용을 한글로 변환할 수 있는 방법좀 알려주세요 ㅠㅠ
답글삭제잘 보고 갑니당
답글삭제Carpedm20: [Python] Scrapy - 네이버 영화 파싱 >>>>> Download Now
답글삭제>>>>> Download Full
Carpedm20: [Python] Scrapy - 네이버 영화 파싱 >>>>> Download LINK
>>>>> Download Now
Carpedm20: [Python] Scrapy - 네이버 영화 파싱 >>>>> Download Full
>>>>> Download LINK