Yêu cầu:
- Scrapy
- Splash (Splash chạy trên docker)
Nội dung bài viết này tham khảo bài viết ở viblo.asia, tác giả đã giải thích rất chi tiết, các bạn có thể đọc để hiểu thêm.
Ở Bài này mình chỉ sử dụng thêm ItemLoader để có thể tùy chỉnh dữ liệu dễ hơn, đồng thời sử dụng phân trang đơn giản hơn.
1. Tạo Spinder
scrapy genspider shopee https://shopee.vn
Xác định các thông tin cần lấy, Ví dụ
- title - tên sản phẩm
- price - giá sản phẩm
2. Trong tệp items.py
Sử dụng Itemloader để dễ xử lý thôn tin khi cần
# items.py
import scrapy
from scrapy.loader import ItemLoader
from itemloaders.processors import TakeFirst, MapCompose
from w3lib.html import remove_tags
""" Dùng với ItemLoader """
# Xóa dấu chấm (.) trong giá
def remove_dot(value):
return value.replace('.', '')
# xóa khoảng trắng đầu và cuôi trong tiêu đề nếu có
def remove_space(value):
return value.strip()
class ShopeeProduct(scrapy.Item):
title = scrapy.Field(input_processor = MapCompose(remove_tags, remove_space), output_processor = TakeFirst())
price = scrapy.Field(remove_tags, remove_vnd, remove_dot), output_processor = TakeFirst())
3. Trong tệp shopee.py
- Vì Shopee sử dung Javascript hiển thị danh sách sản phẩm, nên ta sử dụng
scrapy_splash. - Sử dụng
ItemLoaderđể có thể dễ dàng thêm bớt dữ liệu vào chuỗi trước khi nó được lưu lại.
import re
import scrapy
from scrapy_splash import SplashRequest
from ..items import ShopeeProduct
from scrapy.loader import ItemLoader
class ShopeeSpider(scrapy.Spider):
name = 'shopee'
allowed_domains = ['shopee.vn']
page_number = 0 # trang mặc định page=0
start_urls = ["https://shopee.vn/sp.btw2"] # đây là 1 trang cửa hàng
def start_requests(self):
for url in self.start_urls:
yield SplashRequest(
url,
endpoint="render.html",
args={
'wait': 5,
},
callback=self.parse,
dont_filter=True
)
def parse(self, response):
for data in response.css(".col-xs-2-4"):
l = ItemLoader(item = ShopeeProduct(), selector = data)
l.add_css('title', '.pcmall-shopmicrofe_2498rm', re='([^]]+$)') # Xóa chuỗi [text]
l.add_css('price', '.pcmall-shopmicrofe_1KcSLJ')
yield l.load_item()
# phân trang
next_page = 'https://shopee.vn/sp.btw2?page='+ str(ShopeeSpider.page_number)
if ShopeeSpider.page_number < 5: # Giới hạn quét bao nhiêu trang
ShopeeSpider.page_number += 1
yield response.follow(next_page, callback=self.parse)
4. Bây giờ, đã có thể Crawl và xuất dữ liệu shopee
Ví dụ: Crawl và xuất dữ liệu ra tệp shopee-product.csv
scrapy crawl shopee -o shopee-product.csv