使用 Scrapy 框架定制爬蟲中間件接入淘寶 API 采集商品數據

一、引言

在電商數據分析、市場調研等領域,獲取淘寶平臺上的商品數據是一項常見需求。淘寶提供了 API 接口,允許開發者通過授權的方式獲取商品信息。本文將介紹如何使用 Scrapy 框架定制爬蟲中間件,實現對淘寶?API 的接入,從而高效地采集商品數據。

二、淘寶 API 概述

淘寶提供了豐富的 API 接口,涵蓋商品、交易、用戶、營銷等多個領域。對于商品數據采集,常用的 API 包括:

  • taobao.search:搜索商品列表
  • taobao.item.get:獲取單個商品詳情
  • taobao.cats.get:獲取商品分類
  • taobao.props.get:獲取商品屬性

使用淘寶 API 需要先注冊賬號并獲取 ApiKey和 ApiSecret。同時,API 調用有頻率限制,需要合理控制請求速度。

三、Scrapy 框架與中間件
import logging
import time
import random
import hashlib
import hmac
import json
from urllib.parse import urlencode
import requests
from scrapy import signals
from scrapy.exceptions import NotConfigured, IgnoreRequestclass TaobaoAPIMiddleware:"""淘寶API爬蟲中間件,處理API請求和響應"""def __init__(self, app_key, app_secret, api_url, rate_limit, retry_times):self.app_key = app_keyself.app_secret = app_secretself.api_url = api_urlself.rate_limit = rate_limitself.retry_times = retry_timesself.request_count = 0self.last_reset_time = time.time()self.logger = logging.getLogger(__name__)@classmethoddef from_crawler(cls, crawler):"""從配置中獲取中間件設置"""app_key = crawler.settings.get('TAOBAO_APP_KEY')app_secret = crawler.settings.get('TAOBAO_APP_SECRET')api_url = crawler.settings.get('TAOBAO_API_URL', 'https://eco.taobao.com/router/rest')rate_limit = crawler.settings.getint('TAOBAO_RATE_LIMIT', 500)  # 默認500次/小時retry_times = crawler.settings.getint('TAOBAO_RETRY_TIMES', 3)  # 默認重試3次if not app_key or not app_secret:raise NotConfigured("淘寶API配置缺失:TAOBAO_APP_KEY 和 TAOBAO_APP_SECRET")middleware = cls(app_key, app_secret, api_url, rate_limit, retry_times)crawler.signals.connect(middleware.spider_closed, signal=signals.spider_closed)return middlewaredef process_request(self, request, spider):"""處理API請求,生成簽名并發送"""# 檢查是否為淘寶API請求if not request.meta.get('taobao_api', False):return None# 檢查速率限制self._check_rate_limit()# 構建API請求參數method = request.meta.get('taobao_method')if not method:self.logger.error("淘寶API請求缺少方法名:taobao_method")raise IgnoreRequestparams = self._build_common_params()params.update({'method': method,**request.meta.get('taobao_params', {})})# 生成簽名params['sign'] = self._generate_sign(params)try:# 發送API請求response = requests.post(self.api_url,data=params,timeout=30)response.raise_for_status()# 解析JSON響應result = response.json()request.meta['api_result'] = result# 檢查API返回狀態if not self._check_api_success(result):error_code = result.get('error_response', {}).get('code')error_msg = result.get('error_response', {}).get('msg')self.logger.warning(f"淘寶API返回錯誤: {error_code} - {error_msg}")# 如果是限流錯誤,暫停一段時間if error_code in ('isp.over-quota', 'isp.access-control'):self.logger.warning("API請求達到限流閾值,暫停60秒")time.sleep(60)# 重試機制retry_times = request.meta.get('taobao_retry_times', 0)if retry_times < self.retry_times:self.logger.info(f"準備重試API請求,當前重試次數: {retry_times + 1}")new_request = request.copy()new_request.dont_filter = Truenew_request.meta['taobao_retry_times'] = retry_times + 1# 隨機延遲后重試time.sleep(random.uniform(1, 3))return new_requestelse:self.logger.error("API請求重試次數已達上限")raise IgnoreRequestexcept requests.exceptions.RequestException as e:self.logger.error(f"API請求發生異常: {str(e)}")# 異常情況下的重試邏輯retry_times = request.meta.get('taobao_retry_times', 0)if retry_times < self.retry_times:self.logger.info(f"準備重試API請求,當前重試次數: {retry_times + 1}")new_request = request.copy()new_request.dont_filter = Truenew_request.meta['taobao_retry_times'] = retry_times + 1# 指數退避策略time.sleep(2 ** retry_times + random.random())return new_requestelse:self.logger.error("API請求重試次數已達上限")raise IgnoreRequest# 處理正常響應return Nonedef _build_common_params(self):"""構建API公共參數"""return {'app_key': self.app_key,'format': 'json','v': '2.0','sign_method': 'hmac','timestamp': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}def _generate_sign(self, params):"""生成API請求簽名"""# 排序參數sorted_params = sorted(params.items(), key=lambda x: x[0])# 拼接參數string_to_sign = self.app_secretfor k, v in sorted_params:string_to_sign += f"{k}{v}"string_to_sign += self.app_secret# HMAC-SHA1加密sign = hmac.new(self.app_secret.encode('utf-8'),string_to_sign.encode('utf-8'),hashlib.sha1).hexdigest().upper()return signdef _check_api_success(self, result):"""檢查API響應是否成功"""if 'error_response' in result:return False# 根據具體API調整檢查邏輯method_name = result.get('method')if method_name:# 例如:taobao.items.list.get 返回值檢查if method_name == 'taobao.items.list.get' and 'items_list_response' in result:return True# 其他API方法的檢查邏輯...return Truedef _check_rate_limit(self):"""檢查API請求速率限制"""current_time = time.time()# 如果已經過了1小時,重置計數器if current_time - self.last_reset_time > 3600:self.request_count = 0self.last_reset_time = current_time# 檢查是否超過速率限制if self.request_count >= self.rate_limit:wait_time = 3600 - (current_time - self.last_reset_time)self.logger.warning(f"達到API速率限制,等待{wait_time:.2f}秒")time.sleep(wait_time)# 重置計數器self.request_count = 0self.last_reset_time = current_time# 增加請求計數self.request_count += 1def spider_closed(self, spider):"""爬蟲關閉時的清理工作"""self.logger.info("淘寶API中間件: 爬蟲已關閉")    

