基于golang實(shí)現(xiàn)的爬蟲框架,編寫簡單,性能強(qiáng)勁,內(nèi)置了豐富的實(shí)用中間件,支持多種解析、保存方式。
Feature
- 編寫簡單,性能強(qiáng)勁。
- 內(nèi)置多種實(shí)用中間件,開發(fā)起來更輕松。
- 支持多種解析方式,解析頁面更簡單。
- 支持多種保存方式,數(shù)據(jù)存儲更靈活。
- 提供了豐富的配置選項(xiàng),配置更自由。
- 組件支持自定義,擴(kuò)展功能更簡單。
- 內(nèi)置開發(fā)服務(wù),調(diào)試開發(fā)更方便。
Usage
-
基本架構(gòu)
- Spider:在Spider里可以發(fā)起請求和解析內(nèi)容。您需要使用
spider.SetName(name)方法為每個Spider設(shè)置一個唯一名稱。 - BaseSpider:BaseSpider實(shí)現(xiàn)了Spider的公共方法,避免了在每個Spider中重復(fù)編寫相同的代碼。
- Crawler:Crawler集成了Spider、Downloader(下載器)、Exporter(導(dǎo)出器)、Scheduler(調(diào)度器)等組件,是爬蟲的邏輯處理中心。
- Spider:在Spider里可以發(fā)起請求和解析內(nèi)容。您需要使用
-
crawler選項(xiàng)。
- WithMode 設(shè)置模式(Mode)。
- WithPlatforms 設(shè)置瀏覽器平臺(Platforms)。
- WithBrowsers 設(shè)置瀏覽器(Browsers)。
- WithLogger 設(shè)置日志(Logger)。
- WithFilter 設(shè)置過濾器(Filter)。
- WithDownloader 設(shè)置下載器(Downloader)。
- WithExporter 設(shè)置導(dǎo)出器(Exporter)。
- WithMiddleware 設(shè)置中間件(Middleware)。
- WithStatsMiddleware 設(shè)置統(tǒng)計中間件,用于記錄和統(tǒng)計爬蟲的性能和運(yùn)行情況。
- WithDumpMiddleware 設(shè)置打印中間件。
- WithProxyMiddleware 設(shè)置代理中間件,用于使用代理服務(wù)器進(jìn)行爬取。
- WithRobotsTxtMiddleware 設(shè)置開啟robots.txt支持中間件,用于遵守網(wǎng)站的 robots.txt 規(guī)則。
- WithFilterMiddleware 設(shè)置過濾器中間件,用于過濾已處理的請求。
- WithFileMiddleware 設(shè)置文件中間件,用于處理文件下載請求。
- WithImageMiddleware 設(shè)置圖像中間件,用于處理圖像下載請求。
- WithHttpMiddleware 設(shè)置 HTTP 中間件。
- WithRetryMiddleware 設(shè)置重試中間件,用于在請求失敗時進(jìn)行自動重試。
- WithUrlMiddleware 設(shè)置 URL 中間件。
- WithReferrerMiddleware 設(shè)置 Referrer 中間件,用于自動設(shè)置請求的 Referrer 頭。
- WithCookieMiddleware 設(shè)置 Cookie 中間件,用于處理請求和響應(yīng)中的 Cookie,自動在接下來的請求設(shè)置之前的 Cookie。
- WithRedirectMiddleware 設(shè)置重定向中間件,用于自動處理請求的重定向,跟隨重定向鏈接并獲取最終響應(yīng)。
- WithChromeMiddleware 設(shè)置 Chrome 中間件,用于模擬 Chrome 瀏覽器。
- WithHttpAuthMiddleware 設(shè)置開啟HTTP認(rèn)證中間件,用于處理需要認(rèn)證的網(wǎng)站。
- WithCompressMiddleware 設(shè)置壓縮中間件,用于處理請求和響應(yīng)的壓縮。當(dāng)爬蟲發(fā)送請求或接收響應(yīng)時,該中間件可以自動處理壓縮算法,解壓縮請求或響應(yīng)的內(nèi)容。
- WithDecodeMiddleware 設(shè)置解碼中間件,用于處理請求和響應(yīng)的解碼操作。該中間件可以處理請求或響應(yīng)中的編碼內(nèi)容。
- WithDeviceMiddleware 設(shè)置開啟設(shè)備模擬中間件
- WithCustomMiddleware 設(shè)置自定義中間件,允許用戶定義自己的中間件組件。
- WithPipeline 設(shè)置Pipeline,用于處理爬取的數(shù)據(jù)并進(jìn)行后續(xù)操作。
- WithDumpPipeline 設(shè)置打印管道。
- WithFilePipeline 設(shè)置文件管道,用于處理爬取的文件數(shù)據(jù),將文件保存到指定位置。
- WithImagePipeline 設(shè)置圖像管道,用于處理爬取的圖像數(shù)據(jù),將保存圖像到指定位置。
- WithFilterPipeline 設(shè)置過濾器管道,用于過濾爬取過的數(shù)據(jù)。
- WithCsvPipeline 設(shè)置 CSV 數(shù)據(jù)處理管道,將爬取的數(shù)據(jù)保存為 CSV 格式。
- WithJsonLinesPipeline 設(shè)置 JSON Lines 數(shù)據(jù)處理管道,將爬取的數(shù)據(jù)保存為 JSON Lines 格式。
- WithMongoPipeline 設(shè)置 MongoDB 數(shù)據(jù)處理管道,將爬取的數(shù)據(jù)保存到 MongoDB 數(shù)據(jù)庫。
- WithMysqlPipeline 設(shè)置 MySQL 數(shù)據(jù)處理管道,將爬取的數(shù)據(jù)保存到 MySQL 數(shù)據(jù)庫。
- WithKafkaPipeline 設(shè)置 Kafka 數(shù)據(jù)處理管道,將爬取的數(shù)據(jù)發(fā)送到 Kafka 消息隊(duì)列。
- WithCustomPipeline 設(shè)置自定義數(shù)據(jù)處理管道。
- WithRetryMaxTimes 設(shè)置請求的最大重試次數(shù)(RetryMaxTimes)。
- WithTimeout 設(shè)置請求的超時時間(Timeout)。
- WithInterval 設(shè)置請求的間隔時間(Interval)。
- WithOkHttpCodes 設(shè)置正常的HTTP狀態(tài)碼(OkHttpCodes)。
-
Item
Item用于存儲需要導(dǎo)出的數(shù)據(jù)和一些其他輔助信息。
框架里內(nèi)置的Item涵蓋了主要文件、數(shù)據(jù)庫、消息隊(duì)列等存儲方式。
pkg.Item是一個接口,不能直接使用。pkg.ItemUnimplemented實(shí)現(xiàn)了pkg.Item的所有方法。
如果Item需要實(shí)現(xiàn)pkg.Item,可以組合pkg.ItemUnimplemented。 如:type ItemNone struct { pkg.ItemUnimplemented }- Item有一些通用方法:
-
GetName() pkg.ItemName
獲取Item的具體類型,如pkg.ItemNone、pkg.ItemCsv、pkg.ItemJsonl、pkg.ItemMongo、pkg.ItemMysql、pkg.ItemKafka等,用于Item反序列化到具體Item實(shí)現(xiàn)。 -
SetReferrer(string)設(shè)置referrer,可以用于記錄請求的來源,一般不需要自己設(shè)置,由ReferrerMiddleware自動設(shè)置。 -
GetReferrer() string獲取referrer。 -
SetUniqueKey(string)設(shè)置uniqueKey,可以用于過濾和其他唯一用途。 -
GetUniqueKey() string獲取uniqueKey。 -
SetId(any)設(shè)置id,主要用于保存數(shù)據(jù)時的主鍵,和uniqueKey的一個區(qū)別是,id可能是在Response中產(chǎn)生,請求時不一定能獲得。 -
GetId() any獲取id。 -
SetData(any)設(shè)置data,這是要存儲的完整數(shù)據(jù)。為了規(guī)范化,強(qiáng)制要求指針類型。存儲到不同的目標(biāo)時,data需要設(shè)置不同的格式。 -
GetData() any獲取data。 -
SetFilesRequest([]pkg.Request)設(shè)置文件的請求。這是一個slice,可以下載多個文件。 -
GetFilesRequest() []pkg.Request獲取文件的請求。 -
SetFiles([]pkg.File)設(shè)置文件。下載后的文件通過這個方法設(shè)置到Item中。 -
GetFiles() []pkg.File獲取文件。 -
SetImagesRequest([]pkg.Request)設(shè)置圖片的請求。這是一個slice,可以下載多個圖片。 -
GetImagesRequest() []pkg.Request獲取圖片的請求。 -
SetImages([]pkg.Image)設(shè)置圖片。下載后的圖片通過這個方法設(shè)置到Item中。 -
GetImages() []pkg.Image獲取圖片。
-
- 內(nèi)置Item實(shí)現(xiàn):框架提供了一些內(nèi)置的Item實(shí)現(xiàn),如pkg.ItemNone、pkg.ItemCsv、pkg.ItemJsonl、pkg.ItemMongo、pkg.ItemMysql、pkg.ItemKafka等。
您可以根據(jù)需要,返回Item,并開啟相應(yīng)的Pipeline。如:err = s.YieldItem(ctx, items.NewItemMongo(s.collection, true). SetUniqueKey(extra.Keyword). SetId(extra.Keyword). SetData(&data))app.NewApp(NewSpider, pkg.WithMongoPipeline(), ).Run()- pkg.ItemNone 這個Item沒有實(shí)現(xiàn)任何其他方法,主要用于調(diào)試。
items.NewItemNone()
- pkg.ItemCsv 保存到csv中。
items.NewItemCsv(filename string)- filename 存儲的文件名,不包括拓展名
- pkg.ItemJsonl 保存到j(luò)sonl中。
items.NewItemJsonl(filename string)- filename 存儲的文件名,不包括拓展名
- pkg.ItemMongo 保存到mongo中。
items.NewItemMongo(collection string, update bool)- collection mongo collection
- update 如果數(shù)據(jù)已存在mongo中,是否更新
- pkg.ItemMysql 保存到mysql中。
items.NewItemMysql(table string, update bool)- table mysql table
- update 如果數(shù)據(jù)已存在mongo中,是否更新
- pkg.ItemKafka 保存到kafka中。
items.NewItemKafka(topic string)- topic kafka topic
- pkg.ItemNone 這個Item沒有實(shí)現(xiàn)任何其他方法,主要用于調(diào)試。
- Item有一些通用方法:
middleware/pipeline包括框架內(nèi)置、公共自定義(internal/middlewares,internal/pipelines)和爬蟲內(nèi)自定義(和爬蟲同module)。
請確保不同中間件和Pipeline的order值不重復(fù)。如果有重復(fù)的order值,后面的中間件或Pipeline將替換前面的中間件或Pipeline。
-
在框架中,內(nèi)置的中間件具有預(yù)定義的order值,這些order值是10的倍數(shù),例如10、20、30等。
為了避免與內(nèi)置中間件的order沖突,建議自定義中間件時選擇不同的order值。
當(dāng)您自定義中間件時,請選擇避開內(nèi)置中間件的order值。
根據(jù)中間件的功能和需求,按照預(yù)期的執(zhí)行順序進(jìn)行配置。確保較低order值的中間件先執(zhí)行,然后依次執(zhí)行較高order值的中間件。
內(nèi)置的中間件和自定義中間件使用默認(rèn)的order值即可。
如果需要改變默認(rèn)的order值,需要在NewApp中加入crawler選項(xiàng)pkg.WithMiddleware(new(middleware), order)啟用該中間件并應(yīng)用該order值。- custom: 10
- 自定義中間件
- 在NewApp中加入crawler選項(xiàng)
pkg.WithCustomMiddleware(new(CustomMiddleware))啟用該中間件。
- dump: 20
- 控制臺打印item.data中間件,用于打印請求和響應(yīng)的詳細(xì)信息。
- 可以通過配置項(xiàng)enable_dump_middleware來啟用或禁用,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithDumpMiddleware()
- proxy: 30
- 用于切換請求使用的代理。
- 可以通過配置項(xiàng)enable_proxy_middleware來啟用或禁用,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithProxyMiddleware()
- robotsTxt: 40
- robots.txt支持中間件,用于支持爬取網(wǎng)站的robots.txt文件。
- 可以通過配置項(xiàng)enable_robots_txt_middleware來啟用或禁用,默認(rèn)禁用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithRobotsTxtMiddleware()
- filter: 50
- 過濾重復(fù)請求中間件,用于過濾重復(fù)的請求。默認(rèn)只有在Item保存成功后才會進(jìn)入去重隊(duì)列。
- 可以通過配置項(xiàng)enable_filter_middleware來啟用或禁用,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithFilterMiddleware()
- file: 60
- 自動添加文件信息中間件,用于自動添加文件信息到請求中。
- 可以通過配置項(xiàng)enable_file_middleware來啟用或禁用,默認(rèn)禁用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithFileMiddleware()
- image: 70
- 自動添加圖片的寬高等信息中間件
- 用于自動添加圖片信息到請求中??梢酝ㄟ^配置項(xiàng)enable_image_middleware來啟用或禁用,默認(rèn)禁用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithImageMiddleware()
- retry: 80
- 請求重試中間件,用于在請求失敗時進(jìn)行重試。
- 默認(rèn)最大重試次數(shù)為10??梢酝ㄟ^配置項(xiàng)enable_retry_middleware來啟用或禁用,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithRetryMiddleware()
- url: 90
- 限制URL長度中間件,用于限制請求的URL長度。
- 可以通過配置項(xiàng)enable_url_middleware和url_length_limit來啟用和設(shè)置最長URL長度,默認(rèn)啟用和最長長度為2083。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithUrlMiddleware()
- referrer: 100
- 自動添加Referrer中間件,用于自動添加Referrer到請求中。
- 可以根據(jù)referrer_policy配置項(xiàng)選擇不同的Referrer策略,DefaultReferrerPolicy會加入請求來源,NoReferrerPolicy不加入請求來源
- 配置 enable_referrer_middleware: true 是否開啟自動添加referrer,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithReferrerMiddleware()
- cookie: 110
- 自動添加Cookie中間件,用于自動添加之前請求返回的Cookie到后續(xù)請求中。
- 可以通過配置項(xiàng)enable_cookie_middleware來啟用或禁用,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithCookieMiddleware()
- redirect: 120
- 網(wǎng)址重定向中間件,用于處理網(wǎng)址重定向,默認(rèn)支持301和302重定向。
- 可以通過配置項(xiàng)enable_redirect_middleware和redirect_max_times來啟用和設(shè)置最大重定向次數(shù),默認(rèn)啟用和最大次數(shù)為1。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithRedirectMiddleware()
- chrome: 130
- 模擬Chrome中間件,用于模擬Chrome瀏覽器。
- 可以通過配置項(xiàng)enable_chrome_middleware來啟用或禁用,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithChromeMiddleware()
- httpAuth: 140
- HTTP認(rèn)證中間件,通過提供用戶名(username)和密碼(password)進(jìn)行HTTP認(rèn)證。
- 需要在具體的請求中設(shè)置用戶名和密碼??梢酝ㄟ^配置項(xiàng)enable_http_auth_middleware來啟用或禁用,默認(rèn)禁用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithHttpAuthMiddleware()
- compress: 150
- 支持gzip/deflate解壓縮中間件,用于處理響應(yīng)的壓縮編碼。
- 可以通過配置項(xiàng)enable_compress_middleware來啟用或禁用,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithCompressMiddleware()
- decode: 160
- 中文解碼中間件,支持對響應(yīng)中的GBK、GB2312和Big5編碼進(jìn)行解碼。
- 可以通過配置項(xiàng)enable_decode_middleware來啟用或禁用,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithDecodeMiddleware()
- device: 170
- 修改請求設(shè)備信息中間件,用于修改請求的設(shè)備信息,包括請求頭(header)和TLS信息。目前只支持User-Agent隨機(jī)切換。
- 需要設(shè)置設(shè)備范圍(Platforms)和瀏覽器范圍(Browsers)。
- Platforms: Windows/Mac/Android/Iphone/Ipad/Linux
- Browsers: Chrome/Edge/Safari/FireFox
- 可以通過配置項(xiàng)enable_device_middleware來啟用或禁用,默認(rèn)禁用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithDeviceMiddleware()啟用該中間件。
- http: 200
- 創(chuàng)建請求中間件,用于創(chuàng)建HTTP請求。
- 可以通過配置項(xiàng)enable_http_middleware來啟用或禁用,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithHttpMiddleware()
- stats: 210
- 數(shù)據(jù)統(tǒng)計中間件,用于統(tǒng)計爬蟲的請求、響應(yīng)和處理情況。
- 可以通過配置項(xiàng)enable_stats_middleware來啟用或禁用,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithStatsMiddleware()
- custom: 10
-
Pipeline用于流式處理Item,如數(shù)據(jù)過濾、數(shù)據(jù)存儲等。
通過配置不同的Pipeline,您可以方便地處理Item并將結(jié)果保存到不同的目標(biāo),如控制臺、文件、數(shù)據(jù)庫或消息隊(duì)列中。
內(nèi)置的Pipeline和自定義Pipeline使用默認(rèn)的order值即可。
如果需要改變默認(rèn)的order值,需要在NewApp中加入crawler選項(xiàng)pkg.WithPipeline(new(pipeline), order)啟用該P(yáng)ipeline并應(yīng)用該order值。- dump: 10
- 用于在控制臺打印Item的詳細(xì)信息。
- 您可以通過配置enable_dump_pipeline來控制是否啟用該P(yáng)ipeline,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithDumpPipeline()啟用該P(yáng)ipeline。
- file: 20
- 用于下載文件并保存到Item中。
- 您可以通過配置enable_file_pipeline來控制是否啟用該P(yáng)ipeline,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithFilePipeline()啟用該P(yáng)ipeline。
- image: 30
- 用于下載圖片并保存到Item中。
- 您可以通過配置enable_image_pipeline來控制是否啟用該P(yáng)ipeline,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithImagePipeline()啟用該P(yáng)ipeline。
- filter: 200
- 用于對Item進(jìn)行過濾。
- 它可用于去重請求,需要在中間件同時啟用filter。
- 默認(rèn)情況下,Item只有在成功保存后才會進(jìn)入去重隊(duì)列。
- 您可以通過配置enable_filter_pipeline來控制是否啟用該P(yáng)ipeline,默認(rèn)啟用。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithFilterPipeline()啟用該P(yáng)ipeline。
- csv: 101
- 用于將結(jié)果保存到CSV文件中。
- 需要在ItemCsv中設(shè)置
FileName,指定保存的文件名稱(不包含.csv擴(kuò)展名)。 - 您可以使用tag
column:""來定義CSV文件的列名。 - 您可以通過配置enable_csv_pipeline來控制是否啟用該P(yáng)ipeline,默認(rèn)關(guān)閉。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithCsvPipeline()啟用該P(yáng)ipeline。
- jsonLines: 102
- 用于將結(jié)果保存到JSON Lines文件中。
- 需要在ItemJsonl中設(shè)置
FileName,指定保存的文件名稱(不包含.jsonl擴(kuò)展名)。 - 您可以使用tag
json:""來定義JSON Lines文件的字段。 - 您可以通過配置enable_json_lines_pipeline來控制是否啟用該P(yáng)ipeline,默認(rèn)關(guān)閉。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithJsonLinesPipeline()啟用該P(yáng)ipeline。
- mongo: 103
- 用于將結(jié)果保存到MongoDB中。
- 需要在ItemMongo中設(shè)置
Collection,指定保存的collection名稱。 - 您可以使用tag
bson:""來定義MongoDB文檔的字段。 - 您可以通過配置enable_mongo_pipeline來控制是否啟用該P(yáng)ipeline,默認(rèn)關(guān)閉。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithMongoPipeline()啟用該P(yáng)ipeline。
- mysql: 104
- 用于將結(jié)果保存到MySQL中。
- 需要在ItemMysql中設(shè)置
Table,指定保存的表名。 - 您可以使用tag
column:""來定義MySQL表的列名。 - 您可以通過配置enable_mysql_pipeline來控制是否啟用該P(yáng)ipeline,默認(rèn)關(guān)閉。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithMysqlPipeline()啟用該P(yáng)ipeline。
- kafka: 105
- 用于將結(jié)果保存到Kafka中。
- 需要在ItemKafka中設(shè)置
Topic,指定保存的主題名。 - 您可以使用tag
json:""來定義Kafka消息的字段。 - 您可以通過配置enable_kafka_pipeline來控制是否啟用該P(yáng)ipeline,默認(rèn)關(guān)閉。
- 在NewApp中加入crawler選項(xiàng)
pkg.WithKafkaPipeline()啟用該P(yáng)ipeline。
- custom: 110
- 自定義pipeline
- 在NewApp中加入crawler選項(xiàng)
pkg.WithCustomPipeline(new(CustomPipeline))啟用該P(yáng)ipeline。
- dump: 10
信號(Signal)是一種機(jī)制,用于在運(yùn)行時處理外部發(fā)出的操作指令。通過捕獲和處理信號,您可以實(shí)現(xiàn)對爬蟲的控制和管理
在配置文件中配置全局的請求參數(shù),并在具體的請求中可以覆蓋這些全局配置,可以提供更靈活和細(xì)粒度的請求定制
-
框架內(nèi)置了多個解析模塊。這些解析模塊提供了不同的選擇器和語法,以適應(yīng)不同的數(shù)據(jù)提取需求。您可以根據(jù)具體的爬蟲任務(wù)和數(shù)據(jù)結(jié)構(gòu),選擇適合您的解析模塊和語法,從網(wǎng)頁響應(yīng)中準(zhǔn)確地提取所需的數(shù)據(jù)。
- query選擇器 go-query是一個處理query選擇器的庫 go-query
- 通過調(diào)用
response.Query()方法,您可以使用query選擇器語法來從HTML或XML響應(yīng)中提取數(shù)據(jù)。
- 通過調(diào)用
- xpath選擇器 go-xpath是一個可用于XPath選擇的庫 go-xpath
- 通過調(diào)用
response.Xpath()方法,您可以使用XPath表達(dá)式來從HTML或XML響應(yīng)中提取數(shù)據(jù)。
- 通過調(diào)用
- gjson gjson是一個用于處理JSON的庫
- 通過調(diào)用
response.Json()方法,您可以使用gjson語法從JSON響應(yīng)中提取數(shù)據(jù)。
- 通過調(diào)用
- re選擇器 go-re是一個處理正則的庫 go-re
- 通過調(diào)用
response.Re()方法,您可以使用正則表達(dá)式從響應(yīng)中提取數(shù)據(jù)。
- 通過調(diào)用
- query選擇器 go-query是一個處理query選擇器的庫 go-query
-
代理。它可以幫助爬蟲在請求網(wǎng)站時隱藏真實(shí)IP地址。
- 自行搭建隧道代理:您可以使用 go-proxy
等工具來搭建隧道代理。這些代理工具可以提供隨機(jī)切換的代理功能,對調(diào)用方無感知,方便使用。
您可以在爬蟲框架中集成這些代理工具,以便在爬蟲請求時自動切換代理。
這是一個隨機(jī)切換的隧道代理,調(diào)用方無感知,方便使用。后期會加入一些其他的調(diào)用方式,比如維持原來的代理地址。 - 其他調(diào)用方式:除了隨機(jī)切換的代理方式,后期可以考慮加入其他的調(diào)用方式。
例如,保持原來的代理地址不變,或者使用其他代理池工具進(jìn)行代理IP的管理和調(diào)度。這樣可以提供更多靈活性和選擇性,以滿足不同的代理需求。
- 自行搭建隧道代理:您可以使用 go-proxy
-
要提高爬蟲的性能,您可以考慮關(guān)閉一些未使用的中間件或Pipeline,以減少不必要的處理和資源消耗。以下是一些建議:
- 檢查中間件:審查已配置的中間件,并根據(jù)需要禁用不使用的中間件。您可以在配置文件中進(jìn)行修改,或者在爬蟲的入口方法中進(jìn)行相應(yīng)的配置更改。
- 禁用不需要的Pipeline:檢查已配置的Pipeline,并禁用不需要的Pipeline。
例如,如果您不需要保存結(jié)果到MongoDB,可以禁用MongoPipeline。 - 評估性能影響:在禁用中間件或Pipeline之前,請?jiān)u估其對爬蟲性能的實(shí)際影響。確保禁用的部分不會對功能產(chǎn)生負(fù)面影響。
- 可以禁用的配置:
- enable_dump_middleware: false
- enable_filter_middleware: false
- enable_file_middleware: false
- enable_image_middleware: false
- enable_http_middleware: false
- enable_retry_middleware: false
- enable_referrer_middleware: false
- enable_http_auth_middleware: false
- enable_cookie_middleware: false
- enable_url_middleware: false
- enable_compress_middleware: false
- enable_decode_middleware: false
- enable_redirect_middleware: false
- enable_chrome_middleware: false
- enable_device_middleware: false
- enable_proxy_middleware: false
- enable_robots_txt_middleware: false
- enable_stats_middleware: false
- enable_dump_pipeline: false
- enable_file_pipeline: false
- enable_image_pipeline: false
- enable_filter_pipeline: false
- enable_csv_pipeline: false
- enable_json_lines_pipeline: false
- enable_mongo_pipeline: false
- enable_mysql_pipeline: false
- enable_kafka_pipeline: false
-
文件下載
- 如果您希望將文件保存到S3等對象存儲中,需要進(jìn)行相應(yīng)的配置
- Files下載
- 在Item中設(shè)置Files請求:在Item中,您需要設(shè)置Files請求,即包含要下載的文件的請求列表。
可以使用item.SetFilesRequest([]pkg.Request{...})
方法設(shè)置請求列表。 - Item.data:您的Item.data字段需要實(shí)現(xiàn)pkg.File的切片,用于保存下載文件的結(jié)果。
該字段的名稱必須是Files,如type DataFile struct {Files []*media.File}。
- 在Item中設(shè)置Files請求:在Item中,您需要設(shè)置Files請求,即包含要下載的文件的請求列表。
- Images下載
- 在Item中設(shè)置Images請求:在Item中,您需要設(shè)置Images請求,即包含要下載的圖片的請求列表。
可以使用item.SetImagesRequest([]pkg.Request{...})方法設(shè)置請求列表。 - Item.data:您的Item.data字段需要實(shí)現(xiàn)pkg.Image的切片,用于保存下載圖片的結(jié)果。
該字段的名稱必須是Images,如type DataImage struct {Images []*media.Image}。
- 在Item中設(shè)置Images請求:在Item中,您需要設(shè)置Images請求,即包含要下載的圖片的請求列表。
-
爬蟲結(jié)構(gòu)
- 建議按照每個網(wǎng)站(子網(wǎng)站)或者每個業(yè)務(wù)為一個spider。不必分的太細(xì),也不必把所有的網(wǎng)站和業(yè)務(wù)都寫在一個spider里
-
為了方便開發(fā)和調(diào)試,框架內(nèi)置了本地devServer,在
-m dev模式下會默認(rèn)啟用。
通過使用本地devServer,您可以在開發(fā)和調(diào)試過程中更方便地模擬和觀察網(wǎng)絡(luò)請求和響應(yīng),以及處理自定義路由邏輯。
這為開發(fā)者提供了一個便捷的工具,有助于快速定位和解決問題。
您可以自定義路由(route),只需要實(shí)現(xiàn)pkg.Route接口,并通過在Spider中調(diào)用AddDevServerRoutes(...pkg.Route)
方法將其注冊到devServer中。- 支持http和https,您可以通過設(shè)置
dev_server選項(xiàng)來指定devServer的URL。
http://localhost:8081表示使用HTTP協(xié)議,https://localhost:8081表示使用HTTPS協(xié)議。 - 默認(rèn)顯示JA3指紋。JA3是一種用于TLS客戶端指紋識別的算法,它可以顯示與服務(wù)器建立連接時客戶端使用的TLS版本和加密套件等信息。
- 您可以使用tls工具來生成服務(wù)器的私鑰和證書,以便在devServer中使用HTTPS。tls工具可以幫助您生成自簽名的證書,用于本地開發(fā)和測試環(huán)境。
- devServer內(nèi)置了多種handler,這些handler提供了豐富的功能,可以模擬各種網(wǎng)絡(luò)情景,幫助進(jìn)行開發(fā)和調(diào)試。
您可以根據(jù)需要選擇合適的handler,并將其配置到devServer中,以模擬特定的網(wǎng)絡(luò)響應(yīng)和行為。- BadGatewayHandler 模擬返回502狀態(tài)碼
- Big5Handler 模擬使用big5編碼
- CookieHandler 模擬返回cookie
- DeflateHandler 模擬使用Deflate壓縮
- FileHandler 模擬輸出文件
- Gb2312Handler 模擬使用gb2312編碼
- Gb18030Handler 模擬使用gb18030編碼
- GbkHandler 模擬使用gbk編碼
- GzipHandler 模擬使用gzip壓縮
- HelloHandler 打印請求的header和body信息
- HttpAuthHandler 模擬http-auth認(rèn)證
- InternalServerErrorHandler 模擬返回500狀態(tài)碼
- OkHandler 模擬正常輸出,返回200狀態(tài)碼
- RateLimiterHandler 模擬速率限制,目前基于全部請求,不區(qū)分用戶??膳cHttpAuthHandler配合使用。
- RedirectHandler 模擬302臨時跳轉(zhuǎn),需要同時啟用OkHandler
- RobotsTxtHandler 返回robots.txt文件
- 支持http和https,您可以通過設(shè)置
args
通過配置環(huán)境變量和啟動參數(shù),您可以更靈活地配置和控制爬蟲的行為,包括選擇配置文件、指定入口方法、傳遞額外參數(shù)以及設(shè)定啟動模式。這樣的設(shè)計可以提高爬蟲的可配置性和可擴(kuò)展性,使得爬蟲框架更適應(yīng)各種不同的應(yīng)用場景。
- CRAWLER_CONFIG_FILE -c 配置文件路徑,必須進(jìn)行配置。
- CRAWLER_START_FUNC -f 入口方法名稱,默認(rèn)Test。
- CRAWLER_ARGS -a 額外的參數(shù),該參數(shù)是非必須項(xiàng)。建議使用JSON字符串。參數(shù)會被入口方法調(diào)用。
- CRAWLER_MODE -m 啟動模式,默認(rèn)test。您可以根據(jù)需要使用不同的模式,如dev、prod等,以區(qū)分開發(fā)和生產(chǎn)環(huán)境。
config
- bot_name: crawler 項(xiàng)目名
數(shù)據(jù)庫配置:
- mongo_enable: 是否啟用MongoDB。
- mongo.example.uri: MongoDB的URI。
- mongo.example.database: MongoDB的數(shù)據(jù)庫名稱。
- mysql_enable: 是否啟用MySQL。
- mysql.example.uri: MySQL的URI。
- mysql.example.database: MySQL的數(shù)據(jù)庫名稱。
- redis_enable: 是否啟用Redis。
- redis.example.addr: Redis的地址。
- redis.example.password: Redis的密碼。
- redis.example.db: Redis的數(shù)據(jù)庫。
- s3_enable: 是否啟用S3對象存儲(如COS、OSS、MinIO等)
- s3.example.endpoint: S3的地址
- s3.example.region: S3的區(qū)域。
- s3.example.id: S3的ID。
- s3.example.key: S3的密鑰。
- s3.example.bucket: S3的桶名稱。
- kafka_enable: 是否啟用Kafka。
- kafka.example.uri: Kafka的URI。
日志配置:
- log.filename: 日志文件路徑??梢允褂?{name}"的方式替換成-ldflags的參數(shù)。
- log.long_file: 如果設(shè)置為true(默認(rèn)),則記錄完整文件路徑。
- log.level: 日志級別,可選DEBUG/INFO/WARN/ERROR。
其他配置:
- proxy.example: 代理。
- request.concurrency: 請求并發(fā)數(shù)。
- request.interval: 請求間隔時間(毫秒)。默認(rèn)1000毫秒(1秒)。
- request.timeout: 請求超時時間(秒)。默認(rèn)60秒(1分鐘)。
- request.ok_http_codes: 請求正常的HTTP狀態(tài)碼。
- request.retry_max_times: 請求重試的最大次數(shù),默認(rèn)10。
- request.http_proto: 請求的HTTP協(xié)議。默認(rèn)
2.0 - dev_server: 開發(fā)服務(wù)器的地址。默認(rèn)
https://localhost:8081 - enable_ja3: 是否修改/打印JA3指紋。默認(rèn)關(guān)閉。
- scheduler: 調(diào)度方式,默認(rèn)memory(內(nèi)存調(diào)度),可選值memory、redis、kafka。選擇redis或kafka后可以實(shí)現(xiàn)集群調(diào)度。
- filter: 過濾方式,默認(rèn)memory(內(nèi)存過濾),可選值memory、redis。選擇redis后可以實(shí)現(xiàn)集群過濾。
中間件和Pipeline配置
- enable_stats_middleware: 是否開啟統(tǒng)計中間件,默認(rèn)啟用。
- enable_dump_middleware: 是否開啟打印請求和響應(yīng)中間件,默認(rèn)啟用。
- enable_filter_middleware: 是否開啟過濾中間件,默認(rèn)啟用。
- enable_file_middleware: 是否開啟文件處理中間件,默認(rèn)啟用。
- enable_image_middleware: 是否開啟圖片處理中間件,默認(rèn)啟用。
- enable_http_middleware: 是否開啟HTTP請求中間件,默認(rèn)啟用。
- enable_retry_middleware: 是否開啟請求重試中間件,默認(rèn)啟用。
- enable_referrer_middleware: 是否開啟Referrer中間件,默認(rèn)啟用。
- referrer_policy: 設(shè)置Referrer策略,可選值為DefaultReferrerPolicy(默認(rèn))和NoReferrerPolicy。
- enable_http_auth_middleware: 是否開啟HTTP認(rèn)證中間件,默認(rèn)關(guān)閉。
- enable_cookie_middleware: 是否開啟Cookie中間件,默認(rèn)啟用。
- enable_url_middleware: 是否開啟URL長度限制中間件,默認(rèn)啟用。
- url_length_limit: URL的最大長度限制,默認(rèn)2083。
- enable_compress_middleware: 是否開啟響應(yīng)解壓縮中間件(gzip、deflate),默認(rèn)啟用。
- enable_decode_middleware: 是否開啟中文解碼中間件(GBK、GB2312、Big5編碼),默認(rèn)啟用。
- enable_redirect_middleware: 是否開啟重定向中間件,默認(rèn)啟用。
- redirect_max_times: 重定向的最大次數(shù),默認(rèn)10。
- enable_chrome_middleware: 是否開啟Chrome模擬中間件,默認(rèn)啟用。
- enable_device_middleware: 是否開啟設(shè)備模擬中間件,默認(rèn)關(guān)閉。
- enable_proxy_middleware: 是否開啟代理中間件,默認(rèn)啟用。
- enable_robots_txt_middleware: 是否開啟robots.txt支持中間件,默認(rèn)關(guān)閉。
- enable_dump_pipeline: 是否開啟打印Item Pipeline,默認(rèn)啟用。
- enable_file_pipeline: 是否開啟文件下載Pipeline,默認(rèn)啟用。
- enable_image_pipeline: 是否開啟圖片下載Pipeline,默認(rèn)啟用。
- enable_filter_pipeline: 是否開啟過濾Pipeline,默認(rèn)啟用。
- enable_csv_pipeline: 是否開啟csv Pipeline,默認(rèn)關(guān)閉。
- enable_json_lines_pipeline: 是否開啟json lines Pipeline,默認(rèn)關(guān)閉。
- enable_mongo_pipeline: 是否開啟mongo Pipeline,默認(rèn)關(guān)閉。
- enable_mysql_pipeline: 是否開啟mysql Pipeline,默認(rèn)關(guān)閉。
- enable_kafka_pipeline: 是否開啟kafka Pipeline,默認(rèn)關(guān)閉。
- enable_priority_queue: 是否開啟優(yōu)先級隊(duì)列,默認(rèn)開啟,目前只支持redis。
關(guān)于結(jié)果(item)隊(duì)列
由爬蟲處理自己的請求即可,沒必要處理其他爬蟲的請求。所以本框架雖架構(gòu)上有預(yù)留,但不會去用其他外部隊(duì)列代替本程序內(nèi)存隊(duì)列。
如處理出現(xiàn)性能問題,建議將結(jié)果輸出到隊(duì)列。
關(guān)于請求隊(duì)列
- 優(yōu)先級
優(yōu)先級允許[0-2147483647],建議在0-255,方便后期可能的調(diào)整。
0的優(yōu)先級最高,最先被處理。
因?yàn)閗afka等隊(duì)列實(shí)現(xiàn)不是很好,暫不支持。
使用方法request.SetPriority(0)
關(guān)于單次任務(wù)結(jié)束的判定
實(shí)際生產(chǎn)上,可能會有不同的判定方法,基本無法做到兼容所有情況。特別是如果要支持分布式。
一般的框架里會延時一段時間,如果隊(duì)列不再有請求,會判定任務(wù)結(jié)束,程序關(guān)閉。
本框架里單次任務(wù)的停止條件有:
- 請求和解析方法都已結(jié)束
- item隊(duì)列為空
- request隊(duì)列為空,同時必須有request處理過
達(dá)到以上條件程序會結(jié)束。
Example
example.go
package main
import (
"context"
"errors"
"fmt"
"github.com/lizongying/go-crawler/pkg"
"github.com/lizongying/go-crawler/pkg/app"
"github.com/lizongying/go-crawler/pkg/devServer"
"github.com/lizongying/go-crawler/pkg/items"
"github.com/lizongying/go-crawler/pkg/request"
)
type ExtraOk struct {
Count int
}
type DataOk struct {
Count int
}
type Spider struct {
pkg.Spider
logger pkg.Logger
}
func (s *Spider) ParseOk(ctx context.Context, response pkg.Response) (err error) {
var extra ExtraOk
err = response.UnmarshalExtra(&extra)
if err != nil {
s.logger.Error(err)
return
}
err = s.YieldItem(ctx, items.NewItemNone().
SetData(&DataOk{
Count: extra.Count,
}))
if err != nil {
s.logger.Error(err)
return err
}
if extra.Count > 0 {
return
}
err = s.YieldRequest(ctx, request.NewRequest().
SetUrl(response.GetUrl()).
SetExtra(&ExtraOk{
Count: extra.Count + 1,
}).
SetCallBack(s.ParseOk))
if err != nil {
s.logger.Error(err)
}
return
}
func (s *Spider) TestOk(ctx context.Context, _ string) (err error) {
// mock server
s.AddDevServerRoutes(devServer.NewOkHandler(s.logger))
err = s.YieldRequest(ctx, request.NewRequest().
SetUrl(fmt.Sprintf("%s%s", s.GetHost(), devServer.UrlOk)).
SetExtra(&ExtraOk{}).
SetCallBack(s.ParseOk))
if err != nil {
s.logger.Error(err)
}
return
}
func NewSpider(baseSpider pkg.Spider) (spider pkg.Spider, err error) {
if baseSpider == nil {
err = errors.New("nil baseSpider")
return
}
spider = &Spider{
Spider: baseSpider,
logger: baseSpider.GetLogger(),
}
spider.SetName("test-ok")
host, _ := spider.GetConfig().GetDevServer()
spider.SetHost(host.String())
return
}
func main() {
app.NewApp(NewSpider).Run()
}
go run exampleSpider.go -c example.yml -f TestOk -m dev
更多示例可以按照以下項(xiàng)目
git clone github.com/lizongying/go-crawler-example