Scrapy進階封裝(第三階段:多管道封裝,多文件存儲)

1.yield返回數據的原理?

為什么要用yield返回數據給管道?

  • 遍歷這個函數的返回值的時候,挨個把數據讀到內存,不會造成內存的瞬間占用過高,Python3中的rangepython2中的xrange同理。
  • scrapy是異步爬取,所以通過yield能夠將運行權限教給其他的協程任務去執行,這樣整個程序運行效果會更高。

注意點:解析函數中的yield能夠傳遞的對象只能是:BaseItemRequestdictNone

前置知識,關于數據的存儲

可以參考我另一篇文章python爬蟲之數據存儲_爬蟲代碼w是什么意思-CSDN博客

2.Mysql存儲管道封裝

第一步創建一個管道文件夾

咱們要用多管道,所以咱們不用自帶的pipelines.py文件,雖然可以寫在一個文件,但是如果寫多個導致代碼冗余。不好查看。

類名修改如下:

?第二步在setting.py設置開啟管道文件

按你的路徑修改

?數據越小,優先級越大

第四步設置管道

先下載? pip install pymsql

以豆瓣為例,這三個字段

?初始數據

    def __init__(self):# 數據庫連接信息self.host = '127.0.0.1'self.user = 'root'self.passwd = '12345'self.db = 'spider2'self.charset = 'utf8mb4'

鏈接數據庫

 def open_spider(self, spider):# 連接數據庫self.conn = pymysql.connect(host=self.host,user=self.user,passwd=self.passwd,db=self.db,charset=self.charset)self.cursor = self.conn.cursor()

注意open_spider是爬蟲開啟時自動運行,當前啟動的爬蟲對象,可以通過它獲取爬蟲的名稱、設置等信息。

建表,以爬蟲名稱為表名

 self.cursor = self.conn.cursor()# 根據爬蟲名字創建表table_name = spider.namecreate_table_sql = f"""CREATE TABLE IF NOT EXISTS {table_name} (id INT AUTO_INCREMENT PRIMARY KEY,title VARCHAR(255),rating VARCHAR(50),url VARCHAR(255))"""self.cursor.execute(create_table_sql)self.conn.commit()

?插入數據

    def process_item(self, item, spider):# 獲取爬蟲名字作為表名table_name = spider.name# 插入數據insert_sql = f"""INSERT INTO {table_name} (title, rating, url)VALUES (%s, %s, %s)"""self.cursor.execute(insert_sql, (item['title'], item['rating'], item['url']))self.conn.commit()return item

process_item?方法

作用:每當爬蟲抓取到一個數據項(item)時,該方法會被調用來處理這個數據項。這是管道的核心方法,用于對數據項進行清洗、驗證、存儲等操作。

return item 作用:返回處理后的 item,以便后續的管道可以繼續處理。如果拋出 DropItem 異常

?,則丟棄該數據項,不再傳遞給后續的管道。

        def close_spider(self, spider):# 關閉數據庫連接self.cursor.close()self.conn.close()

close_spider()在爬蟲關閉時被調用,主要用于清理資源,如關閉數據庫連接、文件等操作。

完整代碼如下:

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html# useful for handling different item types with a single interface
from itemadapter import ItemAdapterimport pymysql
class Mysql_Pipeline:def __init__(self):# 數據庫連接信息self.host = '127.0.0.1'self.user = 'root'self.passwd = '12345'self.db = 'spider2'self.charset = 'utf8mb4'def open_spider(self, spider):# 連接數據庫self.conn = pymysql.connect(host=self.host,user=self.user,passwd=self.passwd,db=self.db,charset=self.charset)self.cursor = self.conn.cursor()# 根據爬蟲名字創建表table_name = spider.namecreate_table_sql = f"""CREATE TABLE IF NOT EXISTS {table_name} (id INT AUTO_INCREMENT PRIMARY KEY,title VARCHAR(255),rating VARCHAR(50),url VARCHAR(255))"""self.cursor.execute(create_table_sql)self.conn.commit()def process_item(self, item, spider):# 獲取爬蟲名字作為表名table_name = spider.name# 插入數據insert_sql = f"""INSERT INTO {table_name} (title, rating, url)VALUES (%s, %s, %s)"""self.cursor.execute(insert_sql, (item['title'], item['rating'], item['url']))self.conn.commit()print('mysql插入成功')return itemdef close_spider(self, spider):# 關閉數據庫連接self.cursor.close()self.conn.close()

?結果如下:

?

3. MongoDB存儲管道封裝

直接創建管道

開啟管道

ITEM_PIPELINES = {'myspider.pipelines.Mysql_pipelines.Mysql_Pipeline': 300,'myspider.pipelines.MongoDB_piplines.MongoDBPipeline': 200,
}