Scrapy 是一個為了爬取網站數據、提取結構性數據而編寫的應用框架。它可以應用在數據挖掘、信息處理或存儲歷史數據等一系列的程序中。

Scrapy 的架構中,中間件是一個很重要的組件,分為下載中間件 (Downloader Middleware) 和爬蟲中間件 (Spider Middleware)。下載中間件可以攔截請求和響應,進行預處理;爬蟲中間件則可以處理爬蟲的輸入 (響應) 和輸出 (請求)。

在接入淘寶 API 的場景中,我們可以定制下載中間件,專門處理 API 請求的簽名生成、速率控制、錯誤重試等邏輯,使爬蟲代碼更加簡潔和可維護。

四、定制淘寶 API 中間件

下面是一個完整的淘寶 API 中間件實現,它負責處理 API 請求的簽名生成、速率控制和錯誤重試:

[中間件代碼見上面 doubaocanvas 中的 taobao_middleware.py]

這個中間件具有以下功能:

  1. 參數處理:自動構建 API 請求的公共參數,并根據不同 API 方法添加特定參數
  2. 簽名生成:按照淘寶 API 的要求,生成 HMAC-SHA1 簽名
  3. 速率控制:根據 API 的 QPS 限制,自動控制請求頻率,避免被限流
  4. 錯誤處理:捕獲網絡異常和 API 返回的錯誤,實現智能重試
  5. 數據解析:解析 API 返回的 JSON 數據,并傳遞給爬蟲處理
五、創建淘寶商品爬蟲

有了中間件之后,我們可以創建一個簡單的爬蟲來使用這個中間件:

[爬蟲代碼見上面 doubaocanvas 中的 taobao_spider.py]

這個爬蟲的工作流程是:

  1. 初始化多個搜索關鍵詞,每個關鍵詞生成多頁請求
  2. 通過中間件發送 API 請求獲取商品列表
  3. 解析 API 返回的商品數據,提取需要的字段
  4. 生成 Item 對象傳遞給管道處理
六、數據模型與處理管道

為了存儲爬取到的商品數據,我們需要定義數據模型和處理管道:

[數據模型和管道代碼見上面 doubaocanvas 中的 items.py 和 pipelines.py]

這里我們使用 MongoDB 作為數據存儲,管道會將商品數據去重并存儲到 MongoDB 中。你也可以根據需要擴展管道,添加數據清洗、驗證或導出到其他存儲系統的功能。

七、項目配置

最后,我們需要在 Scrapy 項目的設置文件中配置中間件和其他參數:

[配置代碼見上面 doubaocanvas 中的 settings.py]

在配置文件中,需要填入你的淘寶 API 的 ApiKey 和 ApiSecret,以及 MongoDB 的連接信息。同時,可以根據 API 的訪問權限和性能要求,調整請求并發數、下載延遲等參數。

