scrapy로 11번가의 베스트 상품을 크롤링 하는 예제
수집항목 : 각 카테고리별 베스트 200 상품 (메인카테고리, 서브카테고리, 제목, 가격, 판매자, 세부url)
진행순서
1. 프로젝트 만들기
>>scrapy startproject elest (프로젝트명은 영어만 가능)
2.스파이더 봇 만들기
scrapy genspider elebest www.11st.co.kr/browsing/BestSeller.tmall?method=getBestSellerMain
*url은 추후 수정가능
3. elebest.py 파일 작성하기
elebest.py
import scrapy
from elest.items import ElestItem
class ElebestSpider(scrapy.Spider):
name = 'elebest'
#__init__ 함수처럼 기본으로 실행됨. start_requests 함수 작성시 start_urls 변수는 주석처리 또는 삭제
def start_requests(self):
url = "https://www.11st.co.kr/browsing/BestSeller.tmall?method=getBestSellerMain"
yield scrapy.Request(url = url , callback=self.parse_main)
#카테고리의 세부 url을 얻는 중간 단계
def parse_main(self, response):
ca_link = response.css("div.best_category_box > ul > li button::attr(onclick)").getall()
ca_name = response.css("div.best_category_box > ul > li button::text").getall()
sub_link = response.css("div.sub_category_box > ul > li a::attr(onclick)").getall()
sub_name = response.css("div.sub_category_box > ul > li a::text").getall()
#세부 카테고리들의 베스트 상품만 크롤링
for index, link in enumerate(sub_link):
link_first = link.find("(")
link_last = link.find(")")
link = link[link_first+1:link_last].split(",")
url = "http://www.11st.co.kr/browsing/BestSeller.tmall?method=getBestSellerMain&cornerNo={}&dispCtgrNo={}".format(link[0],link[1])
yield scrapy.Request(url =url,
callback=self.parse_items, meta={"maincategory_name":ca_name[int(link[0])],"subcategory_name":sub_name[index]})
#대표카테고리의 베스트 200도 크롤링 하고 싶다면 아래 코드 추가
# for index, link in enumerate(ca_link):
# link_first = link.find("(")
# link_last = link.find(")")
# link = link[link_first+1:link_last]
# yield scrapy.Request(url ="http://www.11st.co.kr/browsing/BestSeller.tmall?method=getBestSellerMain&cornerNo="+link,
# callback=self.parse_items, meta={"maincategory_name":ca_name[index], "subcategory_name":"ALL"})
각각의 카테고리의 이름과 링크를 최종적으로 parse_items 함수로 넘겨준다. (meta는 카테고리 이름 정보)
def parse_items(self, response):
best_items = response.css("ul.cfix ")[1].css("li")
for s, item in enumerate(best_items):
doc = ElestItem()
main_category=response.meta["maincategory_name"]
sub_category = response.meta["subcategory_name"]
ranking = s+1
title = item.css("a p::text").get()
price = item.css("strong.sale_price::text").get()
seller = item.css("div.store a::text").get()
link = item.css("div a::attr(href)").get()
doc["main_category"] = main_category
doc["sub_category"] =sub_category
doc["ranking"] = ranking
doc["title"] = title
doc["price"] = price
doc["seller"] = seller
doc["link"] = link
yield doc
elebest.py 내의 parse_items 함수에서 상품의 제목, 가격 등을 뽑는다. (메인카테고리, 서브카테고리는 메타로 받은 정보)
4.items.py 작성
import scrapy
class ElestItem(scrapy.Item):
main_category= scrapy.Field()
sub_category = scrapy.Field()
ranking= scrapy.Field()
title= scrapy.Field()
price= scrapy.Field()
seller= scrapy.Field()
link= scrapy.Field()
5.settings.py 작성
settings.py
BOT_NAME = 'elest'
SPIDER_MODULES = ['elest.spiders']
NEWSPIDER_MODULE = 'elest.spiders'
#csv 한글 깨짐 방지
FEED_EXPORT_ENCODING="utf-8-sig"
#각 카테고리의 상품의 순서가 섞이지 않게 딜레이 부여
DOWNLOAD_DELAY = 1
ROBOTSTXT_OBEY = True
#순서대로 크롤링, 시간이 조금 더 소요됨.
CONCURRENT_REQUESTS = 1
#csv 저장시 순서 정렬
FEED_EXPORT_FIELDS=["ranking","main_category","sub_category","title", "price", "seller","link"]
#하나의 함수에서 동일한 url로 Request 할경우
DUPEFILTER_CLASS ='scrapy.dupefilters.BaseDupeFilter'
6. 봇 실행 (csv로 저장)
>> scrapy crawl elebest -o elebest.csv -t csv
몽고db 저장은 아래 글 참조.
7.csv파일 확인
끝
반응형
'크롤링 > scrapy' 카테고리의 다른 글
scrapy 동일한 url Request (0) | 2020.09.24 |
---|---|
scrapy[스크래피] mongo db 인서트 (0) | 2020.09.24 |
[scrapy] 엑셀(csv) 필드 정렬, 순서대로 저장, 한글 깨짐 현상 (1) | 2020.09.22 |
scrapy shell 접속, 크롤링 (0) | 2020.09.22 |
scrapy(스크래피) 프로젝트 생성방법 (0) | 2020.09.18 |