還是以豆瓣三個字段為例

pip insatll pymongo

import pymongo
from scrapy import signalsclass MongoDBPipeline:def __init__(self):self.mongo_uri = 'mongodb://localhost:27017/'  # MongoDB 的 URI 地址self.mongo_db = 'spider'   # MongoDB 的數據庫名稱def open_spider(self, spider):# 在爬蟲啟動時執行,用于初始化操作,如建立 MongoDB 連接self.client = pymongo.MongoClient(self.mongo_uri)#自動創建數據庫self.db = self.client[self.mongo_db]def close_spider(self, spider):# 在爬蟲關閉時執行,用于清理操作,如關閉 MongoDB 連接self.client.close()def process_item(self, item, spider):# 處理每個數據項,將數據存儲到 MongoDB 中collection_name = spider.name  # 使用爬蟲名字作為集合名#自動創建表self.db[collection_name].insert_one(item)  # 將數據插入到集合中print('MongoDB插入成功!')#字典字典插入return item

?原理差不多一樣,鏈接數據庫,插入數據庫,關閉數據庫。

雙數據庫插入

結果如下:

mongodb?

?

mysql?

?

但如果只想插入其中一個數據庫

要么注釋return item,優先級設置高,這樣會拋出錯誤

要么注釋管道開啟

?最好的還是在爬蟲里重寫配置

    custom_settings = {'ITEM_PIPELINES': {'myspider.pipelines.MongoDB_piplines.MongoDBPipeline': 300,}}

這樣管道設置以爬蟲類為主,只插入mongodb

?

?4.文件管道封裝

圖片存儲

class FilePipeline:def process_item(self, item, spider):# getcwd(): 用于獲取當前工作目錄(Current Working Directory)的路徑#圖片下載if item.get("f_type"):if  item.get("f_type") == 'img':download_path = os.getcwd() + f'/img/'if not os.path.exists(download_path):os.mkdir(download_path)# 圖片保存image_name = item.get("title")image_content = item.get("content")if image_content:with open(download_path+f'{image_name}.jpg', "wb") as f:f.write(image_content)print("圖片保存成功: ", image_name)

一般用item.get("f_type")區分文件下載用os生成文件夾

圖片存儲一共就兩個參數,響應體和名字,這樣配置,

在爬蟲里重寫設置

  custom_settings = {'ITEM_PIPELINES': {'myspider.pipelines.File_piplines.FilePipeline': 300,}}

二次請求圖片url

以上有個小錯誤,把?item_img['title'] =item['title']改為item_img['title'] =item

?結果如下:

利用item.get("f_type")區分文件下載,文件管道可以封裝如下:

import os
import picklefrom itemadapter import ItemAdapterimport json
class FilePipeline:def process_item(self, item, spider):# getcwd(): 用于獲取當前工作目錄(Current Working Directory)的路徑#圖片下載if item.get("f_type"):if  item.get("f_type") == 'img':download_path = os.getcwd() + f'/img/'if not os.path.exists(download_path):os.mkdir(download_path)# 圖片保存image_name = item.get("title")image_content = item.get("content")if image_content:with open(download_path+f'{image_name}.jpg', "wb") as f:f.write(image_content)print("圖片保存成功: ", image_name)elif item.get("f_type") == 'txt':download_path = os.getcwd() + '/txt/'if not os.path.exists(download_path):os.mkdir(download_path)# 文本保存txt_name = item.get("title")txt_content = item.get("content")with open(download_path+f'{txt_name}.txt', 'a', encoding='utf-8') as f:f.write(txt_content + '\n')print('文本存儲成功')elif item.get("f_type") == 'json':download_path = os.getcwd() + '/json/'if not os.path.exists(download_path):os.mkdir(download_path)# 文本保存json_name = item.get("title")json_obj = itemwith open(download_path+f'{json_name}.json', 'a', encoding='utf-8') as file:file.write(json.dumps(json_obj, indent=2, ensure_ascii=False), )print('json存儲成功')elif item.get("f_type") == 'music':download_path = os.getcwd() + '/music/'if not os.path.exists(download_path):os.mkdir(download_path)# 文本保存music_name = item.get("title")music_content = item.get("content")with open(download_path+f'{music_name}.mp3', 'a', encoding='utf-8') as f:f.write(music_content + '\n')print('MP3存儲成功')else:print('無事發生')

包括mp3,文本,json,圖片等文件下載。?