八、使用與優化建議
  1. 運行爬蟲:在項目根目錄下執行命令?scrapy crawl taobao?即可啟動爬蟲

  2. API 權限:不同的 API 需要不同的權限,需要申請相應的權限

  3. 速率控制:中間件已經實現了基本的速率控制,但不同 API 的 QPS 限制不同,需要根據實際情況調整

  4. 數據量控制:淘寶 API 通常對單次請求返回的數據量有限制,可以通過分頁獲取更多數據

  5. 異常處理:中間件已經包含了基本的異常處理和重試機制,但在實際使用中可能需要根據具體情況調整

  6. 數據存儲:MongoDB 適合存儲結構靈活的商品數據,也可以根據需要改用其他數據庫

通過以上步驟,你可以建立一個高效、穩定的淘寶商品數據采集系統。定制的中間件使 API 請求處理邏輯與爬蟲業務邏輯分離,提高了代碼的可維護性和復用性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/91348.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/91348.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/91348.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Jmeter全局變量跨線程組的使用

一、線程組1中從數據庫中查詢到字段值二、BeanShell取樣器中設置為全局變量#為什么說props.put("Out1",Out);其實是設置Out1為Jmeter的屬性了呢&#xff1f; 因為在后面的調試取樣器運行結果中&#xff0c;會發現如果只打開顯示變量開關&#xff0c;是看不到Out1運行…

前端技術棧詳解

前端技術棧是指構建現代Web應用程序所需的一系列技術和工具的集合。以下是當前主流前端技術棧的詳細解析&#xff1a; 一、核心基礎技術 1. HTML5 作用&#xff1a;網頁內容的結構化標記關鍵特性&#xff1a; 語義化標簽&#xff08;<header>, <section>, <arti…

Git Pull 時遇到 Apply 和 Abort 選項?詳解它們的含義與應對策略

在使用 Git 進行團隊協作時&#xff0c;git pull 是最常用的命令之一&#xff0c;用于拉取遠程倉庫的最新代碼并合并到本地分支。但有時執行 git pull 后&#xff0c;Git 會提示 ?Apply&#xff08;應用&#xff09;?? 和 ?Abort&#xff08;中止&#xff09;?? 兩個選項…

暑期算法訓練.11

目錄 47. 力扣203 移除鏈表元素 47.1 題目解析&#xff1a; ?編輯 47.2 算法思路&#xff1a; 47.3 代碼演示&#xff1a; ?編輯 48. 力扣2.兩數相加 48.1 題目解析&#xff1a; ?編輯 48.2 算法思路; 48.3 代碼演示&#xff1a; 48.4 總結反思&#xff1a; …

nl2sql grpo強化學習訓練,加大數據量和輪數后,準確率沒提升,反而下降了,如何調整

在NL2SQL任務中使用GRPO強化學習訓練時&#xff0c;增加數據量和訓練輪數后準確率下降&#xff0c;通常是由過擬合、訓練不穩定、獎勵函數設計不合理、數據質量問題或探索-利用失衡等原因導致的。以下是具體的診斷思路和調整策略&#xff0c;幫助定位問題并優化性能&#xff1a…

PHP/Java/Python實現:如何有效防止惡意文件上傳

