Scrapy 實戰:高效爬取 Taobao 商品列表與詳情頁

在電子商務數據獲取與分析的領域中,「如何有效、穩定地抓取商品數據」始終是一項關鍵挑戰。本文將以 Python 的 Scrapy 框架為核心,構建一套具備擴展性、可維護性的 Taobao 爬蟲系統,涵蓋商品列表頁與詳情頁的爬取過程,並介紹常見優化技巧與資料庫整合方案。

本篇將適合有一定 Python 基礎的開發者,希望構建工程化數據抓取系統,並掌握 Scrapy 的實務應用。

Scrapy 實戰:高效爬取 Taobao 商品列表與詳情頁

一、Scrapy 專案初始化與結構說明

Scrapy 是一套以「非同步、高效、模組化」著稱的 Python 爬蟲框架,非常適合用於構建大型電商數據抓取專案。我們首先創建一個專案:

scrapy startproject taobao_spider

專案結構如下:

taobao_spider/

├── items.py # 定義數據模型

├── pipelines.py # 數據清洗與儲存

├── settings.py # 爬蟲設定參數

├── middlewares.py # 中介層設置(如 UA / Proxy)

└── spiders/

└── search_spider.py # 主爬蟲文件

每個模組都具備高度擴展性,支援自定義與重用。

二、商品列表頁解析與翻頁控制

Taobao 商品搜尋頁(如:https://s.taobao.com/search?q=耳機)採用了 AJAX 動態載入,商品資料以 JSON 格式嵌在頁面中。我們透過 Scrapy 發送 GET 請求並解析每一頁的商品 ID,進而生成詳情頁的請求。

基本翻頁邏輯:

# spiders/search_spider.py

import scrapy

import re

class TaobaoSearchSpider(scrapy.Spider):

name = 'taobao_search'

allowed_domains = ['s.taobao.com', 'item.taobao.com']

start_urls = []

def start_requests(self):

keyword = '耳機'

for page in range(1, 6): # 抓取前 5 頁

offset = (page - 1) * 44

url = f'https://s.taobao.com/search?q={keyword}&s={offset}'

yield scrapy.Request(url=url, callback=self.parse)

def parse(self, response):

item_ids = re.findall(r'"nid":"(\d+)"', response.text)

for nid in item_ids:

detail_url = f'https://item.taobao.com/item.htm?id={nid}'

yield scrapy.Request(url=detail_url, callback=self.parse_detail)

此處透過正則從搜尋頁 HTML 中擷取商品 nid,並組裝成詳情頁 URL 進行後續請求。

三、詳情頁爬取與多欄位資料提取

詳情頁為商品核心資訊的展示區域,包括標題、價格、店鋪、銷量、評價數等。不同商品可能頁面佈局稍有差異,因此解析時需具備容錯性與條件判斷。

解析邏輯如下:

def parse_detail(self, response):

def safe_get(selector):

return selector.get().strip() if selector else ''

title = safe_get(response.css('#J_Title .tb-main-title::attr(data-title)'))

price = safe_get(response.css('.tb-rmb-num::text'))

shop = safe_get(response.css('.tb-shop-name::text'))

sales = safe_get(response.css('#J_SellCounter::text'))

location = safe_get(response.css('.tb-deliveryAdd span::text'))

yield {

'title': title,

'price': price,

'shop': shop,

'sales': sales,

'location': location,

'url': response.url

}

為了提升穩定性,這裡設計了一個 safe_get 函式來避免因缺失節點導致的錯誤。

四、Pipeline 設計:資料存入 MongoDB

Scrapy 支援將抓取到的資料傳送至 pipelines.py 進行處理與儲存。以下是將資料寫入 MongoDB 的範例:

pipelines.py:

import pymongo

class MongoPipeline:

def open_spider(self, spider):

self.client = pymongo.MongoClient('localhost', 27017)

self.db = self.client['taobao_data']

self.col = self.db['products']

def close_spider(self, spider):

self.client.close()

def process_item(self, item, spider):

self.col.update_one(

{'title': item['title']},

{'$set': dict(item)},

upsert=True

)

return item

settings.py:啟用 pipeline

ITEM_PIPELINES = {

'taobao_spider.pipelines.MongoPipeline': 300,

}

透過 upsert=True,可避免資料重複寫入。

五、效能與穩定性優化技巧

爬取 Taobao 頁面時,需應對封鎖與速率限制,以下提供幾項關鍵優化建議:

1. 設定限速與並發數

# settings.py

DOWNLOAD_DELAY = 1.5

CONCURRENT_REQUESTS = 4

適度延時可降低被偵測風險。

2. User-Agent 與代理池

middlewares.py 中實現 User-Agent 隨機與代理池切換,可有效防止封鎖。

import random

class RandomUserAgentMiddleware:

USER_AGENTS = [

'Mozilla/5.0 (Windows NT 10.0; Win64; x64)...',

'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...'

]

def process_request(self, request, spider):

request.headers['User-Agent'] = random.choice(self.USER_AGENTS)

啟用:

DOWNLOADER_MIDDLEWARES = {

'taobao_spider.middlewares.RandomUserAgentMiddleware': 400,

}

3. 增量抓取策略

若資料已存在資料庫中,可根據商品 ID 或 URL 判斷是否跳過:

def process_item(self, item, spider):

exists = self.col.find_one({'url': item['url']})

if not exists:

self.col.insert_one(dict(item))

return item

4. 錯誤重試與日誌追蹤

可設定 Scrapy 內建參數來開啟自動重試與紀錄錯誤:

RETRY_ENABLED = True

RETRY_TIMES = 3

LOG_LEVEL = 'INFO'

六、小結與後續方向

本文透過 Scrapy 框架構建了一套涵蓋「搜尋列表解析」、「詳情頁抓取」、「資料入庫」、「性能優化」的完整 Taobao 商品爬蟲實作方案。

此爬蟲具備以下特點:

  • 工程化專案結構,易於擴展與維護

  • 使用 MongoDB 儲存資料,可靈活對接分析系統

  • 提供限速、UA 池、增量抓取等生產級設計

在後續應用中,可進一步拓展功能至:

  • 評價評論資料的抓取與情感分析

  • 商品歷史價格追蹤與比價系統

  • 結合 Redis / Kafka 實現分散式爬蟲架構

Scrapy 作為成熟的框架,配合適當的架構設計與優化手段,完全可勝任商業級電商資料抓取需求。

Articles related to APIs :

如您需要 Taobao API 可聯係我們:support@luckdata.com