?但是事實上,一個文件可以進行多次存儲,這也是用yield返回給管道的主要原因

    def parse(self, response, **kwargs):# scrapy的response對象可以直接進行xpathol_list = response.xpath('//ol[@class="grid_view"]/li')for ol in ol_list:# 創建一個數據字典item = {}# 利用scrapy封裝好的xpath選擇器定位元素,并通過extract()或extract_first()來獲取結果item['title'] = ol.xpath('.//div[@class="hd"]/a/span[1]/text()').extract_first()#標題item['content'] = ol.xpath('.//div[@class="bd"]/div/span[2]/text()').extract_first()#評分item['f_type'] = 'txt'yield itemitem['url'] = ol.xpath('.//a/@href').extract_first()#鏈接item['img_url'] = ol.xpath('.//img/@src').extract_first()item['f_type'] = 'json'yield item# yield itemyield scrapy.Request(url= item['img_url'] , headers=self.headers, callback=self.img_parse,cb_kwargs={"item":item['title']},meta={"meta":item})#自定義一個回調方法def img_parse(self, response,item):item_img = {'f_type':"img"}item_img['content'] = response.bodyitem_img['title'] =itemyield item_imgif __name__ == '__main__':cmdline.execute('scrapy crawl douban'.split())

以上三個yield,返回三次 ,分別是文本保存,json保存,圖片保存。

運行結果如下:

文本存儲評分

管道封裝到此一段落了。?

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

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

相關文章

證照大師 MAX 4.0安裝與基礎功能體驗(附流程演示)

軟件介紹 證照大師 MAX 4.0是一款功能強大的證件照制作軟件,專為滿足用戶不同場景下的證件照需求而設計。它整合了專業的照片處理技術和智能化的操作系統,提供了自動摳圖、尺寸調整、美顏處理、批量處理以及格式轉換等多種功能。該軟件用戶界面簡潔明快…

RK3568-適配mipi屏幕觸摸和顯示