文章目錄 木馬病毒防范:文件上傳如何徹底防止偽造文件類型 引言 一、文件類型偽造的原理與危害 1.1 常見偽造手段 1.2 潛在危害 二、防御體系設計 2.1 防御架構 三、核心防御技術實現 3.1 服務端驗證實現 3.1.1 文件內容檢測(Python示例) 3.1.2 擴展名與內容雙重驗證(Java示…

SpringBoot系列之基于Redis的分布式限流器

SpringBoot系列之基于Redis的分布式限流器 SpringBoot 系列之基于 Redis 的分布式限流器 圖文并茂,代碼即拷即用,支持 4 種算法(固定窗口 / 滑動窗口 / 令牌桶 / 漏桶) 一、為什么要用分布式限流? 單機 Guava-RateLimiter 在集群下會 各玩各的,流量漂移,無法全局控量。…

面試遇到的問題2

Redisson的看門狗相關問題 首先要明確一點&#xff0c;看門狗機制的使用方式是&#xff1a;在加鎖的時候不加任何參數&#xff0c;也就是&#xff1a; RLock lock redisson.getLock("myLock"); try {lock.lock(); // 阻塞式加鎖// 業務邏輯... } finally {lock.unl…

Linux—進程概念與理解

目錄 1.馮諾依曼體系結構 小結&#xff1a; 2.操作系統 概念&#xff1a; 結構示意圖&#xff1a; 理解操作系統&#xff1a; 用戶使用底層硬件層次圖&#xff1a;?編輯 3.進程 概念 結構示意圖 task_ struct內容分類 典型用法示例 觀察進程: 了解 PID PPID 查…

LeetCode 面試經典 150_數組/字符串_買賣股票的最佳時機(7_121_C++_簡單)(貪心)

LeetCode 面試經典 150_數組/字符串_買賣股票的最佳時機&#xff08;7_121_C_簡單&#xff09;題目描述&#xff1a;輸入輸出樣例&#xff1a;題解&#xff1a;解題思路&#xff1a;思路一&#xff08;貪心算法&#xff09;&#xff1a;代碼實現代碼實現&#xff08;思路一&…

Ubuntu 18.04 repo sync報錯:line 0: Bad configuration option: setenv

repo sync時報 line 0: Bad configuration option: setenv因為 Ubuntu 18.04 默認的 openssh-client 是 7.6p1&#xff0c;還不支持 setenv&#xff0c;但是.repo/repo/ssh.py 腳本中明確地傳入了 SetEnv 參數給 ssh&#xff0c;而你的 OpenSSH 7.6 不支持這個參數。需要按如下…

bug記錄-stylelint

BUG1不支持Vue文件內聯style樣式解決&#xff1a; "no-invalid-position-declaration": null

前端開發(HTML,CSS,VUE,JS)從入門到精通!第一天(HTML5)

一、HTML5 簡介1&#xff0e;HTML全稱是 Hyber Text Markup Language&#xff0c;超文本標記語言&#xff0c;它是互聯網上應用最廣泛的標記語言&#xff0c;簡單說&#xff0c;HTML 頁面就等于“普通文本HTML標記&#xff08;HTML標簽&#xff09;“。2&#xff0e;HTML 總共經…

智慧收銀系統開發進銷存:便利店、水果店、建材與家居行業的—仙盟創夢IDE

在數字化轉型的浪潮中&#xff0c;收銀系統已不再局限于簡單的收款功能&#xff0c;而是成為企業進銷存管理的核心樞紐。從便利店的快消品管理到建材家居行業的大宗商品調度&#xff0c;現代收銀系統通過智能化技術重塑了傳統商業模式。本文將深入探討收銀系統在不同行業進銷存…

三維掃描相機:工業自動化的智慧之眼——遷移科技賦能智能制造新紀元

在當今工業4.0時代&#xff0c;自動化技術正重塑生產流程&#xff0c;而核心工具如三維掃描相機已成為關鍵驅動力。作為工業自動化領域的“智慧之眼”&#xff0c;三維掃描相機通過高精度三維重建能力&#xff0c;解決了傳統制造中的效率瓶頸和精度痛點。遷移科技&#xff0c;自…

Jmeter的元件使用介紹:(九)監聽器詳解

監聽器主要是用來監聽腳本執行的取樣器結果。Jmeter的默認監聽器有&#xff1a;查看結果樹、聚合報告、匯總報告、用表格查看結果&#xff0c;斷言結果、圖形結果、Beanshell監聽器、JSR223監聽器、比較斷言可視化器、后端監聽器、郵件觀察器&#xff0c;本文介紹最常用的監聽器…

聯通元景萬悟 開源,搶先體驗!!!

簡介&#xff1a; 元景萬悟智能體平臺是一款面向企業級場景的一站式、商用license友好的智能體開發平臺&#xff0c;是業界第一款go語言&#xff08;后端&#xff09;開發的智能體開發平臺&#xff08;7月19日&#xff09;&#xff0c;coze studio開源是7月26日&#xff0c;同時…

Git之本地倉庫管理

一.什么是Git在學習工作中&#xff0c;我們經常會遇到改文檔的場景。一個文檔可能會被我們修改多次&#xff0c;而最終真正使用的可能是最先的幾版。而如果我們直接在原文檔上修改&#xff0c;就會導致無法找到最先的幾次。這也就導致我們要對我們所有的版本進行維護&#xff0…

Go再進階:結構體、接口與面向對象編程

&#x1f680; Go再進階&#xff1a;結構體、接口與面向對象編程 大家好&#xff01;在前兩篇文章中&#xff0c;我們深入學習了Go語言的流程控制語句以及數組和切片的使用并且還對Go 語言的核心知識點進行了補充講解&#xff0c;這些知識讓我們能夠編寫出更為復雜和靈活的程序…

Python入門第六課:現代開發與前沿技術

異步編程(asyncio) 1. 協程基礎 import asyncio import time# 定義協程函數 async def say_after(delay, message):await asyncio.sleep(delay)print(message)# 主協程 async def main():print(f"開始時間: {time.strftime(%X)}")# 順序執行await say_after(2, 你…