一、簡介 官網:https:///#/ feapder是一款上手簡單,功能強大的Python爬蟲框架,內置AirSpider、Spider、TaskSpider、BatchSpider四種爬蟲解決不同場景的需求,但像任何工具一樣,它也有其優(yōu)點和缺點。以下是 feapder 的一些優(yōu)缺點: 優(yōu)點: - 分布式爬取支持:feapder 支持分布式爬取,可以在多臺機器上同時運行,提高了爬取效率。
- 多種爬取方式:支持普通請求爬取、Selenium 動態(tài)渲染爬取、API 調用、抓包分析等多種爬取方式,適用于不同類型的網站。
- 靈活的配置:可以通過配置文件或代碼來定義爬取任務的規(guī)則,包括起始 URL、爬取間隔、解析規(guī)則等。
- 強大的去重功能:支持多種去重方式,確保數(shù)據(jù)的唯一性,避免重復爬取。
- 內建的數(shù)據(jù)存儲和輸出:支持將爬取的數(shù)據(jù)存儲到文件、數(shù)據(jù)庫(支持 MySQL、MongoDB 等)或其他數(shù)據(jù)存儲介質。
- 動態(tài)代理支持:可以集成動態(tài)代理,應對需要翻墻或 IP 限制的網站。
- 內建的分布式調度器:提供了一個簡單易用的分布式調度器,靈活管理和調度爬取任務。
- 自動化任務管理:提供了完善的任務管理機制,包括監(jiān)控任務狀態(tài)、自動重試、任務日志等功能。
- 并發(fā)請求支持:可以配置并發(fā)數(shù),實現(xiàn)同時發(fā)送多個請求,提高爬取效率。
- 支持 JavaScript 渲染:通過集成 Selenium,可以處理動態(tài)渲染的頁面,支持爬取 JavaScript 渲染的內容。
- 支持斷點續(xù)爬、監(jiān)控報警、瀏覽器渲染等功能。
缺點: - 學習曲線:對于新手來說,可能需要一些時間來學習和理解框架的使用方法和配置。
- 對于小規(guī)模任務:如果只需要爬取少量數(shù)據(jù)或者只需簡單的爬取任務,可能會覺得框架功能較為復雜,使用成本較高。
- 依賴:feapder 依賴于 Python 環(huán)境,需要安裝相關依賴庫。
- 可能需要自定義解析規(guī)則:對于特定的網站,可能需要編寫自定義的解析規(guī)則,這需要一定的編程能力。
二、安裝 pip install feapder #精簡版,不支持瀏覽器渲染、不支持基于內存去重、不支持入庫mongopip install 'feapder[render]' #瀏覽器渲染版,不支持基于內存去重、不支持入庫mongopip install 'feapder[all]' #完整版,支持所有功能
三、命令 - 查看支持的命令行:打開命令行窗口,輸入feapder
使用:feapder <command> [options] [args] create:創(chuàng)建項目 shell:交互式環(huán)境 zip:壓縮項目,項目打包 retry:重試
- 查看某個命令行:feapder -h
- 創(chuàng)建項目:feapder create
-h, --help 查看create命令行幫助信息,feapder create -h-p , --project 創(chuàng)建項目,feapder create -p <project_name>-s , --spider 創(chuàng)建爬蟲,feapder create -s <spider_name>-i , --item 創(chuàng)建item ,feapder create -i <table_name> 支持模糊匹配 如 feapder create -i %table_name%-t , --table 根據(jù)json創(chuàng)建表,feapder create -t <table_name>-init 創(chuàng)建__init__.py,會自動引入當前目錄下的所有py文件到__all__中,feapder create -init-j, --json 創(chuàng)建json,feapder create -j-sj, --sort_json 創(chuàng)建有序json,feapder create -sj-c, --cookies 創(chuàng)建cookie--params 解析地址中的參數(shù)--setting 創(chuàng)建全局配置文件feapder create --setting# feapder create -i spider_data --host localhost --db feapder --username feapder --password feapder123--host mysql 連接地址,常和-i搭配使用,也可直接在setting文件配置mysql配置--port mysql 端口,常和-i搭配使用,也可直接在setting文件配置mysql配置--username mysql 用戶名,常和-i搭配使用,也可直接在setting文件配置mysql配置--password mysql 密碼,常和-i搭配使用,也可直接在setting文件配置mysql配置--db mysql 數(shù)據(jù)庫名,常和-i搭配使用,也可直接在setting文件配置mysql配置
- 交互式環(huán)境:feapder shell
-h, --help 查看shell命令行幫助信息,feapder shell -h -u , --url 請求指定地址, feapder shell --url http://www.spidertools.cn/ -c, --curl 執(zhí)行curl,調試響應, feapder shell --curl http://www.spidertools.cn/
- 壓縮項目,項目打包:feapder zip
-h, --help 查看shell命令行幫助信息,feapder zip -h-i 忽略文件,逗號分隔,支持正則-I 忽略文件夾,逗號分隔,支持正則-o 輸出路徑,默認為當前目錄
- 重試:feapder retry
-h, --help 查看shell命令行幫助信息,feapder retry -h-r , --request 重試失敗的request 如 feapder retry --request <redis_key>-i , --item 重試失敗的item 如 feapder retry --item <redis_key>
四、內置爬蟲模板 - AirSpider:AirSpider是輕量爬蟲,學習成本低。面對一些數(shù)據(jù)量較少,無需斷點續(xù)爬,無需分布式采集的需求,可采用此爬蟲。
- Spider:Spider是基于redis的分布式爬蟲,適用于海量數(shù)據(jù)采集,支持斷點續(xù)爬、爬蟲報警、數(shù)據(jù)自動入庫等功能
- TaskSpider:TaskSpider是任務分布式爬蟲,內部封裝了取種子任務的邏輯,內置支持從redis或者mysql獲取任務,也可通過自定義實現(xiàn)從其他來源獲取任務
- BatchSpider:BatchSpider是分布式批次爬蟲,對于需要周期性采集的數(shù)據(jù),優(yōu)先考慮使用本爬蟲。
五、Item 類型 item為與數(shù)據(jù)庫表的映射,與數(shù)據(jù)入庫的邏輯相關。 在使用此命令前,需在數(shù)據(jù)庫中創(chuàng)建好表,且setting.py中配置好數(shù)據(jù)庫連接地址 Item和UpdateItem區(qū)別,UpdateItem可以根據(jù)數(shù)據(jù)庫的唯一索引,插入數(shù)據(jù)時發(fā)現(xiàn)數(shù)據(jù)已存在,則更新數(shù)據(jù),而item不會更新 #創(chuàng)建douban表CREATE TABLE IF NOT EXISTS douban( id INT AUTO_INCREMENT, title VARCHAR(255), rating FLOAT, quote VARCHAR(255), intro TEXT, PRIMARY KEY(id) )
- Item:feapder create -i douban 選擇Item創(chuàng)建
from feapder import Itemclass DoubanItem(Item): ''' This class was generated by feapder command: feapder create -i douban ''' __table_name__ = 'douban' def __init__(self, *args, **kwargs): super().__init__(**kwargs) # self.id = None self.intro = None self.quote = None self.rating = None self.title = None
- Item 支持字典賦值:若item字段過多,不想逐一賦值,可選擇支持字典賦值的Item類型創(chuàng)建,feapder create -i douban 選擇Item 支持字典賦值
from feapder import Itemclass DoubanItem(Item): ''' This class was generated by feapder command: feapder create -i douban 1 ''' __table_name__ = 'douban' def __init__(self, *args, **kwargs): super().__init__(**kwargs) # self.id = kwargs.get('id') self.intro = kwargs.get('intro') self.quote = kwargs.get('quote') self.rating = kwargs.get('rating') self.title = kwargs.get('title')
- UpdateItem:feapder create -i douban 選擇UpdateItem創(chuàng)建
from feapder import UpdateItemclass DoubanItem(UpdateItem): ''' This class was generated by feapder command: feapder create -i douban ''' __table_name__ = 'douban' def __init__(self, *args, **kwargs): super().__init__(**kwargs) # self.id = None self.intro = None self.quote = None self.rating = None self.title = None
- UpdateItem 支持字典賦值:若item字段過多,不想逐一賦值,可選擇支持字典賦值的UpdateItem類型創(chuàng)建,feapder create -i douban 選擇UpdateItem 支持字典賦值
from feapder import UpdateItemclass DoubanItem(UpdateItem): ''' This class was generated by feapder command: feapder create -i douban 1 ''' __table_name__ = 'douban' def __init__(self, *args, **kwargs): super().__init__(**kwargs) # self.id = kwargs.get('id') self.intro = kwargs.get('intro') self.quote = kwargs.get('quote') self.rating = kwargs.get('rating') self.title = kwargs.get('title')
六、feapder.AirSpider 模塊,繼承了BaseParser、Thread - feapder.AirSpider(thread_count):創(chuàng)建AirSpider對象,thread_count開啟線程數(shù)量
- feapder.AirSpider.join(timeout):等待所有線程完成。timeout 參數(shù)表示最長等待時間(秒),超過該時間將不再等待
- feapder.AirSpider.stop_spider():停止爬蟲
- feapder.AirSpider.run():運行爬蟲
- feapder.AirSpider.all_thread_is_done():檢查所有線程是否已經完成任務,如果完成返回 True,否則返回 False
- feapder.AirSpider.distribute_task():分配任務
- feapder.AirSpider.to_DebugSpider():用于將當前的爬蟲實例轉換為調試模式下的爬蟲實例
七、feapder.Spider 模塊,繼承了BaseParser、Scheduler - feapder.Spider(redis_key=redis_key,..., wait_lock=wait_lock, **kwargs):創(chuàng)建Spider對象
redis_key:用于任務調度的 Redis 鍵名。任務隊列中的任務將根據(jù)此鍵名進行調度和分發(fā)。thread_count:爬蟲的線程數(shù)。指定同時運行的線程數(shù)量,用于并發(fā)地處理任務。begin_callback:爬蟲開始時調用的回調函數(shù)。可以指定一個函數(shù),在爬蟲開始時執(zhí)行特定的操作。end_callback:爬蟲結束時調用的回調函數(shù)。可以指定一個函數(shù),在爬蟲結束時執(zhí)行特定的操作。delete_keys:在爬蟲結束時要刪除的 Redis 鍵列表。可以傳遞一個包含要刪除的鍵名的列表,用于清理任務隊列中的任務。keep_alive:指定是否保持爬蟲在后臺運行。設置為 True 時,爬蟲將保持運行狀態(tài),不會自動退出。auto_start_requests:指定是否自動開始爬取任務。設置為 True 時,爬蟲會自動開始處理任務隊列中的任務。batch_interval:任務批處理的時間間隔。可以指定一個時間間隔(以秒為單位),用于控制任務的批處理。wait_lock:指定是否等待鎖釋放。設置為 True 時,爬蟲在獲取任務鎖時會等待,直到鎖被釋放才繼續(xù)執(zhí)行。**kwargs:其他自定義參數(shù)。可以傳遞其他自定義參數(shù)作為關鍵字參數(shù),用于配置爬蟲的其他行為和屬性。
- feapder.Spider.start_monitor_task(*args, **kws):啟動監(jiān)控任務
- feapder.Spider.distribute_task(*args, **kws):用于分發(fā)任務
- feapder.Spider.run():用于啟動爬蟲
- feapder.Spider.to_DebugSpider():用于將當前的爬蟲實例轉換為調試模式下的爬蟲實例
八、feapder.TaskSpider 模塊,繼承TaskParser、Scheduler - feapder.TaskSpider(redis_key,...,use_mysql=True,**kwargs,):創(chuàng)建TaskSpider對象
redis_key:用于任務調度的 Redis 鍵名。任務隊列中的任務將根據(jù)此鍵名進行調度和分發(fā)。task_table:任務表的名稱或對象??梢允且粋€字符串,表示任務表的名稱,也可以是一個任務表對象,用于操作任務表。task_table_type:任務表的類型,默認為 'mysql'??梢允?'mysql'、'mongodb' 或其他支持的任務表類型。task_keys:任務鍵列表。指定任務表中的鍵名列表,用于唯一標識任務。task_state:任務狀態(tài)字段名,默認為 'state'。任務表中的該字段用于標識任務的狀態(tài)。min_task_count:最小任務數(shù)。指定任務表中的最小任務數(shù)量,當任務數(shù)量低于此值時,會觸發(fā)任務補充。check_task_interval:檢查任務的時間間隔(秒)。指定任務補充的檢查間隔,用于定期檢查任務數(shù)量并進行補充。task_limit:任務限制數(shù)。指定每次從任務表中獲取的任務數(shù)量上限。related_redis_key:關聯(lián)的 Redis 鍵名。指定一個關聯(lián)的 Redis 鍵名,用于在任務補充時進行關聯(lián)任務的獲取。related_batch_record:關聯(lián)任務的批處理記錄。指定一個關聯(lián)任務的批處理記錄對象,用于在任務補充時進行關聯(lián)任務的獲取。task_condition:任務查詢條件。指定一個查詢條件,用于篩選任務表中的任務。task_order_by:任務排序方式。指定一個排序方式,用于對任務表中的任務進行排序。thread_count:爬蟲的線程數(shù)。指定同時運行的線程數(shù)量,用于并發(fā)地處理任務。begin_callback:爬蟲開始時調用的回調函數(shù)??梢灾付ㄒ粋€函數(shù),在爬蟲開始時執(zhí)行特定的操作。end_callback:爬蟲結束時調用的回調函數(shù)??梢灾付ㄒ粋€函數(shù),在爬蟲結束時執(zhí)行特定的操作。delete_keys:在爬蟲結束時要刪除的 Redis 鍵列表??梢詡鬟f一個包含要刪除的鍵名的列表,用于清理任務隊列中的任務。keep_alive:指定是否保持爬蟲在后臺運行。設置為 True 時,爬蟲將保持運行狀態(tài),不會自動退出。batch_interval:任務批處理的時間間隔。可以指定一個時間間隔(以秒為單位),用于控制任務的批處理。use_mysql:是否使用 MySQL 數(shù)據(jù)庫,默認為 True。設置為 False 時,將不會使用 MySQL 數(shù)據(jù)庫進行任務操作。**kwargs:其他自定義參數(shù)。可以傳遞其他自定義參數(shù)作為關鍵字參數(shù),用于配置爬蟲的其他行為和屬性。
- feapder.TaskSpider.add_parser(parser, **kwargs):將參數(shù)解析器添加到 TaskSpider 中??梢酝ㄟ^調用 add_parser 方法將自定義的參數(shù)解析器添加到 TaskSpider 中,以便解析命令行參數(shù)。
- feapder.TaskSpider.start_monitor_task():啟動任務監(jiān)控。調用此方法會啟動一個線程,用于監(jiān)控任務的狀態(tài)和數(shù)量,并進行任務的自動補充和分發(fā)。
- feapder.TaskSpider.get_task(todo_task_count):從任務表中獲取任務。可以指定要獲取的任務數(shù)量 todo_task_count,返回獲取到的任務列表。
- feapder.TaskSpider.distribute_task(tasks):分發(fā)任務。將傳入的任務列表 tasks 分發(fā)到任務隊列中,供爬蟲線程處理。
- feapder.TaskSpider.get_task_from_redis():從 Redis 中獲取任務。從任務隊列中獲取一個任務,并返回任務的內容。
- feapder.TaskSpider.get_todo_task_from_mysql():從 MySQL 中獲取待處理的任務數(shù)量。返回任務表中狀態(tài)為待處理的任務數(shù)量。
- feapder.TaskSpider.get_doing_task_from_mysql():從 MySQL 中獲取正在處理的任務數(shù)量。返回任務表中狀態(tài)為正在處理的任務數(shù)量。
- feapder.TaskSpider.get_lose_task_count():獲取丟失的任務數(shù)量。返回任務表中狀態(tài)為丟失的任務數(shù)量。
- feapder.TaskSpider.reset_lose_task_from_mysql():重置丟失的任務。將任務表中狀態(tài)為丟失的任務重新設置為待處理狀態(tài)。
- feapder.TaskSpider.related_spider_is_done():關聯(lián)的爬蟲是否已完成。判斷關聯(lián)的爬蟲是否已經完成任務。
- feapder.TaskSpider.task_is_done():任務是否已完成。判斷任務是否已經完成。
- feapder.TaskSpider.run():運行 TaskSpider。啟動 TaskSpider 的運行,開始處理任務。
- feapder.TaskSpider.to_DebugTaskSpider(*args, **kwargs):將 TaskSpider 轉換為 DebugTaskSpider。返回一個 DebugTaskSpider 對象,用于調試任務的處理流程
九、feapder.BatchSpider 模塊,繼承BatchParser、Scheduler - feapder.BatchSpider( task_table,...,auto_start_next_batch=True,**kwargs,):創(chuàng)建BatchSpider對象
task_table:任務表的名稱或對象??梢允且粋€字符串,表示任務表的名稱,也可以是一個任務表對象,用于操作任務表。batch_record_table:批處理記錄表的名稱或對象。可以是一個字符串,表示批處理記錄表的名稱,也可以是一個批處理記錄表對象,用于操作批處理記錄表。batch_name:批處理的名稱。指定批處理的名稱,用于在批處理記錄表中標識批處理的記錄。batch_interval:批處理的時間間隔(秒)。指定批處理的時間間隔,用于控制批處理的頻率。task_keys:任務鍵列表。指定任務表中的鍵名列表,用于唯一標識任務。task_state:任務狀態(tài)字段名,默認為 'state'。任務表中的該字段用于標識任務的狀態(tài)。min_task_count:最小任務數(shù)。指定任務表中的最小任務數(shù)量,當任務數(shù)量低于此值時,會觸發(fā)任務補充。check_task_interval:檢查任務的時間間隔(秒)。指定任務補充的檢查間隔,用于定期檢查任務數(shù)量并進行補充。task_limit:任務限制數(shù)。指定每次從任務表中獲取的任務數(shù)量上限。related_redis_key:關聯(lián)的 Redis 鍵名。指定一個關聯(lián)的 Redis 鍵名,用于在任務補充時進行關聯(lián)任務的獲取。related_batch_record:關聯(lián)任務的批處理記錄。指定一個關聯(lián)任務的批處理記錄對象,用于在任務補充時進行關聯(lián)任務的獲取。task_condition:任務查詢條件。指定一個查詢條件,用于篩選任務表中的任務。task_order_by:任務排序方式。指定一個排序方式,用于對任務表中的任務進行排序。redis_key:用于任務調度的 Redis 鍵名。任務隊列中的任務將根據(jù)此鍵名進行調度和分發(fā)。thread_count:爬蟲的線程數(shù)。指定同時運行的線程數(shù)量,用于并發(fā)地處理任務。begin_callback:爬蟲開始時調用的回調函數(shù)??梢灾付ㄒ粋€函數(shù),在爬蟲開始時執(zhí)行特定的操作。end_callback:爬蟲結束時調用的回調函數(shù)??梢灾付ㄒ粋€函數(shù),在爬蟲結束時執(zhí)行特定的操作。delete_keys:在爬蟲結束時要刪除的 Redis 鍵列表。可以傳遞一個包含要刪除的鍵名的列表,用于清理任務隊列中的任務。keep_alive:指定是否保持爬蟲在后臺運行。設置為 True 時,爬蟲將保持運行狀態(tài),不會自動退出。auto_start_next_batch:是否自動啟動下一批處理。設置為 True 時,當當前批處理完成后,會自動啟動下一批處理。**kwargs:其他自定義參數(shù)??梢詡鬟f其他自定義參數(shù)作為關鍵字參數(shù),用于配置爬蟲的其他行為和屬性。
- feapder.BatchSpider.init_batch_property():初始化批處理屬性。在批處理開始時調用,用于初始化批處理的屬性,包括批處理記錄、任務狀態(tài)等。
- feapder.BatchSpider.add_parser(parser, **kwargs):將參數(shù)解析器添加到 BatchSpider 中。可以通過調用 add_parser 方法將自定義的參數(shù)解析器添加到 BatchSpider 中,以便解析命令行參數(shù)。
- feapder.BatchSpider.start_monitor_task():啟動任務監(jiān)控。調用此方法會啟動一個線程,用于監(jiān)控任務的狀態(tài)和數(shù)量,并進行任務的自動補充和分發(fā)。
- feapder.BatchSpider.create_batch_record_table():創(chuàng)建批處理記錄表。根據(jù)配置的批處理記錄表名稱和字段,在數(shù)據(jù)庫中創(chuàng)建對應的批處理記錄表。
- feapder.BatchSpider.distribute_task(tasks):分發(fā)任務。將傳入的任務列表 tasks 分發(fā)到任務隊列中,供爬蟲線程處理。
- feapder.BatchSpider.update_task_done_count():更新任務完成數(shù)量。在任務完成后調用,更新批處理記錄表中的任務完成數(shù)量。
- feapder.BatchSpider.update_is_done():更新批處理狀態(tài)為完成。在批處理完成后調用,更新批處理記錄表中的狀態(tài)為完成。
- feapder.BatchSpider.get_todo_task_from_mysql():從 MySQL 中獲取待處理的任務數(shù)量。返回任務表中狀態(tài)為待處理的任務數(shù)量。
- feapder.BatchSpider.get_doing_task_from_mysql():從 MySQL 中獲取正在處理的任務數(shù)量。返回任務表中狀態(tài)為正在處理的任務數(shù)量。
- feapder.BatchSpider.get_lose_task_count():獲取丟失的任務數(shù)量。返回任務表中狀態(tài)為丟失的任務數(shù)量。
- feapder.BatchSpider.reset_lose_task_from_mysql():重置丟失的任務。將任務表中狀態(tài)為丟失的任務重新設置為待處理狀態(tài)。
- feapder.BatchSpider.get_deal_speed(total_count, done_count, last_batch_date):獲取處理速度。根據(jù)總任務數(shù)、已完成任務數(shù)和上一批處理的時間,計算并返回任務處理的速度。
- feapder.BatchSpider.init_task():初始化任務。在批處理開始時調用,用于初始化任務表中的任務狀態(tài)和批處理記錄表中的任務數(shù)量。
- feapder.BatchSpider.check_batch(is_first_check=False):檢查批處理。根據(jù)配置的批處理時間間隔和任務數(shù)量限制,檢查是否需要進行批處理的觸發(fā)。
- feapder.BatchSpider.related_spider_is_done():關聯(lián)的爬蟲是否已完成。判斷關聯(lián)的爬蟲是否已經完成任務。
- feapder.BatchSpider.record_batch():記錄批處理。將批處理的相關信息記錄到批處理記錄表中。
- feapder.BatchSpider.task_is_done():任務是否已完成。判斷任務是否已經完成。
- feapder.BatchSpider.run():運行 BatchSpider。啟動 BatchSpider 的運行,開始處理任務。
- feapder.BatchSpider.to_DebugBatchSpider(*args, **kwargs):將 BatchSpider 轉換為 DebugBatchSpider。返回一個 DebugBatchSpider 對象,用于調試批處理的處理流程。
十、feapder.core 框架核心模塊 - 基礎解析器:from feapder.core.base_parser import BaseParser,用于解析任務或批處理的參數(shù)和配置
- BaseParser.name:解析器的名稱
- BaseParser.close():用于關閉解析器,可以在其中進行一些清理工作
- BaseParser.start_requests():生成初始的請求,可以在這里通過 yield 語句返回起始請求
- BaseParser.parse(request, response):默認的頁面解析方法,可以在這里定義解析邏輯。
- BaseParser.end_callback():程序結束的回調
- BaseParser.download_midware(request):下載中間件,可以在這里實現(xiàn)一些自定義的下載邏輯
- BaseParser.exception_request(request, response, e):請求或者parser里解析出異常的request
- BaseParser.failed_request(request, response, e):超過最大重試次數(shù)的request
- BaseParser.start_callback():程序開始的回調
- BaseParser.validate(request, response):用于驗證解析器的有效性,若函數(shù)內拋出異常,則重試請求若返回True 或 None,則進入解析函數(shù)若返回False,則拋棄當前請求
- 基礎任務解析器:from feapder.core.base_parser import TaskParser,用于解析單個任務的參數(shù)和配置,繼承BaseParser
- TaskParser(task_table, task_state, mysqldb=None):創(chuàng)建基礎任務解析器對象
task_table:任務表的名稱或配置。可以是一個字符串,表示任務表的名稱,也可以是一個字典,包含任務表的配置信息。task_state:任務狀態(tài)的配置。一個字典,包含任務狀態(tài)的配置信息,用于定義任務的不同狀態(tài),如待處理、正在處理、已完成等。mysqldb:MySQL 數(shù)據(jù)庫連接對象??蛇x參數(shù),用于指定連接到的 MySQL 數(shù)據(jù)庫。
- TaskParser.add_task(): 用于添加一個任務到任務表中,每次啟動start_monitor 都會調用,且在init_task之前調用
- TaskParser.start_requests(task): 用于開始處理指定的任務。
- TaskParser.update_task_state(task_id, state=1, **kwargs): 更新任務表中任務狀態(tài),做完每個任務時代碼邏輯中要主動調用
- TaskParser.update_task_batch(task_id, state=1, **kwargs): 批量更新任務 多處調用,更新的字段必須一致
- 基礎批處理解析器:from feapder.core.base_parser import BatchParser,用于解析批處理任務的參數(shù)和配置,繼承TaskParser
- BatchParser(task_table, batch_record_table, task_state, date_format, mysqldb=None):創(chuàng)建基礎批處理解析器對象
task_table:任務表的名稱或配置??梢允且粋€字符串,表示任務表的名稱,也可以是一個字典,包含任務表的配置信息。batch_record_table:批處理記錄表的名稱或配置??梢允且粋€字符串,表示批處理記錄表的名稱,也可以是一個字典,包含批處理記錄表的配置信息。task_state:任務狀態(tài)的配置。一個字典,包含任務狀態(tài)的配置信息,用于定義任務的不同狀態(tài),如待處理、正在處理、已完成等。date_format:日期格式的配置。一個字符串,表示日期的格式,用于解析和格式化日期。mysqldb:MySQL 數(shù)據(jù)庫連接對象??蛇x參數(shù),用于指定連接到的 MySQL 數(shù)據(jù)庫。
- BatchParser.batch_date:用于表示批處理日期。它指定了批處理任務的日期,用于在批處理記錄表中進行日期篩選和操作
- 解析器控制模塊:from feapder.core.parser_control import ParserControl,用于控制解析器的執(zhí)行流程和任務調度
- parserControl = ParserControl(collector, redis_key, request_buffer, item_buffer):創(chuàng)建ParserControl對象
collector:用于收集數(shù)據(jù)的對象或組件。redis_key:用于標識任務狀態(tài)的 Redis 鍵名。request_buffer:請求緩沖區(qū),用于存儲待處理的請求。item_buffer:數(shù)據(jù)項緩沖區(qū),用于存儲待收集的數(shù)據(jù)項。
- parserControl.DOWNLOAD_TOTAL:下載總數(shù)。
- parserControl.DOWNLOAD_EXCEPTION:下載異常數(shù)。
- parserControl.DOWNLOAD_SUCCESS:下載成功數(shù)。
- parserControl.is_show_tip:是否示提示。
- parserControl.PAESERS_EXCEPTION:解析器異常數(shù)。
- parserControl.add_parser(parser):添加解析器。
- parserControl.stop():停止解析器。
- parserControl.run():運行解析器。
- parserControl.deal_request(request):處理請求。
- parserControl.get_task_status_count():獲取任務狀態(tài)計數(shù)。
- parserControl.is_not_task():檢查是否沒有任務。
- AirSpider爬蟲解析器控制模塊,繼承ParserControl:from feapder.core.parser_control import AirSpiderParserControl
- airSpiderParserControl = AirSpiderParserControl(memory_db, request_buffer, item_buffer):創(chuàng)建AirSpiderParserControl對象
- airSpiderParserControl.is_show_tip:是否顯示提示。
- airSpiderParserControl.deal_request(request):處理請求。
- airSpiderParserControl.run():運行解析器。
- 收集數(shù)據(jù)模塊:from feapder.core.collector import Collector,用于收集和處理爬取的數(shù)據(jù)
- collector = Collector(redis_key):創(chuàng)建收集器對象
redis_key:用于標識任務狀態(tài)的 Redis 鍵名。
- collector.run():運行收集器。
- collector.stop():停止收集器。
- collector.is_collector_task():檢查是否有收集任務。
- collector.get_request():獲取一個請求對象。
- collector.get_requests_count():獲取請求對象的數(shù)量。
- 調度管理:from feapder.core.scheduler import Scheduler,用于管理和調度爬蟲任務的執(zhí)行
- scheduler = Scheduler(redis_key,..., **kwargs):創(chuàng)建調度器對象
redis_key:用于標識任務狀態(tài)的 Redis 鍵名。thread_count:調度器使用的線程數(shù)。begin_callback:在開始調度時調用的回調函數(shù)。end_callback:在結束調度時調用的回調函數(shù)。delete_keys:在結束調度時刪除的 Redis 鍵。keep_alive:調度器是否保持活動狀態(tài)。auto_start_requests:是否自動開始請求。batch_interval:批量處理請求的間隔時間。wait_lock:等待鎖的時間。task_table:任務表的名稱。**kwargs:其他參數(shù)。
- wait_lock:等待鎖的時間。
- check_task_status():檢查任務狀態(tài)。
- run():運行調度器。
- wait_lock:等待鎖的時間。
- add_parser():添加解析器。
- join():等待所有線程完成。
- all_thread_is_done():檢查是否所有線程都完成了。
- check_task_status:檢查任務狀態(tài)。
- delete_tables():刪除表。
- have_alive_spider():檢查是否有活躍的爬蟲。
- heartbeat():心跳。
- heartbeat_start():啟動心跳。
- heartbeat_stop():停止心跳。
- init_metrics():初始化指標。
- is_reach_next_spider_time():檢查是否到達啟動下一個爬蟲的時間。
- record_end_time():記錄結束時間。
- reset_task():重置任務。
- send_msg():發(fā)送消息。
- spider_begin():爬蟲開始。
- spider_end():爬蟲結束。
- stop_spider():停止爬蟲。
十一、feapder.setting:配置模塊 - setting.py文件,可通過命令 feapder create --setting 創(chuàng)建
# -*- coding: utf-8 -*-'''爬蟲配置文件'''# import os# import sys## # MYSQL# MYSQL_IP = 'localhost'# MYSQL_PORT = 3306# MYSQL_DB = ''# MYSQL_USER_NAME = ''# MYSQL_USER_PASS = ''## # MONGODB# MONGO_IP = 'localhost'# MONGO_PORT = 27017# MONGO_DB = ''# MONGO_USER_NAME = ''# MONGO_USER_PASS = ''## # REDIS# # ip:port 多個可寫為列表或者逗號隔開 如 ip1:port1,ip2:port2 或 ['ip1:port1', 'ip2:port2']# REDISDB_IP_PORTS = 'localhost:6379'# REDISDB_USER_PASS = ''# REDISDB_DB = 0# # 適用于redis哨兵模式# REDISDB_SERVICE_NAME = ''## # 數(shù)據(jù)入庫的pipeline,可自定義,默認MysqlPipeline# ITEM_PIPELINES = [# 'feapder.pipelines.mysql_pipeline.MysqlPipeline',# # 'feapder.pipelines.mongo_pipeline.MongoPipeline',# # 'feapder.pipelines.console_pipeline.ConsolePipeline',# ]# EXPORT_DATA_MAX_FAILED_TIMES = 10 # 導出數(shù)據(jù)時最大的失敗次數(shù),包括保存和更新,超過這個次數(shù)報警# EXPORT_DATA_MAX_RETRY_TIMES = 10 # 導出數(shù)據(jù)時最大的重試次數(shù),包括保存和更新,超過這個次數(shù)則放棄重試## # 爬蟲相關# # COLLECTOR# COLLECTOR_TASK_COUNT = 32 # 每次獲取任務數(shù)量,追求速度推薦32## # SPIDER# SPIDER_THREAD_COUNT = 1 # 爬蟲并發(fā)數(shù),追求速度推薦32# # 下載時間間隔 單位秒。 支持隨機 如 SPIDER_SLEEP_TIME = [2, 5] 則間隔為 2~5秒之間的隨機數(shù),包含2和5# SPIDER_SLEEP_TIME = 0# SPIDER_MAX_RETRY_TIMES = 10 # 每個請求最大重試次數(shù)# KEEP_ALIVE = False # 爬蟲是否常駐# 下載# DOWNLOADER = 'feapder.network.downloader.RequestsDownloader'# SESSION_DOWNLOADER = 'feapder.network.downloader.RequestsSessionDownloader'# RENDER_DOWNLOADER = 'feapder.network.downloader.SeleniumDownloader'# # RENDER_DOWNLOADER='feapder.network.downloader.PlaywrightDownloader',# MAKE_ABSOLUTE_LINKS = True # 自動轉成絕對連接# # 瀏覽器渲染# WEBDRIVER = dict(# pool_size=1, # 瀏覽器的數(shù)量# load_images=True, # 是否加載圖片# user_agent=None, # 字符串 或 無參函數(shù),返回值為user_agent# proxy=None, # xxx.xxx.xxx.xxx:xxxx 或 無參函數(shù),返回值為代理地址# headless=False, # 是否為無頭瀏覽器# driver_type='CHROME', # CHROME、EDGE、PHANTOMJS、FIREFOX# timeout=30, # 請求超時時間# window_size=(1024, 800), # 窗口大小# executable_path=None, # 瀏覽器路徑,默認為默認路徑# render_time=0, # 渲染時長,即打開網頁等待指定時間后再獲取源碼# custom_argument=[# '--ignore-certificate-errors',# '--disable-blink-features=AutomationControlled',# ], # 自定義瀏覽器渲染參數(shù)# xhr_url_regexes=None, # 攔截xhr接口,支持正則,數(shù)組類型# auto_install_driver=True, # 自動下載瀏覽器驅動 支持chrome 和 firefox# download_path=None, # 下載文件的路徑# use_stealth_js=False, # 使用stealth.min.js隱藏瀏覽器特征# )## PLAYWRIGHT = dict(# user_agent=None, # 字符串 或 無參函數(shù),返回值為user_agent# proxy=None, # xxx.xxx.xxx.xxx:xxxx 或 無參函數(shù),返回值為代理地址# headless=False, # 是否為無頭瀏覽器# driver_type='chromium', # chromium、firefox、webkit# timeout=30, # 請求超時時間# window_size=(1024, 800), # 窗口大小# executable_path=None, # 瀏覽器路徑,默認為默認路徑# download_path=None, # 下載文件的路徑# render_time=0, # 渲染時長,即打開網頁等待指定時間后再獲取源碼# wait_until='networkidle', # 等待頁面加載完成的事件,可選值:'commit', 'domcontentloaded', 'load', 'networkidle'# use_stealth_js=False, # 使用stealth.min.js隱藏瀏覽器特征# page_on_event_callback=None, # page.on() 事件的回調 如 page_on_event_callback={'dialog': lambda dialog: dialog.accept()}# storage_state_path=None, # 保存瀏覽器狀態(tài)的路徑# url_regexes=None, # 攔截接口,支持正則,數(shù)組類型# save_all=False, # 是否保存所有攔截的接口, 配合url_regexes使用,為False時只保存最后一次攔截的接口# )## # 爬蟲啟動時,重新抓取失敗的requests# RETRY_FAILED_REQUESTS = False# # 保存失敗的request# SAVE_FAILED_REQUEST = True# # request防丟機制。(指定的REQUEST_LOST_TIMEOUT時間內request還沒做完,會重新下發(fā) 重做)# REQUEST_LOST_TIMEOUT = 600 # 10分鐘# # request網絡請求超時時間# REQUEST_TIMEOUT = 22 # 等待服務器響應的超時時間,浮點數(shù),或(connect timeout, read timeout)元組# # item在內存隊列中最大緩存數(shù)量# ITEM_MAX_CACHED_COUNT = 5000# # item每批入庫的最大數(shù)量# ITEM_UPLOAD_BATCH_MAX_SIZE = 1000# # item入庫時間間隔# ITEM_UPLOAD_INTERVAL = 1# # 內存任務隊列最大緩存的任務數(shù),默認不限制;僅對AirSpider有效。# TASK_MAX_CACHED_SIZE = 0## # 下載緩存 利用redis緩存,但由于內存大小限制,所以建議僅供開發(fā)調試代碼時使用,防止每次debug都需要網絡請求# RESPONSE_CACHED_ENABLE = False # 是否啟用下載緩存 成本高的數(shù)據(jù)或容易變需求的數(shù)據(jù),建議設置為True# RESPONSE_CACHED_EXPIRE_TIME = 3600 # 緩存時間 秒# RESPONSE_CACHED_USED = False # 是否使用緩存 補采數(shù)據(jù)時可設置為True## # 設置代理# PROXY_EXTRACT_API = None # 代理提取API ,返回的代理分割符為\r\n# PROXY_ENABLE = True## # 隨機headers# RANDOM_HEADERS = True# # UserAgent類型 支持 'chrome', 'opera', 'firefox', 'internetexplorer', 'safari','mobile' 若不指定則隨機類型# USER_AGENT_TYPE = 'chrome'# # 默認使用的瀏覽器頭# DEFAULT_USERAGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'# # requests 使用session# USE_SESSION = False## # 去重# ITEM_FILTER_ENABLE = False # item 去重# REQUEST_FILTER_ENABLE = False # request 去重# ITEM_FILTER_SETTING = dict(# filter_type=1 # 永久去重(BloomFilter) = 1 、內存去重(MemoryFilter) = 2、 臨時去重(ExpireFilter)= 3、輕量去重(LiteFilter)= 4# )# REQUEST_FILTER_SETTING = dict(# filter_type=3, # 永久去重(BloomFilter) = 1 、內存去重(MemoryFilter) = 2、 臨時去重(ExpireFilter)= 3、 輕量去重(LiteFilter)= 4# expire_time=2592000, # 過期時間1個月# )## # 報警 支持釘釘、飛書、企業(yè)微信、郵件# # 釘釘報警# DINGDING_WARNING_URL = '' # 釘釘機器人api# DINGDING_WARNING_PHONE = '' # 報警人 支持列表,可指定多個# DINGDING_WARNING_ALL = False # 是否提示所有人, 默認為False# # 飛書報警# # https://open.feishu.cn/document/ukTMukTMukTM/ucTM5YjL3ETO24yNxkjN#e1cdee9f# FEISHU_WARNING_URL = '' # 飛書機器人api# FEISHU_WARNING_USER = None # 報警人 {'open_id':'ou_xxxxx', 'name':'xxxx'} 或 [{'open_id':'ou_xxxxx', 'name':'xxxx'}]# FEISHU_WARNING_ALL = False # 是否提示所有人, 默認為False# # 郵件報警# EMAIL_SENDER = '' # 發(fā)件人# EMAIL_PASSWORD = '' # 授權碼# EMAIL_RECEIVER = '' # 收件人 支持列表,可指定多個# EMAIL_SMTPSERVER = 'smtp.163.com' # 郵件服務器 默認為163郵箱# # 企業(yè)微信報警# WECHAT_WARNING_URL = '' # 企業(yè)微信機器人api# WECHAT_WARNING_PHONE = '' # 報警人 將會在群內@此人, 支持列表,可指定多人# WECHAT_WARNING_ALL = False # 是否提示所有人, 默認為False# # 時間間隔# WARNING_INTERVAL = 3600 # 相同報警的報警時間間隔,防止刷屏; 0表示不去重# WARNING_LEVEL = 'DEBUG' # 報警級別, DEBUG / INFO / ERROR# WARNING_FAILED_COUNT = 1000 # 任務失敗數(shù) 超過WARNING_FAILED_COUNT則報警## LOG_NAME = os.path.basename(os.getcwd())# LOG_PATH = 'log/%s.log' % LOG_NAME # log存儲路徑# LOG_LEVEL = 'DEBUG'# LOG_COLOR = True # 是否帶有顏色# LOG_IS_WRITE_TO_CONSOLE = True # 是否打印到控制臺# LOG_IS_WRITE_TO_FILE = False # 是否寫文件# LOG_MODE = 'w' # 寫文件的模式# LOG_MAX_BYTES = 10 * 1024 * 1024 # 每個日志文件的最大字節(jié)數(shù)# LOG_BACKUP_COUNT = 20 # 日志文件保留數(shù)量# LOG_ENCODING = 'utf8' # 日志文件編碼# OTHERS_LOG_LEVAL = 'ERROR' # 第三方庫的log等級## # 切換工作路徑為當前項目路徑# project_path = os.path.abspath(os.path.dirname(__file__))# os.chdir(project_path) # 切換工作路經# sys.path.insert(0, project_path)# print('當前工作路徑為 ' + os.getcwd())
- 導入配置:import feapder.setting as setting 或 from feapder import setting
十二、feapder.network,處理網絡請求和響應的模塊 - from feapder.network.request import Request 或 from feapder import Request:用于表示一個 HTTP 請求??梢栽O置請求的 URL、請求方法、請求頭、請求體等信息
- request = Request(url,...,**kwargs)
url: 待抓取urlretry_times: 當前重試次數(shù)priority: 優(yōu)先級 越小越優(yōu)先 默認300parser_name: 回調函數(shù)所在的類名 默認為當前類callback: 回調函數(shù) 可以是函數(shù) 也可是函數(shù)名(如想跨類回調時,parser_name指定那個類名,callback指定那個類想回調的方法名即可)filter_repeat: 是否需要去重 (True/False) 當setting中的REQUEST_FILTER_ENABLE設置為True時該參數(shù)生效 默認Trueauto_request: 是否需要自動請求下載網頁 默認是。設置為False時返回的response為空,需要自己去請求網頁request_sync: 是否同步請求下載網頁,默認異步。如果該請求url過期時間快,可設置為True,相當于yield的reqeust會立即響應,而不是去排隊use_session: 是否使用session方式random_user_agent: 是否隨機User-Agent (True/False) 當setting中的RANDOM_HEADERS設置為True時該參數(shù)生效 默認Truedownload_midware: 下載中間件。默認為parser中的download_midwareis_abandoned: 當發(fā)生異常時是否放棄重試 True/False. 默認Falserender: 是否用瀏覽器渲染render_time: 渲染時長,即打開網頁等待指定時間后再獲取源碼make_absolute_links: 是否轉成絕對連接,默認是**kwargs: 其他值: 如 Request(item=item) 則item可直接用 request.item 取出method:請求方式,可以是 POST 或 GET。params:請求參數(shù),通常是一個字典,包含了發(fā)送到服務器的額外參數(shù)。data:請求的主體內容,通常用于 POST 請求。json:請求的主體內容,以 JSON 字符串形式傳遞。headers:請求頭,包含了一些額外的信息,如 User-Agent、Content-Type 等。cookies:用于發(fā)送請求的 cookies,可以是一個字典或者 CookieJar 對象。files:上傳文件時使用的參數(shù)。auth:用于 HTTP 基本認證。timeout:等待服務器響應的超時時間,可以是一個浮點數(shù),也可以是一個元組,表示連接超時和讀取超時。allow_redirects:是否允許跟蹤 POST/PUT/DELETE 方法的重定向。proxies:代理設置,以字典形式傳遞,如 {'http': 'http://xxx', 'https': 'https://xxx'}。verify:是否驗證 SSL 證書。stream:如果為 False,將會立即下載響應內容。cert:SSL 證書的路徑。
- request.requests_kwargs:請求的一些額外參數(shù)。
- request.url:請求的URL。
- request.headers:請求頭。
- request.parser_name:解析器的名稱。
- request.downloader:下載器。
- request.auto_request:是否自動發(fā)送請求。
- request.download_midware:下載中間件。
- request.to_dict:將請求對象轉換成字典。
- request.priority:請求的優(yōu)先級。
- request.callback:回調函數(shù)。
- request.method:請求方法(GET、POST等)。
- request.cache_db:緩存數(shù)據(jù)庫。
- request.cached_expire_time:緩存過期時間。
- request.cached_redis_key:緩存的 Redis 鍵。
- request.callback_name:回調函數(shù)的名稱。
- request.custom_proxies:自定義代理。
- request.custom_ua:自定義 User-Agent。
- request.filter_repeat:是否進行去重。
- request.fingerprint:指紋。
- request.is_abandoned:是否被廢棄。
- request.make_absolute_links:是否創(chuàng)建絕對鏈接。
- request.proxies_pool:代理池。
- request.random_user_agent:隨機 User-Agent。
- request.render:是否進行渲染。
- request.render_downloader:渲染下載器。
- request.render_time:渲染時間。
- request.request_sync:請求同步。
- request.retry_times:重試次數(shù)。
- request.session_downloader:會話下載器。
- request.use_session:是否使用會話。
- request.user_agent_pool:User-Agent 池。
- request.from_dict(request_dict):從字典中創(chuàng)建一個請求對象。
- request.get_cookies():獲取請求的 cookies。
- request.get_headers():獲取請求的 headers。
- request.get_params():獲取請求的參數(shù)。
- request.get_proxies():獲取請求的代理。
- request.get_proxy():獲取單個代理。
- request.get_response():獲取響應。
- request.get_response_from_cached():從緩存中獲取響應。
- request.get_user_agent():獲取 User-Agent。
- request.make_requests_kwargs():生成請求參數(shù)。
- request.save_cached(response, expire_time):將響應緩存。
- request.del_proxy():刪除代理。
- request.del_response_cached():從緩存中刪除響應。
- request.copy():復制請求對象。
- from feapder.network.response import Response 或 from feapder import Response:用于表示一個 HTTP 響應。包含響應的狀態(tài)碼、響應頭、響應體等信息
- response = Response(response, make_absolute_links)
response:代表接收到的 HTTP 響應。make_absolute_links:一個布爾值,用于指定是否將相對鏈接轉換為絕對鏈接。
- response.make_absolute_links:將相對鏈接轉換為絕對鏈接。
- response.url:響應的URL。
- response.request:關聯(lián)的請求對象。
- response.to_dict:將響應對象轉換成字典。
- response.selector:用于解析的選擇器。
- response.browser:瀏覽器對象。
- response.text:響應的文本內容。
- response.json:將響應解析為 JSON。
- response.headers:響應頭信息。
- response.encoding:響應的編碼方式。
- response.cookies:響應的 cookies。
- response.driver:瀏覽器驅動。
- response.content:響應的內容。
- response.next:返回下一個請求對象。
- response.apparent_encoding:響應的編碼方式(自動檢測)。
- response.code:響應的狀態(tài)碼。
- response.elapsed:響應時間。
- response.encoding_errors:編碼錯誤。
- response.history:響應的重定向歷史。
- response.is_html:判斷響應是否為 HTML。
- response.is_permanent_redirect:是否為永久重定向。
- response.is_redirect:是否為重定向。
- response.links:響應中的鏈接。
- response.ok:響應是否成功。
- response.raw:原始響應。
- response.reason:響應的原因。
- response.status_code:響應的狀態(tài)碼。
- response.xpath(query, **kwargs):使用 XPath 進行解析。
- response.css(query):使用 CSS 選擇器進行解析。
- response.extract():提取響應內容。
- response.re(regex, replace_entities):使用正則表達式進行提取。
- response.re_first(regex, default, replace_entities):提取第一個匹配的內容。
- from_dict(response_dict):從字典創(chuàng)建一個響應對象。
- response.close():關閉響應對象。
- response.open():打開響應對象。
- response.bs4(features):使用 BeautifulSoup 進行解析。
- response.close_browser(request):關閉瀏覽器。
- response.from_text(text,url,cookies,headerse, encoding,):從文本創(chuàng)建響應對象。
- response.iter_content(chunk_size, decode_unicode):迭代響應內容。
- response.iter_lines(chunk_size, decode_unicode, delimiter):迭代響應內容的行。
- response.raise_for_status():檢查響應的狀態(tài),并在非成功響應時引發(fā)異常
- from feapder.network.item import Item 或 from feapder import Item
- item = Item(**kwargs):創(chuàng)建item對象,繼承ItemMetaclass,**kwargs item的字典對象
'''ItemMetaclass:使Item繼承一些默認屬性__name__:類的名稱,默認為 None。__table_name__:類對應的表的名稱,默認為 None。__name_underline__:類名的下劃線版本,默認為 None。__update_key__:用于更新記錄的關鍵字,默認為 None。__unique_key__:用于唯一標識記錄的關鍵字,默認為 None。'''class ItemMetaclass(type): def __new__(cls, name, bases, attrs): attrs.setdefault('__name__', None) attrs.setdefault('__table_name__', None) attrs.setdefault('__name_underline__', None) attrs.setdefault('__update_key__', None) attrs.setdefault('__unique_key__', None) return type.__new__(cls, name, bases, attrs)
- item.item_name: 這可能是用于表示一個項目(item)的名稱。
- item.unique_key: 這可能是一個用于唯一標識一個項目的關鍵字。
- item.to_ict: 這可能是一個方法,用于將項目轉換為一個字典。
- item.name_underline: 這可能是表示項目名稱的下劃線版本。
- item.table_name: 這可能是用于表示項目對應的表格名稱。
- item.fingerprint: 這個屬性可能與項目的指紋(fingerprint)有關。
- item.to_UpdateItem(): 這可能是一個方法,用于將項目轉換為一個更新項。
- item.update(*args, **kwargs): 這可能是一個用于更新項目的方法,接受位置參數(shù)和關鍵字參數(shù)。
- item.pre_to_db(): 這可能是一個用于將項目預處理為數(shù)據(jù)庫中的格式的方法。
- item.to_sql(auto_update=False, update_columns=()): 這可能是一個用于將項目轉換為 SQL 語句的方法,可能有一個名為 auto_update 的參數(shù)和一個名為 update_columns 的參數(shù)。
- item.update_strict(*args, **kwargs): 這可能是一個用于嚴格更新項目的方法,接受位置參數(shù)和關鍵字參數(shù)。
- from feapder.network.item import UpdateItem 或 from feapder import UpdateItem,繼承item
- item = UpdateItem(**kwargs):創(chuàng)建item對象,繼承ItemMetaclass,**kwargs item的字典對象
- item.update_key(keys):更新__update_key__值
- from feapder.network.user_agent import get as get_ua
ua_type: ua類型chromeoperafirefoxinternetexplorersafarimobile
- from feapder.network.proxy_pool import BaseProxyPool:基礎代理池,會在文章后面另起標題配置代理
- BaseProxyPool.get_proxy(): 用于獲取一個代理IP。
- BaseProxyPool.del_proxy(): 用于刪除一個代理IP。
- BaseProxyPool.tag_proxy(): 用于給一個代理IP打上標簽或者標記。
- from feapder.network.proxy_pool import ProxyPool:代理池,繼承BaseProxyPool
- proxyPool = ProxyPool(proxy_api=None, **kwargs):創(chuàng)建代理池對象,會在文章后面另起標題配置代理
proxy_api 是一個用于獲取代理IP的API接口,如果不提供的話,可能會使用默認的代理獲取方式。**kwargs 則是用于傳遞其他可能需要的參數(shù)。
- proxyPool.proxy_api: 用于獲取代理IP的API接口。
- proxyPool.proxy_queue: 用于存儲代理IP。
- proxyPool.pull_proxies: 用于從代理API中獲取代理IP并將其放入隊列中。
- proxyPool.del_proxy(proxy): 用于從隊列中刪除指定的代理IP。
- proxyPool.get_proxy(): 用于從隊列中獲取一個代理IP。
- proxyPool.format_proxy(proxy): 用于格式化代理IP的表示方式。
- from feapder.network.user_pool import GuestUserPool, GuestUser:游客用戶池,用于從不需要登錄的頁面獲取cookie
- guestUserPool = GuestUserPool(redis_key,page_url=None,min_users=1,must_contained_keys=(),keep_alive=False, **kwargs):創(chuàng)建游客用戶池對象
redis_key: user存放在redis中的key前綴page_url: 生產user的urlmin_users: 最小user數(shù)must_contained_keys: cookie中必須包含的key,用于校驗cookie是否正確keep_alive: 是否保持常駐,以便user不足時立即補充kwargs: WebDriver的一些參數(shù) load_images: 是否加載圖片 user_agent: 字符串 或 無參函數(shù),返回值為user_agent proxy: xxx.xxx.xxx.xxx:xxxx 或 無參函數(shù),返回值為代理地址 headless: 是否啟用無頭模式 driver_type: CHROME,EDGE 或 PHANTOMJS,FIREFOX timeout: 請求超時時間 window_size: # 窗口大小 executable_path: 瀏覽器路徑,默認為默認路徑
- guestUserPool.login():用于登錄獲取用戶代理。在調用該方法后,用戶代理池會向指定的頁面 URL 發(fā)送請求,獲取用戶代理列表并存儲到 Redis 中。
- guestUserPool.add_user():用于手動添加一個用戶代理到用戶代理池中。你可以通過調用該方法來添加自定義的用戶代理。
- guestUserPool.get_user(user):用于從用戶代理池中獲取一個用戶代理對象。你可以將其用于發(fā)送請求。
- guestUserPool.run():用于啟動用戶代理池,它會自動定時登錄獲取用戶代理。
- guestUserPool.del_user(user_id):用于刪除指定 user_id 的用戶代理。
- guestUser = GuestUser(user_agent=None, proxies=None, cookies=None, **kwargs):創(chuàng)建用戶代理信息對象
user_agent:用戶代理字符串,用于模擬瀏覽器發(fā)送請求。proxies:代理信息,可以是一個代理字典,例如 {'http': 'http://proxy.:8080', 'https': 'https://proxy.:8080'}。cookies:Cookie 信息,可以是一個 Cookie 字符串,例如 'cookie1=value1; cookie2=value2'**kwargs:自定義屬性
- guestUser.user_agent:用戶代理字符串,用于模擬瀏覽器發(fā)送請求。
- guestUser.user_id:用戶代理的唯一標識符,用于在用戶代理池中識別和管理用戶代理。
- guestUser.cookies:Cookie 信息,可以是一個 Cookie 字符串,例如 'cookie1=value1; cookie2=value2'。
- guestUser.proxies:代理信息,可以是一個代理字典,例如 {'http': 'http://proxy.:8080', 'https': 'https://proxy.:8080'}。
- guestUser.to_dict():將 GuestUser 對象轉換為字典形式,方便序列化和存儲。
- guestUser.from_dict(data):從字典中恢復 GuestUser 對象的屬性。
- from feapder.network.user_pool import NormalUserPool, NormalUser:普通用戶池,管理大量賬號的信息,從需要登錄的頁面獲取cookie
- normalUserPool = NormalUserPool(redis_key,...,keep_alive=False,):創(chuàng)建用戶池對象
redis_key: 項目名table_userbase: 用戶表名login_state_key: 登錄狀態(tài)列名lock_state_key: 封鎖狀態(tài)列名username_key: 登陸名列名password_key: 密碼列名login_retry_times: 登陸失敗重試次數(shù)keep_alive: 是否保持常駐,以便user不足時立即補充
- normalUserPool.add_user(user):用于手動添加一個用戶代理到用戶代理池中。你可以通過調用該方法來添加自定義的用戶代理。
- normalUserPool.del_user(user_id):用于刪除指定 user_id 的用戶代理。
- normalUserPool.get_user(block=True):用于從用戶代理池中獲取一個用戶代理對象。如果 block 參數(shù)為 True,并且用戶代理池為空,該方法會等待直到有可用的用戶代理為止。
- normalUserPool.run():用于啟動用戶代理池,它會自動定時從數(shù)據(jù)庫中獲取用戶代理。
- normalUserPool.login(user):用于登錄獲取用戶代理。它接受一個 NormalUser 對象作為參數(shù)。
- normalUserPool.handel_exception(e):用于處理異常情況,例如在發(fā)送請求時發(fā)生錯誤。
- normalUserPool.handle_login_failed_user(user):用于處理登錄失敗的用戶代理。
- normalUserPool.tag_user_locked(user_id):用于標記指定 user_id 的用戶代理為鎖定狀態(tài)。
- normalUser = NormalUser(username, password, **kwargs):創(chuàng)建用戶代理信息對象,繼承GuestUser
- normalUser.user_id:用戶代理的id
- normalUser.username:用戶名
- normalUser.password:用戶密碼
- from feapder.network.user_pool import GoldUserPool, GoldUser, GoldUserStatus:昂貴的用戶池,用于賬號單價較高,需要限制使用頻率、使用時間的場景
- goldUserPool = GoldUserPool(redis_key,users,keep_alive=False):創(chuàng)建用戶池對象
redis_key: user存放在redis中的key前綴users: 賬號信息keep_alive: 是否保持常駐,以便user不足時立即補充
- goldUserPool.users:包含用戶代理字符串的列表,用于模擬不同類型的高級用戶。
- goldUserPool.add_user(user):用于手動添加一個高級用戶代理到用戶代理池中。你可以通過調用該方法來添加自定義的高級用戶代理。
- goldUserPool.del_user(user_id):用于刪除指定 user_id 的高級用戶代理。
- goldUserPool.get_user(block=True, username=None, used_for_spider_name=None, not_limit_use_interval=False):用于從用戶代理池中獲取一個高級用戶代理對象。如果 block 參數(shù)為 True,并且用戶代理池為空,該方法會等待直到有可用的高級用戶代理為止。
- goldUserPool.run(username):用于啟動用戶代理池,它會自動定時從數(shù)據(jù)庫中獲取高級用戶代理。
- goldUserPool.login(user):用于登錄獲取高級用戶代理。它接受一個 GoldUser 對象作為參數(shù)。
- goldUserPool.delay_use(user_id, delay_seconds):用于延遲使用指定 user_id 的高級用戶代理,以避免頻繁請求。
- goldUserPool.get_user_by_id(user_id):用于通過 user_id 獲取指定的高級用戶代理。
- goldUserPool.record_exception_user(user_id):用于記錄發(fā)生異常的高級用戶代理。
- goldUserPool.record_success_user(user_id):用于記錄成功使用的高級用戶代理。
- goldUserPool.record_user_status(user_id, status):用于記錄高級用戶代理的狀態(tài),如是否可用、是否鎖定等。
- goldUser = GoldUser(max_use_times,use_interval=0,work_time=(7, 23),login_interval=30 * 60,exclusive_time=None,**kwargs,):創(chuàng)建用戶代理信息對象,繼承NormalUser
max_use_times:@param use_interval: 使用時間間隔。 支持元組 指定間隔的時間范圍 如(5,10)即5到10秒;或直接傳整數(shù)work_time: 工作時間,默認 7點到23點login_interval: 登錄時間間隔 防止頻繁登錄 導致賬號被封exclusive_time: 獨占時長
- goldUser.redisdb:與用戶代理相關的 Redis 數(shù)據(jù)庫。
- goldUser.redis_key:用戶代理存儲在 Redis 中的鍵名。
- goldUser.use_interval:兩次使用之間的最小間隔時間(以秒為單位)。
- goldUser.use_times:已經使用的次數(shù)。
- goldUser.cookies:Cookie 信息。
- goldUser.work_time:工作時間段,表示在哪些時間段內可以使用該高級用戶代理。
- goldUser.login_interval:兩次登錄之間的最小間隔時間(以秒為單位)。
- goldUser.max_use_times:高級用戶代理的最大使用次數(shù)。
- goldUser.exclusive_time:高級用戶代理的獨占時間(以秒為單位)
- goldUser.to_dict():將 GoldUser 對象轉換為字典形式。
- goldUser.from_dict(data):從字典中恢復 GoldUser 對象的屬性。
- goldUser.update(ohter):更新 GoldUser 對象的屬性。
- goldUser.get_last_use_time():獲取上次使用的時間。
- goldUser.get_login_time():獲取上次登錄的時間。
- goldUser.get_used_for_spider_name():獲取用于爬蟲的名稱。
- goldUser.is_at_work_time():判斷當前時間是否在工作時間段內。
- goldUser.is_overwork():判斷是否超過最大工作次數(shù)。
- goldUser.is_time_to_login():判斷是否到了登錄的時間。
- goldUser.is_time_to_use():判斷是否到了使用的時間。
- goldUser.next_login_time():獲取下次登錄的時間。
- goldUser.reset_use_times():重置使用次數(shù)。
- goldUser.set_cookies(cookies):設置 Cookie 信息。
- goldUser.set_delay_use(seconds):設置延遲使用的時間。
- goldUser.set_login_time(login_time):設置登錄時間。
- goldUser.set_used_for_spider_name(name):設置用于爬蟲的名稱。
- goldUser.sycn_to_redis():將用戶代理信息同步到 Redis 中。
- goldUserStatus = GoldUserStatus():用戶代理的狀態(tài)
- goldUserStatus.USED:表示用戶代理已經被使用過,也可直接通過GoldUserStatu獲取該屬性。
- goldUserStatus.SUCCESS:表示某個操作(比如登錄)成功,也可直接通過GoldUserStatu獲取該屬性。
- goldUserStatus.OVERDUE:表示用戶代理已經過期,不再可用,也可直接通過GoldUserStatu獲取該屬性。
- goldUserStatus.SLEEP:表示用戶代理處于休眠狀態(tài),也可直接通過GoldUserStatu獲取該屬性。
- goldUserStatus.EXCEPTION:表示發(fā)生了異常情況,也可直接通過GoldUserStatu獲取該屬性。
- goldUserStatus.LOGIN_SUCCESS:表示登錄操作成功,也可直接通過GoldUserStatu獲取該屬性。
- goldUserStatus.LOGIN_FAILED:表示登錄操作失敗,也可直接通過GoldUserStatu獲取該屬性。
十三、feapder.db 數(shù)據(jù)庫模塊 - from feapder.db.mysqldb import MysqlDB:mysql數(shù)據(jù)庫
- mysql = MysqlDB(ip, port, db, user_name, user_pass, **kwargs):連接mysql
- mysql.connect_pool:連接池對象,用于管理數(shù)據(jù)庫連接。
- mysql.execute(sql):執(zhí)行 SQL 。
- mysql.update(sql):執(zhí)行 SQL 更新操作。
- mysql.add(sql, exception_callfunc=None):執(zhí)行 SQL 插入操作。
- mysql.find(sql, limit=None, to_json=False, conver_col=False):執(zhí)行查詢操作。
- mysql.get_connection():獲取數(shù)據(jù)庫連接。
- mysql.delete(sql):執(zhí)行刪除操作。
- mysql.add_batch(sql, datas):批量插入數(shù)據(jù)。
- mysql.add_batch_smart(table, datas, **kwargs):智能批量插入數(shù)據(jù)。
- mysql.add_smart(table, data, **kwargs):智能插入數(shù)據(jù)。
- mysql.close_connection(conn, cursor):關閉數(shù)據(jù)庫連接。
- mysql.from_url(url, **kwargs):從URL獲取數(shù)據(jù)庫連接信息。
- mysql.size_of_connect_pool():連接池大小。
- mysql.size_of_connections():連接數(shù)。
- mysql.unescape_string(value):反轉義字符串。
- mysql.update_smart(table, data, condition):智能更新數(shù)據(jù)。
- from feapder.db.mysqldb import auto_retry:mysql自動重試數(shù)據(jù)庫操作,是個裝飾器
- from feapder.db.redisdb import RedisDB:redis數(shù)據(jù)庫
- redisDB = RedisDB(ip_ports,db,user_pass,url,decode_responses,service_name,max_connections,**kwargs):連接redis數(shù)據(jù)庫
- redisDB.from_url(url):從 URL 獲取連接信息。
- redisDB.get_redis_obj():獲取 Redis 連接對象。
- redisDB.clear(table):清除指定表的數(shù)據(jù)。
- redisDB.srem(table, values):從集合中移除一個或多個元素。
- redisDB.sadd(table, values):向集合中添加一個或多個元素。
- redisDB.zrem(table, values):從有序集合中移除一個或多個元素。
- redisDB.lrange(table, start, end):獲取列表指定范圍內的元素。
- redisDB.lpush(table, values):將一個或多個值插入到列表頭部。
- redisDB.hdel(table, *keys):刪除哈希表中的一個或多個指定字段。
- redisDB.hset(table, key, value):設置哈希表中指定字段的值。
- redisDB.bitcount(table):計算給定字符串中,被設置為 1 的比特位的數(shù)量。
- redisDB.current_status(show_key, filter_key_by_used_memory):獲取當前狀態(tài)。
- redisDB.exists_key(key):檢查指定的鍵是否存在。
- redisDB.get_connect():獲取連接。
- redisDB.get_expire(key):獲取鍵的過期時間。
- redisDB.getbit(table, offsets):獲取位圖中指定偏移量的值。
- redisDB.getkeys(regex):獲取匹配指定模式的所有鍵。
- redisDB.hexists(table, key):檢查哈希表中是否存在指定的字段。
- redisDB.hget(table, key, is_pop):獲取哈希表中指定字段的值。
- redisDB.hget_count(table):獲取哈希表的字段數(shù)量。
- redisDB.hgetall(table):獲取哈希表中的所有字段和值。
- redisDB.hincrby(table, key, increment):為哈希表中的字段加上指定增量。
- redisDB.hkeys(table):獲取哈希表中的所有字段。
- redisDB.hset_batch(table, datas):批量設置哈希表中的字段值
- redisDB.lget_count(table):獲取列表的長度。
- redisDB.lpop(table, count):移除并返回列表的第一個元素。
- redisDB.lrem(table, value, num):移除列表元素。
- redisDB.rpoplpush(from_table, to_table):移除列表的最后一個元素,并將該元素添加到另一個列表。
- redisDB.sdelete(table):刪除集合。
- redisDB.set_expire(key, seconds):設置鍵的過期時間。
- redisDB.setbit(table, offsets, values):對字符串的指定偏移量設置位值。
- redisDB.sget(table, count, is_pop):獲取集合中的元素。
- redisDB.sget_count(table):獲取集合的元素數(shù)量。
- redisDB.sismember(table, key):檢查集合中是否存在指定的元素。
- redisDB.str_incrby(table, value):將存儲的數(shù)字值增一。
- redisDB.strget(table):獲取字符串值。
- redisDB.strlen(table):獲取字符串的長度。
- redisDB.strset(table, value, **kwargs):設置字符串的值。
- redisDB.zadd(table, values, prioritys):將一個或多個成員及其分數(shù)添加到有序集合中。
- redisDB.zexists(table, values):檢查有序集合中是否存在指定的成員。
- redisDB.zget(table, count, is_pop):獲取有序集合中的成員。
- redisDB.zget_count(table, priority_min, priority_max):獲取指定分數(shù)范圍內的成員數(shù)量。
- redisDB.zincrby(table, amount, value):有序集合中對指定成員的分數(shù)進行增量操作。
- redisDB.zrangebyscore(table, priority_min, priority_max, count, is_pop):通過分數(shù)返回有序集合指定區(qū)間內的成員。
- redisDB.zrangebyscore_increase_score(table, priority_min, priority_max, increase_score, count):通過分數(shù)返回有序集合指定區(qū)間內的成員,并增加分數(shù)。
- redisDB.zrangebyscore_set_score(table, priority_min, priority_max, score, count):通過分數(shù)返回有序集合指定區(qū)間內的成員,并設置分數(shù)。
- redisDB.zremrangebyscore(table, priority_min, priority_max):根據(jù)分數(shù)移除有序集合中的成員
- from feapder.db.redisdb import Encoder:redis對數(shù)據(jù)進行編碼或序列化的工具
- from feapder.db.memorydb import MemoryDB:memory基于內存的隊列
- memoryDB = MemoryDB():創(chuàng)建對象
- memoryDB.priority_queue:優(yōu)先級隊列
- memoryDB.get():獲取數(shù)據(jù)
- memoryDB.add(item, ignore_max_size):添加數(shù)據(jù)
- memoryDB.empty():檢查是否為空
- from feapder.db.mongodb import MongoDB:mongoDB數(shù)據(jù)庫
- mongoDB = MongoDB(ip,port,db,user_name,user_pass,urle,**kwargs):連接數(shù)據(jù)庫
ip:MongoDB 服務器的 IP 地址。port:MongoDB 服務器的端口號。db:要連接的數(shù)據(jù)庫名稱。user_name:數(shù)據(jù)庫用戶的用戶名。user_pass:數(shù)據(jù)庫用戶的密碼。urle:數(shù)據(jù)庫的連接 URL。**kwargs:其他參數(shù)。
- mongoDB.db:MongoDB 數(shù)據(jù)庫對象。
- mongoDB.client:MongoDB 客戶端對象。
- mongoDB.add(coll_name,data,replace,update_columns,update_columns_value,insert_ignore):向指定集合中插入數(shù)據(jù)。
- mongoDB.update(coll_name, data, condition, upsert):更新集合中的數(shù)據(jù)。
- mongoDB.find(coll_name, condition, limit, **kwargs):在集合中查詢數(shù)據(jù)。
- mongoDB.delete(coll_name, condition):在集合中刪除數(shù)據(jù)。
- mongoDB.from_url(url, **kwargs):從 URL 獲取數(shù)據(jù)庫連接信息。
- mongoDB.add_batch(coll_name, datas, replace, update_columns, update_columns_value, condition_fields):批量插入數(shù)據(jù)。
- mongoDB.get_database(database):獲取指定名稱的數(shù)據(jù)庫。
- mongoDB.get_collection(coll_name, **kwargs):獲取指定名稱的集合。
- mongoDB.count(coll_name, condition, limit, **kwargs):統(tǒng)計集合中符合條件的文檔數(shù)量。
- mongoDB.create_index(coll_name, keys, unique):在集合中創(chuàng)建索引。
- mongoDB.drop_collection(coll_name):刪除指定名稱的集合。
- mongoDB.get_index(coll_name):獲取集合的索引信息。
- mongoDB.get_index_key(coll_name, index_name):獲取指定索引的鍵。
- mongoDB.run_command(command):在數(shù)據(jù)庫上運行命令。
十四、feapder.utils 工具模塊 - from feapder.utils.log import get_logger:獲取log
- get_logger(name=None,path=None,log_level=None,is_write_to_console=None,is_write_to_file=None,color=None,mode=None,max_bytes=None,backup_count=None,encoding=None):返回logging對象
name: log名path: log文件存儲路徑 如 D://xxx.log@param log_level: log等級 CRITICAL/ERROR/WARNING/INFO/DEBUG@param is_write_to_console: 是否輸出到控制臺is_write_to_file: 是否寫入到文件 默認否color:是否有顏色mode:寫文件模式max_bytes: 每個日志文件的最大字節(jié)數(shù)backup_count:日志文件保留數(shù)量encoding:日志文件編碼
- from feapder.utils.log import log:logging對象
- import feapder.utils.tools as tools:工具模塊
- tools.send_msg(msg, level='DEBUG', message_prefix=''): 發(fā)送消息,可指定消息級別和前綴。
- tools.get_ip(domain): 獲取指定域名的IP地址。
- tools.retry(retry_times=3, interval=0): 重試函數(shù),可指定重試次數(shù)和間隔時間。
- tools.get_md5(*args): 計算給定參數(shù)的MD5哈希值。
- tools.mkdir(path): 創(chuàng)建目錄。
- tools.get_json(json_str): 將JSON字符串解析為Python對象。
- tools.add_zero(n): 給數(shù)字添加前導零。
- tools.aio_wrap(loop=None, executor=None): 異步包裝器函數(shù)。
- tools.canonicalize_url(url): 規(guī)范化URL。
- tools.compile_js(js_func): 編譯JavaScript函數(shù)。
- tools.cookies2str(cookies): 將Cookie對象轉換為字符串。
- tools.cookiesjar2str(cookies): 將CookieJar對象轉換為字符串。
- tools.cut_string(text, length): 截取指定長度的字符串。
- tools.date_to_timestamp(date, time_format='%Y-%m-%d %H:%M:%S'): 將日期字符串轉換為時間戳。
- tools.del_file(path, ignore=()): 刪除文件。
- tools.del_html_js_css(content): 刪除HTML內容中的JavaScript和CSS。
- tools.del_html_tag(content, save_line_break=True, save_p=False, save_img=False): 刪除HTML內容中的標簽。
- tools.del_redundant_blank_character(text): 刪除字符串中多余的空白字符。
- tools.delay_time(sleep_time=60): 延遲指定時間。
- tools.dingding_warning(message, message_prefix=None, rate_limit=None, url=None, user_phone=None, secret=None): 發(fā)送釘釘警告消息。
- tools.download_file(url, file_path, *, call_func=None, proxies=None, data=None): 下載文件。
- tools.dumps_json(data, indent=4, sort_keys=False): 將Python對象轉換為JSON字符串。
- tools.dumps_obj(obj): 將對象轉換為字符串。
- tools.email_warning(message, title, message_prefix=None, email_sender=None, email_password=None, email_receiver=None, email_smtpserver=None, rate_limit=None): 發(fā)送電子郵件警告消息。
- tools.ensure_float(n): 確保值為浮點數(shù)。
- tools.ensure_int(n): 確保值為整數(shù)。
- tools.escape(str): 轉義字符串中的特殊字符。
- tools.exec_js(js_code): 執(zhí)行JavaScript代碼。
- tools.feishu_warning(message, message_prefix=None, rate_limit=None, url=None, user=None): 發(fā)送飛書警告消息。
- tools.fit_url(urls, identis): 匹配URL。
- tools.flatten(x): 扁平化列表。
- tools.format_json_key(json_data): 格式化JSON鍵。
- tools.format_date(date, old_format='', new_format='%Y-%m-%d %H:%M:%S'): 格式化日期字符串。
- tools.format_seconds(seconds): 格式化秒數(shù)。
- tools.format_sql_value(value): 格式化SQL值。
- tools.format_time(release_time, date_format='%Y-%m-%d %H:%M:%S'): 格式化時間。
- tools.func_timeout(timeout): 函數(shù)超時裝飾器。
- tools.reach_freq_limit(rate_limit, *key): 判斷是否達到頻率限制。
- tools.get_all_keys(datas, depth=None, current_depth=0): 獲取所有鍵。
- tools.get_all_params(url): 獲取URL中的所有參數(shù)。
- tools.get_base64(data): 獲取數(shù)據(jù)的Base64編碼。
- tools.get_before_date(current_date, days, current_date_format='%Y-%m-%d %H:%M:%S', return_date_format='%Y-%m-%d %H:%M:%S'): 獲取前幾天的日期。
- tools.get_between_date(begin_date, end_date=None, date_format='%Y-%m-%d', **time_interval): 獲取兩個日期之間的日期列表。
- tools.get_between_months(begin_date, end_date=None): 獲取兩個日期之間的月份列表。
- tools.get_cache_path(filename, root_dir=None, local=False): 獲取緩存文件路徑。
- tools.get_chinese_word(content): 獲取字符串中的中文字符。
- tools.get_conf_value(config_file, section, key): 獲取配置文件中的值。
- tools.get_cookies(response): 從響應中獲取Cookie。
- tools.get_cookies_from_selenium_cookie(cookies): 從Selenium的Cookie對象中獲取Cookie字符串。
- tools.get_cookies_from_str(cookie_str): 從字符串中獲取Cookie。
- tools.get_cookies_jar(cookies): 將Cookie字符串轉換為CookieJar對象。
- tools.get_current_date(date_format='%Y-%m-%d %H:%M:%S'): 獲取當前日期。
- tools.get_current_timestamp(): 獲取當前時間戳。
- tools.get_date_number(year=None, month=None, day=None): 獲取日期的數(shù)字表示。
- tools.get_days_of_month(year, month): 獲取指定年份和月份的天數(shù)。
- tools.get_domain(url): 獲取URL的域名。
- tools.get_english_words(content): 獲取字符串中的英文單詞。
- tools.get_file_list(path, ignore=[]): 獲取指定目錄下的文件列表。
- tools.get_file_path(file_path): 獲取文件的路徑。
- tools.get_file_type(file_name): 獲取文件的類型。
- tools.get_firstday_month(month_offset=0): 獲取指定月份的第一天。
- tools.get_firstday_of_month(date): 獲取指定日期所在月份的第一天。
- tools.get_form_data(form): 獲取表單數(shù)據(jù)。
- tools.get_full_url(root_url, sub_url): 獲取完整的URL。
- tools.get_hash(text): 獲取文本的哈希值。
- tools.get_html_by_requests(url, headers=None, code='utf-8', data=None, proxies={}, with_response=False): 使用Requests庫獲取HTML內容。
- tools.get_index_url(url): 獲取URL的索引URL。
- tools.get_info(html, regexs, allow_repeat=True, fetch_one=False, split=None): 從HTML中提取信息。
- tools.get_json_by_requests(url, params=None, headers=None, data=None, proxies={}, with_response=False, cookies=None): 使用Requests庫獲取JSON數(shù)據(jù)。
- tools.get_json_value(json_object, key): 從JSON對象中獲取指定鍵的值。
- tools.get_last_month(month_offset=0): 獲取上個月的月份
- tools.get_lastday_month(month_offset=0): 獲取指定月份的最后一天。
- tools.get_lastday_of_month(date): 獲取指定日期所在月份的最后一天。
- tools.get_localhost_ip(): 獲取本機的IP地址。
- tools.get_method(obj, name): 獲取對象中的方法。
- tools.get_month(month_offset=0): 獲取指定月份的月份。
- tools.get_oss_file_list(oss_handler, prefix, date_range_min, date_range_max=None): 獲取指定OSS存儲桶中指定前綴和日期范圍內的文件列表。
- tools.get_param(url, key): 獲取URL中指定參數(shù)的值。
- tools.get_random_email(length=None, email_types=None, special_characters=''): 獲取隨機的電子郵件地址。
- tools.get_random_password(length=8, special_characters=''): 獲取隨機密碼。
- tools.get_random_string(length=1): 獲取指定長度的隨機字符串。
- tools.get_redisdb(): 獲取Redis數(shù)據(jù)庫連接對象。
- tools.get_sha1(*args): 計算給定參數(shù)的SHA1哈希值。
- tools.get_table_row_data(table): 獲取表格中的行數(shù)據(jù)。
- tools.get_text(soup, *args): 從BeautifulSoup對象中獲取文本。
- tools.get_today_of_day(day_offset=0): 獲取指定偏移天數(shù)的日期。
- tools.get_url_md5(url): 計算URL的MD5哈希值。
- tools.get_urls(html, stop_urls=('javascript', '+', '.css', '.js', '.rar', '.xls', '.exe', '.apk', '.doc', '.jpg', '.png', '.flv', '.mp4')): 從HTML中獲取URL列表。
- tools.get_uuid(key1='', key2=''): 生成UUID。
- tools.get_year_month_and_days(month_offset=0): 獲取指定月份及其包含的天數(shù)。
- tools.iflatten(x): 迭代扁平化列表。
- tools.import_cls(cls_info): 動態(tài)導入類。
- tools.ip_to_num(ip): 將IP地址轉換為數(shù)字表示。
- tools.is_html(url): 判斷URL是否為HTML頁面。
- tools.is_exist(file_path): 判斷文件是否存在。
- tools.is_have_chinese(content): 判斷字符串中是否包含中文字符。
- tools.is_have_english(content): 判斷字符串中是否包含英文字符。
- tools.is_valid_proxy(proxy, check_url=None): 檢查代理是否有效。
- tools.is_valid_url(url): 檢查URL是否有效。
- tools.jsonp2json(jsonp): 將JSONP轉換為JSON。
- tools.key2hump(key): 將下劃線命名轉換為駝峰命名。
- tools.key2underline(key, strict=True): 將駝峰命名轉換為下劃線命名。
- tools.linkedsee_warning(message, rate_limit=3600, message_prefix=None, token=None): 發(fā)送LinkedSee警告消息。
- tools.make_batch_sql(table, datas, auto_update=False, update_columns=(), update_columns_value=()): 生成批量插入或更新SQL語句。
- tools.mkdir(path): 創(chuàng)建目錄。
- tools.memoizemethod_noargs(method): 無參數(shù)的方法緩存裝飾器。
- tools.make_item(cls, data): 根據(jù)類定義和數(shù)據(jù)生成實例對象。
- tools.make_insert_sql(table, data, auto_update=False, update_columns=(), insert_ignore=False): 生成插入SQL語句。
- tools.make_update_sql(table, data, condition): 生成更新SQL語句。
- tools.list2str(datas): 將列表轉換為字符串。
- tools.linksee_warning(message, rate_limit=3600, message_prefix=None, token=None): 發(fā)送LinkedSee警告消息。
- tools.loads_obj(obj_str): 將字符串轉換為對象。
- tools.log_function_time(func): 記錄函數(shù)執(zhí)行時間的裝飾器。
- tools.parse_url_params(url): 解析URL中的參數(shù)。
- tools.print_pretty(object): 打印對象的漂亮格式。
- tools.print_cookie2json(cookie_str_or_list): 打印Cookie字符串或列表的JSON格式。
- tools.print_params2json(url): 打印URL參數(shù)的JSON格式。
- tools.quick_to_json(text): 快速將文本轉換為JSON對象。
- tools.quote_url(url, encoding='utf-8'): 對URL進行編碼。
- tools.quote_chinese_word(text, encoding='utf-8'): 對中文字符進行編碼。
- tools.escape(str): 轉義字符串中的特殊字符。
- tools.exec_js(js_code): 執(zhí)行JavaScript代碼。
- tools.email_warning(message, title, message_prefix=None, email_sender=None, email_password=None, email_receiver=None, email_smtpserver=None, rate_limit=None): 發(fā)送電子郵件警告消息。
- tools.ensure_int(n): 確保值為整數(shù)。
- tools.re_def_supper_class(obj, supper_class): 重新定義對象的父類。
- tools.reach_freq_limit(rate_limit, *key): 判斷是否達到頻率限制。
- tools.read_file(filename, readlines=False, encoding='utf-8'): 讀取文件內容。
- tools.rename_file(old_name, new_name): 重命名文件。
- tools.retry_asyncio(retry_times=3, interval=0): 異步重試函數(shù)。
- tools.rows2json(rows, keys=None): 將數(shù)據(jù)庫查詢結果轉換為JSON格式。
- tools.replace_str(source_str, regex, replace_str=''): 使用正則表達式替換字符串。
- tools.run_safe_model(module_name): 安全運行模塊。
- tools.write_file(filename, content, mode='w', encoding='utf-8'): 寫入文件內容。
- tools.wechat_warning(message, message_prefix=None, rate_limit=None, url=None, user_phone=None, all_users=None): 發(fā)送微信警告消息。
- tools.urlencode(params): 對URL參數(shù)進行編碼。
- tools.urldecode(url): 對URL進行解碼。
- tools.unquote_url(url, encoding='utf-8'): 對URL進行解碼。
- tools.unescape(str): 反轉義字符串中的特殊字符。
- tools.transform_lower_num(data_str): 將字符串中的大寫數(shù)字轉換為小寫數(shù)字。
- tools.to_date(date_str, date_format='%Y-%m-%d %H:%M:%S'): 將日期字符串轉換為日期對象。
- tools.to_chinese(unicode_str): 將Unicode字符串轉換為中文字符串。
- tools.timestamp_to_date(timestamp, time_format='%Y-%m-%d %H:%M:%S'): 將時間戳轉換為日期字符串。
- tools.table_json(table, save_one_blank=True): 函數(shù)用于將表格數(shù)據(jù)轉換為JSON格式,并保存到文件中
- tools.switch_workspace(project_path): 函數(shù)用于切換工作目錄到指定的項目路徑
- from feapder.utils.email_sender import EmailSender:發(fā)送郵件,可在setting.py中配置
- senderEmail = EmailSender(username, password, smtpserver='smtp.163.com'):創(chuàng)建發(fā)送郵件對象
- senderEmail.send(receivers,title,content,content_type,filepath):發(fā)送郵件
- senderEmail.login():登錄
- senderEmail.quit():退出
- from feapder.utils.custom_argparse import ArgumentParser 或 from feapder import ArgumentParser:解析命令行參數(shù)并生成幫助信息,繼承argparse.ArgumentParser,官方文檔:https://docs./3/library/argparse.html#adding-arguments
- parser = ArgumentParser(prog=None,usage=None,description=None,epilog=None,parents=[],formatter_class=HelpFormatter,prefix_chars='-',fromfile_prefix_chars=None,argument_default=None, conflict_handler='error',add_help=True,allow_abbrev=True,exit_on_error=True):創(chuàng)建解析器對象
查看運行命令 python main.py --help
prog -- 程序的名稱(默認為:os.path.basename(sys.argv[0]))usage -- 使用說明消息(默認從參數(shù)自動生成)description -- 程序功能的描述epilog -- 在參數(shù)描述之后的文本parents -- 將其參數(shù)復制到此程序中的解析器formatter_class -- 用于打印幫助信息的 HelpFormatter 類prefix_chars -- 可選參數(shù)前綴字符fromfile_prefix_chars -- 前綴文件的字符,包含額外的參數(shù)argument_default -- 所有參數(shù)的默認值conflict_handler -- 表示如何處理沖突的字符串add_help -- 添加一個 -h/-help 選項allow_abbrev -- 允許對長選項進行無歧義的縮寫exit_on_error -- 確定當發(fā)生錯誤時 ArgumentParser 是否退出并顯示錯誤信息
- parser.start(args=None, namespace=None):用于啟動解析器的某些功能或流程。
- parser.add_argument(*args, **kwargs):用于向解析器添加一個命令行參數(shù),*args 通常用于指定參數(shù)的名字,**kwargs 用于指定參數(shù)的屬性和默認值
name or flags: 參數(shù)的名稱或者選項(可以是一個字符串或一個字符串列表),例如 '--input' 或 '-i'。action: 參數(shù)的動作。通??梢允?store(默認)、store_const、store_true、store_false、append、append_const、count 等。choices: 允許的參數(shù)值的列表。const: 用于 store_const 和 append_const 動作的常量值。default: 參數(shù)的默認值,如果用戶沒有提供此參數(shù)。dest: 參數(shù)被解析后的存儲屬性的名稱。help: 參數(shù)的幫助信息。metavar:參數(shù)的備用顯示名稱,如幫助中所示nargs: 參數(shù)的個數(shù),可以是一個具體的數(shù)字,也可以是 '+' 表示一個或多個,'*' 表示零個或多個。required: 是否要求必須提供此參數(shù)。type: 參數(shù)的類型,例如 int、float、str 等。
- parser.add_mutually_exclusive_group(**kwargs):創(chuàng)建一個互斥的參數(shù)組,其中只能選擇一個參數(shù)。
- parser.parse_args(args=None, namespace=None):解析命令行參數(shù)并返回一個包含參數(shù)值的命名空間(Namespace)對象。
- parser.run(args, values=None):用于運行解析器的某些功能或流程。
可打?。簆arser.functions 查看有哪些argsargs:通過add_argument添加的命令行參數(shù)values:通過add_argument添加的命令行中function的參數(shù)
- parser.error(message):用于顯示錯誤消息并終止程序執(zhí)行。
- parser.add_argument_group(*args, **kwargs):用于創(chuàng)建一個參數(shù)組,可以將相關的參數(shù)分組顯示在幫助信息中。
- parser.add_subparsers(**kwargs):創(chuàng)建一個子命令解析器,用于處理不同的子命令。
- parser.convert_arg_line_to_args(arg_line):將一個參數(shù)字符串轉換為參數(shù)列表。
- parser.exit(status=0, message=None):用于退出程序,并可選地顯示一條消息。
- parser.format_help():生成并返回幫助信息的字符串。
- parser.format_usage():生成并返回用法信息的字符串。
- parser.parse_intermixed_args(args=None, namespace=None):解析混合的位置參數(shù)和可選參數(shù)。
- parser.parse_known_args(args=None, namespace=None):解析命令行參數(shù),返回已知參數(shù)和未知參數(shù)的 Namespace 對象。
- parser.print_help(file=None):將幫助信息打印到指定文件或標準輸出。
- parser.print_usage(file=None):將用法信息打印到指定文件或標準輸出。
- parser.parse_known_intermixed_args(args=None, namespace=None):解析混合的位置參數(shù)和可選參數(shù),返回已知參數(shù)和未知參數(shù)的 Namespace 對象
- import feapder.utils.perfect_dict as perfect_dict:處理字典數(shù)據(jù)
- perfect_dict.ensure_value(value):確保值存在,如果值為 None 則返回一個空字典。
- perfect_dict.PerfectDict.get():從字典中獲取指定鍵的值,支持多級鍵訪問
- from feapder.utils import metrics:用于度量或評估某些任務的性能或指標
- metrics.init(influxdb_host=None,influxdb_port=None,influxdb_udp_port=None,influxdb_database=None,influxdb_user=None,influxdb_password=None,influxdb_measurement=None,retention_policy=None,retention_policy_duration='180d',emit_interval=60, batch_size=100, debug=False, use_udp=False,timeout=22,ssl=False, retention_policy_replication: str = '1',set_retention_policy_default=True, **kwargs):打點監(jiān)控初始化
influxdb_host: InfluxDB 主機的地址。influxdb_port: InfluxDB 使用的端口。influxdb_udp_port: InfluxDB 使用的 UDP 端口。influxdb_database: InfluxDB 數(shù)據(jù)庫的名稱。influxdb_user: InfluxDB 連接所使用的用戶名。influxdb_password: InfluxDB 連接所使用的密碼influxdb_measurement: 存儲的表,也可以在打點的時候指定retention_policy: 保留策略retention_policy_duration: 保留策略過期時間emit_interval: 打點最大間隔batch_size: 打點的批次大小debug: 是否開啟調試use_udp: 是否使用udp協(xié)議打點timeout: 與influxdb建立連接時的超時時間ssl: 是否使用https協(xié)議retention_policy_replication: 保留策略的副本數(shù), 確保數(shù)據(jù)的可靠性和高可用性。如果一個節(jié)點發(fā)生故障,其他節(jié)點可以繼續(xù)提供服務,從而避免數(shù)據(jù)丟失和服務不可用的情況set_retention_policy_default: 是否設置為默認的保留策略,當retention_policy初次創(chuàng)建時有效**kwargs: 可傳遞MetricsEmitter類的參數(shù)
- metrics.emit_any(tags,fields, classify= '', measurement= None, timestamp=None):原生的打點,不進行額外的處理
tags: influxdb的tag的字段和值fields: influxdb的field的字段和值classify: 點的類別measurement: 存儲的表timestamp: 點的時間搓,默認為當前時間
- metrics.emit_counter(key,count = 1,classify= '', tags=None, measurement=None, timestamp= None):聚合打點,即會將一段時間內的點求和,然后打一個點數(shù)和
key: 與點綁定的key值count: 點數(shù)classify: 點的類別tags: influxdb的tag的字段和值measurement: 存儲的表timestamp: 點的時間搓,默認為當前時間
- metrics.emit_timer(key= None,duration= 0, classify= '',tags= None,measurement= None,timestamp=None):時間打點,用于監(jiān)控程序的運行時長等,每個duration一個點,不會被覆蓋
key: 與點綁定的key值duration: 時長classify: 點的類別tags: influxdb的tag的字段和值measurement: 存儲的表timestamp: 點的時間搓,默認為當前時間
- metrics.emit_store(key= None,value= 0, classify= '',tags= None,measurement= None,timestamp=None):直接打點,不進行額外的處理
key: 與點綁定的key值value: 點的值classify: 點的類別tags: influxdb的tag的字段和值measurement: 存儲的表timestamp: 點的時間搓,默認為當前時間
- metrics.flush():強刷點到influxdb
- metrics.close():關閉
- from feapder.utils.metrics import MetricsEmitter
- metricsEmitter = MetricsEmitter(influxdb,batch_size=10, max_timer_seq=0,emit_interval=10,retention_policy=None, ratio=1.0, debug=False,add_hostname=False, max_points=10240,default_tags=None,):創(chuàng)建打點對象
influxdb: influxdb instancebatch_size: 打點的批次大小max_timer_seq: 每個時間間隔內最多收集多少個 timer 類型點, 0 表示不限制emit_interval: 最多等待多長時間必須打點retention_policy: 對應的 retention policyratio: store 和 timer 類型采樣率,比如 0.1 表示只有 10% 的點會留下debug: 是否打印調試日志add_hostname: 是否添加 hostname 作為 tagmax_points: 本地 buffer 最多累計多少個點
- metricsEmitter.make_point(measurement, tags, fields, timestamp=None):創(chuàng)建一個度量指標點(measurement point)
measurement: 存儲的表fields:一個字典,包含了度量的字段和其對應的值。字段通常包含了實際的測量值tags: influxdb的tag的字段和值timestamp: 點的時間搓,默認為當前時間
- metricsEmitter.get_timer_point(measurement,key = None,duration = 0,tags= None,timestamp=None,):獲取一個計時器(timer)度量指標點
measurement: 存儲的表key: 與點綁定的key值duration: 時長tags: influxdb的tag的字段和值timestamp: 點的時間搓,默認為當前時間
- metricsEmitter.get_store_point(measurement,key = None,value= 0,tags = None,timestamp=None,):獲取一個存儲(store)度量指標點
measurement: 存儲的表key: 與點綁定的key值value: 點的值tags: influxdb的tag的字段和值timestamp: 點的時間搓,默認為當前時間
- metricsEmitter.get_counter_point(measurement,key = None,count= 1,tags = None,timestamp=None,):獲取一個計數(shù)器(counter)度量指標點
measurement: 存儲的表key: 與點綁定的key值count: 點數(shù)tags: influxdb的tag的字段和值timestamp: 點的時間搓,默認為當前時間
- metricsEmitter.emit_any(*args, **kwargs):原生的打點,不進行額外的處理,方法內部實現(xiàn)make_point+emit
- metricsEmitter.emit_counter(*args, **kwargs)):聚合打點,即會將一段時間內的點求和,然后打一個點數(shù)和,方法內部實現(xiàn)get_counter_point+emit
- metricsEmitter.emit_store(*args, **kwargs):直接打點,不進行額外的處理,方法內部實現(xiàn)get_store_point+emit
- metricsEmitter.emit_timer(*args, **kwargs):時間打點,用于監(jiān)控程序的運行時長等,每個duration一個點,不會被覆蓋,方法內部實現(xiàn)get_timer_point+emit
- metricsEmitter.emit(point=None, force=False):發(fā)送度量指標點到 InfluxDB
- metricsEmitter.define_tagkv(tagk, tagvs):定義標簽鍵值對
- metricsEmitter.close():關閉
- metricsEmitter.flush():刷新緩沖區(qū),將度量指標發(fā)送到 InfluxDB
- from feapder.utils.webdriver import WebDriver:內置的自動化測試工具,繼承了selenium的WebDriver
- webDriver = WebDriver(xhr_url_regexes, **kwargs):創(chuàng)建WebDriver對象
xhr_url_regexes:用于配置 WebDriver 的一些正則表達式,以匹配 XMLHttpRequest(XHR)請求的URL。這樣可以在需要的情況下進行特定URL的處理或過濾。**kwargs:用于傳遞額外的配置項給 WebDriver 對象
- webDriver.driver:獲取當前 WebDriver 實例的底層驅動程序。
- webDriver.cookies:獲取當前頁面的 cookies 信息。
- webDriver.user_agent:獲取當前 WebDriver 的用戶代理信息。
- webDriver.url:獲取當前頁面的 URL。
- webDriver.CHROME:代表 Chrome 瀏覽器標識。
- webDriver.domain:獲取當前頁面的域名信息。
- webDriver.EDGE:代表 Edge 瀏覽器標識。
- webDriver.FIREFOX:代表 Firefox 瀏覽器標識。
- webDriver.PHANTOMJS:代表 PhantomJS 瀏覽器標識。
- webDriver.chrome_driver():用于創(chuàng)建 Chrome 瀏覽器驅動的方法。
- webDriver.get_driver():獲取當前的 WebDriver 對象。
- webDriver.edge_driver():用于創(chuàng)建 Edge 瀏覽器驅動的方法。
- webDriver.filter_kwargs():用于過濾關鍵字參數(shù)的方法。
- webDriver.firefox_driver():用于創(chuàng)建 Firefox 瀏覽器驅動的方法。
- webDriver.phantomjs_driver():用于創(chuàng)建 PhantomJS 瀏覽器驅動的方法。
- webDriver.xhr_data():用于處理 XMLHttpRequest(XHR)請求,獲取請求的數(shù)據(jù)。
- webDriver.xhr_json():用于處理 XMLHttpRequest(XHR)請求,獲取 JSON 數(shù)據(jù)。
- webDriver.xhr_response():用于處理 XMLHttpRequest(XHR)請求,獲取請求的響應。
- webDriver.xhr_text():用于處理 XMLHttpRequest(XHR)請求,獲取文本數(shù)據(jù)。
十五、mands 執(zhí)行命令行模塊 - import mands.retry as retry:重試相關的功能
- retry.retry_failed_items(redis_key):可能用于重試處理失敗的數(shù)據(jù)項(items)。
- retry.retry_failed_requests(redis_key):可能用于重試處理失敗的請求(requests)。
- retry.parse_args():可能用于解析命令行參數(shù),以獲取相應的配置信息。
- import mands.zip as zip:文件壓縮相關的功能
- zip.parse_args(): 用于解析命令行參數(shù),以獲取相應的配置信息。
- zip.zip(dir_path, zip_name, ignore_dirs=None, ignore_files=None): 用于將指定目錄下的文件進行壓縮打包。參數(shù)包括待壓縮的目錄路徑、壓縮文件的名稱、要忽略的目錄列表以及要忽略的文件列表。
- zip.is_ignore_file(ignore_files, filename): 用于判斷某個文件是否在忽略列表中。參數(shù)包括要忽略的文件列表和要判斷的文件名。
- import mands.shell as shell:命令行交互相關的功能
- shell.parse_args(): 用于解析命令行參數(shù),以獲取相應的配置信息。
- shell.request(**kwargs): 可能用于發(fā)送 HTTP 請求,并返回響應。參數(shù)可能包括了用于配置請求的各種參數(shù),如 URL、請求方式、請求頭等。
- shell.fetch_curl(): 可能用于獲取用于復制粘貼的 cURL 命令,用于模擬請求。
- shell.parse_curl(curl_str): 可能用于解析 cURL 命令,從中提取出請求的各種參數(shù),以便進行相應的操作。
- shell.usage(): 可能用于顯示命令行操作的使用說明。
十六、feapder.pipelines 管道模塊 - basePipeline = BasePipeline():創(chuàng)建管道
- basePipeline.save_items(table, items):保存數(shù)據(jù)
- basePipeline.update_items(table, items, update_keys):更新數(shù)據(jù), 與UpdateItem配合使用
- basePipeline.close():關閉
十七、代理 - 在項目中創(chuàng)建代理包:proxy
- 創(chuàng)建代理文件proxy>kuaidaili.py,這里以快代理為例:https://www./
import requestsclass Kuaidaili(): request_url = { # 獲取代理ip前面 'getIpSignature': 'https://auth./api/get_secret_token', # 獲取代理ip 'getIp': 'https://dps./api/getdps?secret_id=oy2q5xu76k4s8olx59et&num=1&signature={}' } headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36' } ip_use = '購買代理的用戶名' ip_password = '購買代理的密碼' def __init__(self): '''創(chuàng)建request會話對象''' self.request_session = requests.Session() self.request_session.headers.update(self.headers) # 獲取代理ip簽名 @classmethod def get_ip_url(cls): par = { 'secret_id': 'oy2q5xu76k4s8olx59et', 'secret_key': '5xg6gvouc0vszfw0kxs1a8vrw1r6ity7' } response = requests.post(cls.request_url['getIpSignature'],data=par) response_data = response.json() return cls.request_url['getIp'].format(response_data['data']['secret_token']) @classmethod def get_all_ip(cls): url = cls.get_ip_url() response = requests.get(url) return f'http://{cls.ip_use}:{cls.ip_password}@{response.text}' @classmethod def get_ip(cls): url = cls.get_ip_url() response = requests.get(url) return f'{cls.ip_use}:{cls.ip_password}@{response.text}'if __name__ == '__main__': kuaidaili = Kuaidaili()
- 直接給請求指定代理,爬蟲文件
import feapderfrom proxy.kuaidaili import Kuaidailiclass AirSpiderDouban(feapder.AirSpider): def __init__(self, thread_count=None): super().__init__(thread_count) self.request_url = 'https://movie.douban.com/top250' # ip代理 self.kuaidaili = Kuaidaili() proxy_ip = self.kuaidaili.get_all_ip() self.proxies = { 'http': proxy_ip, 'https': proxy_ip } print(f'當前代理{self.proxies}') def start_requests(self): yield feapder.Request('https://www.baidu.com') def download_midware(self, request): # 這里使用代理使用即可 request.proxies = self.proxies return request def parse(self, request, response): print(response) def exception_request(self, request, response, e): prox_err = [ConnectTimeout,ProxyError] if type(e) in prox_err: request.del_proxy()
- 配置文件setting.py中配置代理,在快代理中需要先設置白名單,設置白名單后ip可以免密碼使用,如不想設置白名單可自定義代理池
PROXY_EXTRACT_API = None # 代理提取API ,返回的代理分割符為\r\nPROXY_ENABLE = TruePROXY_MAX_FAILED_TIMES = 5 # 代理最大失敗次數(shù),超過則不使用,自動刪除
- 自定義代理池
- 創(chuàng)建proxy>proxypool.py代理池文件
from feapder.network.proxy_pool import BaseProxyPoolfrom proxy import kuaidailifrom queue import Queueimport feapder.utils.tools as toolsfrom feapder.utils import metricsclass MyProxyPool(BaseProxyPool): def __init__(self): self.kuaidaili = kuaidaili.Kuaidaili() self.proxy_queue = Queue() def format_proxy(self, proxy): return {'http': proxy, 'https': proxy} def get_proxy(self): try: if self.proxy_queue.empty(): proxy_ip = self.kuaidaili.get_ip() self.proxy_queue.put_nowait(proxy_ip) proxy = self.proxy_queue.get_nowait() self.proxy_queue.put_nowait(proxy) metrics.emit_counter('used_times', 1, classify='proxy') return self.format_proxy(proxy) except Exception as e: tools.send_msg('獲取代理失敗', level='error') raise Exception('獲取代理失敗', e) def del_proxy(self, proxy): ''' @summary: 刪除代理 --------- @param proxy: ip:port ''' if proxy in self.proxy_queue.queue: self.proxy_queue.queue.remove(proxy) metrics.emit_counter('invalid', 1, classify='proxy') self.get_proxy()
PROXY_EXTRACT_API = True # 代理提取API ,返回的代理分割符為\r\nPROXY_ENABLE = TruePROXY_MAX_FAILED_TIMES = 5 # 代理最大失敗次數(shù),超過則不使用,自動刪除PROXY_POOL = 'proxy.proxypool.MyProxyPool' # 代理池
import feapderclass AirSpiderDouban(feapder.AirSpider): def start_requests(self): yield feapder.Request('https://www.baidu.com') def parse(self, request, response): print(response) def exception_request(self, request, response): prox_err = [ConnectTimeout,ProxyError] if type(e) in prox_err: request.del_proxy()
十八、去重 - 修改setting.py配置文件
# # REDIS# # ip:port 多個可寫為列表或者逗號隔開 如 ip1:port1,ip2:port2 或 ['ip1:port1', 'ip2:port2']REDISDB_IP_PORTS = 'localhost:6379'REDISDB_USER_PASS = ''REDISDB_DB = 0# 連接redis時攜帶的其他參數(shù),如ssl=TrueREDISDB_KWARGS = dict()# 適用于redis哨兵模式REDISDB_SERVICE_NAME = ''# # 去重ITEM_FILTER_ENABLE = True # item 去重# REQUEST_FILTER_ENABLE = False # request 去重ITEM_FILTER_SETTING = dict( filter_type=1, # 永久去重(BloomFilter) = 1 、內存去重(MemoryFilter) = 2、 臨時去重(ExpireFilter)= 3、輕量去重(LiteFilter)= 4 name='douban')# REQUEST_FILTER_SETTING = dict(# filter_type=3, # 永久去重(BloomFilter) = 1 、內存去重(MemoryFilter) = 2、 臨時去重(ExpireFilter)= 3、 輕量去重(LiteFilter)= 4# expire_time=2592000, # 過期時間1個月# )
- Dedup參數(shù):用于配置REQUEST_FILTER_SETTING、ITEM_FILTER_SETTING
- filter_type:去重類型,支持BloomFilter、MemoryFilter、ExpireFilter三種
- redis_url:不是必須傳遞的,若項目中存在setting.py文件,且已配置redis連接方式,則可以不傳遞redis_url
- name: 過濾器名稱 該名稱會默認以dedup作為前綴 dedup:expire_set:[name]或dedup:bloomfilter:[name]。 默認ExpireFilter name=過期時間,BloomFilter name=dedup:bloomfilter:bloomfilter
- absolute_name:過濾器絕對名稱 不會加dedup前綴
- expire_time:ExpireFilter的過期時間 單位為秒,其他兩種過濾器不用指定
- error_rate:BloomFilter/MemoryFilter的誤判率 默認為0.00001
- to_md5:去重前是否將數(shù)據(jù)轉為MD5,默認是
- 修改item文件,增加__unique_key__
from feapder import Itemclass DoubanItem(Item): ''' This class was generated by feapder command: feapder create -i douban ''' __table_name__ = 'douban' __unique_key__ = ['title','quote','rating','title'] # 指定去重的key為 title、quote,最后的指紋為title與quote值聯(lián)合計算的md5 def __init__(self, *args, **kwargs): super().__init__(**kwargs) # self.id = None self.intro = None self.quote = None self.rating = None self.title = None
十九、郵件報警 - 需要根據(jù)官網文檔郵件報警配置163郵箱,https:///#/source_code/%E6%8A%A5%E8%AD%A6%E5%8F%8A%E7%9B%91%E6%8E%A7
- 修改setting.py配置
EMAIL_SENDER = '123123123@163.com' # 發(fā)件人EMAIL_PASSWORD = 'EYNXMBWJKMLZFTKQ' # 授權碼EMAIL_RECEIVER = ['123123123@163.com'] # 收件人 支持列表,可指定多個EMAIL_SMTPSERVER = 'smtp.163.com' # 郵件服務器 默認為163郵箱
- 修改爬蟲文件
import feapderfrom feapder.network.user_agent import get as get_uafrom requests.exceptions import ConnectTimeout,ProxyErrorfrom feapder.utils.email_sender import EmailSenderimport feapder.setting as settingclass AirSpiderDouban(feapder.AirSpider): def __init__(self, thread_count=None): super().__init__(thread_count) self.request_url = 'https://www.baidu.com' def start_requests(self): yield feapder.Request(self.request_url) def parse(self, request, response): pass def end_callback(self): with EmailSender(setting.EMAIL_SENDER,setting.EMAIL_PASSWORD) as email_sender: email_sender.send(setting.EMAIL_RECEIVER, title='python',content='爬蟲結束')if __name__ == '__main__': AirSpiderDouban(thread_count=5).start()
二十、自定義管道 - 創(chuàng)建pipeline包
- 創(chuàng)建pipeline>mysql_pipeline.py文件
from feapder.pipelines import BasePipelineclass MysqlPipeline(BasePipeline): def save_items(self, table, items): print('自定義pipeline, 保存數(shù)據(jù) >>>>', table, items) return True def update_items(self, table, items, update_keys): print('自定義pipeline, 更新數(shù)據(jù) >>>>', table, items, update_keys) return True
- 修改setting.py文件
ITEM_PIPELINES = [ 'pipeline.mysql_pipeline.MysqlPipeline',]
|