1.1 適配mipi屏幕觸摸 gt9xx_lvds: gt9xx-lvds5d {compatible "goodix,gt9xx";reg <0x5d>;pinctrl-names "default";pinctrl-0 <&touch_gpio>;touch-gpio <&gpio1 RK_PA4 IRQ_TYPE_LEVEL_LOW>;reset-gpio <&gpio1…

ICME 2025音頻編碼器能力挑戰賽Workshop即將舉辦!

IEEE International Conference on Multimedia and Expo 2025&#xff08;ICME 2025&#xff09; 將于 6月30日至7月4日在法國南特舉行。作為全球多媒體領域的頂級會議之一&#xff0c;ICME 2025 匯聚全球頂尖學者與產業專家&#xff0c;聚焦人工智能驅動的多媒體技術&#xff…

物奇微WQ5007A上手指南

一、獲取SDK 需要與物奇微電子股份有限公司簽訂NDA協議才會提供SDK。 二、搭建開發環境 SDK里包含了編譯工具、開發文檔、源碼。在windows系統下搭建開發環境&#xff1a; 1、安裝交叉編譯工具 將\wuqi_sdk\tools\riscv64-unknown-elf-gcc-10.2.0-windows.zip文件解壓到任…

[論文閱讀] 人工智能 + 軟件工程 | LLM在單元測試中的應用:系統性綜述與未來展望

LLM在單元測試中的應用&#xff1a;系統性綜述與未來展望 論文信息 arXiv:2506.15227 Large Language Models for Unit Testing: A Systematic Literature Review Quanjun Zhang, Chunrong Fang, Siqi Gu, Ye Shang, Zhenyu Chen, Liang Xiao Subjects: Software Engineering …

數據重疊對CLIP零樣本能力影響CLIP論文圖17筆記

這兩張圖表&#xff08;圖17左、右圖&#xff09;是CLIP論文中驗證“數據重疊是否影響CLIP零樣本能力”的關鍵證據&#xff0c;核心是通過**“數據重疊分析”排除CLIP“作弊”嫌疑**&#xff08;即CLIP的高零樣本準確率是否因為“見過測試集圖像”&#xff09;。下面用“先看懂…

996引擎-假人系統

996引擎-假人系統 lua 假人問題添加假人名字列表打開M2設置假人參考資料 lua 假人問題 添加假人名字列表 假人名字列表 Mir200\Envir\DummyNameList.txt 打開M2設置假人 【選項】>【假人設置】 參考資料 假人系統

Rk3568驅動開發_Key驅動_13

設備樹配置 key{compatible "alientek,key";pinctrl-0 <&key_gpio>;pinctrl-names "alientek,key";key-gpio <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;status "okay";};配置信息方便后面直接引用&#xff1a; // Narnat 2025…

參展回顧 | AI應用創新場景:數據分析助手ChatBI、璞公英教學平臺亮相2025四川國際職教大會暨產教融合博覽會

2025年6月11日-13日&#xff0c;以“數字賦能產教融合&#xff0c;創新驅動技能未來”為主題的2025四川國際職業教育大會暨產教融合博覽會在成都盛大開幕。璞華聯合百度共同參展&#xff0c;并攜旗下創新產品ChatBI數據分析助手、璞公英教學平臺重磅亮相&#xff0c;憑借前沿的…

動態規劃之01背包問題

動態規劃算法 動態規劃算法介紹 動態規劃(Dynamic Programming)算法的核心思想是&#xff1a;將大問題劃分為小問題進行解決&#xff0c;從而一步步獲取最優解的處理算法動態規劃算法與分治法類似&#xff0c;其基本思想也是將待解決問題分解成若干個子問題&#xff0c;先求解…

人大金倉新建用戶,并且賦值查詢權限

-- 1. 創建用戶 visitor&#xff0c;并且設置密碼 CREATE USER visitor WITH PASSWORD 1234qwer; -- 2. 授予該用戶連接到數據庫 "yonbip_db" 的權限 GRANT CONNECT ON DATABASE yonbip_db TO visitor; -- 3. 假設你要讓 visitor 查詢的模式是 public&#xff08;或…

學習筆記丨信號處理新趨勢:量子計算將如何顛覆傳統DSP?

在算力需求爆炸式增長的今天&#xff0c;傳統數字信號處理&#xff08;DSP&#xff09;芯片正面臨物理極限的嚴峻挑戰。當經典計算機架構在摩爾定律的黃昏中掙扎時&#xff0c;量子計算正以顛覆性姿態崛起&#xff0c;準備重新定義信號處理的未來圖景。 目錄 傳統DSP的瓶頸&am…

react day.js使用及經典場景

簡介 Day.js 是一個輕量級的 JavaScript 日期庫&#xff0c;它提供了簡單易用的 API 來處理日期和時間。以及更加輕量級&#xff0c;并且具有更快的性能。 安裝 npm install dayjs 使用 import dayjs from "dayjs";dayjs().format("YYYY-MM-DD HH:mm:ss&qu…

【機器學習深度學習】線性回歸

目錄 一、定義 二、舉例說明 三、 數學形式 四、 訓練過程&#xff08;機器怎么學會這條線&#xff1f;&#xff09; 五、在 PyTorch 中怎么實現線性回歸&#xff1f; 六、如果你學懂了線性回歸&#xff0c;你也能理解這些 七、綜合應用&#xff1a;線性回歸示例 7.1 執…

如何在 Manjaro Linux 上安裝 .NET Core

.NET 是一個開源的開發框架平臺,可在所有流行的操作系統(如 Windows、Linux 和 macOS)上免費使用和安裝。它是跨平臺的,是主要由微軟員工在 .NET 基金會下開發的專有 .NET Framework 的繼承者。.NET 是一個統一的平臺,用于開發各種操作系統上的軟件,如 Web、移動、桌面應…

Mysql解惑(一)

使用 or 可能不走索引 使用 union替代 使用in&#xff0c;可能不走索引 如果優化&#xff1a; 臨時表強制索引exists代替

基于機器學習的側信道分析(MLSCA)Python實現(帶測試)

一、MLSCA原理介紹 基于機器學習的側信道分析(MLSCA)是一種結合傳統側信道分析技術與現代機器學習算法的密碼分析方法。該方法通過分析密碼設備運行時的物理泄漏信息(如功耗、電磁輻射等)&#xff0c;利用機器學習模型建立泄漏數據與密鑰信息之間的關聯模型&#xff0c;從而實…

【LLM】位置編碼

【LLM】位置編碼 1 絕對位置嵌入為什么用 1000 0 2 t d 10000^{\frac{2t}{d}} 10000d2t?? 2 相對位置嵌入2.1 Shaw等人的方法&#xff08;2018&#xff09;2.2 Dai等人的方法&#xff08;2019&#xff09;2.3 Raffel 等人的方法&#xff08;2020&#xff09;2.4 He 等人的方法…

Java 根據分組key構建合并數據集

文章目錄 前言背景總結 前言 請各大網友尊重本人原創知識分享&#xff0c;謹記本人博客&#xff1a;南國以南i、 提示&#xff1a;以下是本篇文章正文內容&#xff0c;下面案例可供參考 背景 Java 需要返回一組數據供前端展示&#xff0c;獲取到的數據格式如下&#xff1a; …

Linux平臺Oracle開機自啟動設置

網上和官方文檔已經有不少介紹如何設置開機啟動Oracle實例的文章(Linux平臺)&#xff0c;不過以sysvinit和service這種方式居多。最近遇到了UAT環境的服務器打補丁后需要重啟服務器的情況&#xff0c; 需要DBA去手工啟動Oracle實例的情形&#xff0c;和同事討論&#xff0c;決定…