Python爬蟲第6節-requests庫的基本用法

目錄

前言

一、準備工作

二、實例引入

三、GET請求

3.1 基本示例

3.2 抓取網頁

3.3 抓取二進制數據

3.4 添加headers

四、POST請求

五、響應


前言

????????前面我們學習了urllib的基礎使用方法。不過,urllib在實際應用中存在一些不便之處。以網頁驗證和Cookies處理為例,使用 urllib 時,得編寫Opener和Handler才能完成操作。

????????為了更輕松地實現這些操作,功能更強大的 requests 庫應運而生。利用 requests 庫,管理Cookies、進行登錄驗證,以及設置代理等操作,都能輕松搞定。下面,我們先介紹 requests 庫的基本使用方法。

一、準備工作

????????在開始使用requests庫前,要確保已經正確安裝了該庫。如果還未安裝,可以通過下面命令安裝:
- 對于 Python 2:

 pip install requests

- 對于 Python 3(推薦):

pip3 install requests

二、實例引入

????????urllib庫用urlopen()方法發起GET方式的網頁請求。與之對應,requests庫提供了get()方法。相比之下,get()這個名字,能讓人更直接地明白它用于發起GET請求。?

下面通過實例來看:

import requests
r = requests.get('https://www.baidu.com/')
print(type(r))
print(r.status_code)
print(type(r.text))
print(r.text)
print(r.cookies)

運行結果如下:

<class 'requests.models.Response'>
200
<class 'str'>
<html>
<head>
<script>
location.replace(location.href.replace("https://","http://"));
</script>
</head>
<body>
<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>
<RequestsCookieJar[<Cookie BIDUPSID=992C3B26F4C4D09505C5E959D5FBC005 for .baidu.com/>,<Cookie PSTM=1472227535 for .baidu.com/>,<Cookie bs=153047544986095451480040NN20303CO2FNNNO for .www.baidu.com/>,<Cookie BD_NOT_HTTPS=1 for www.baidu.com/>]>

????????在這兒,我們通過調用requests庫的get()方法,完成了和urllib庫中urlopen()一樣的操作,得到一個Response對象。緊接著,我們又輸出了這個Response對象的類型、狀態碼,響應體的類型、內容,以及Cookies信息。從運行結果能知道,Response對象的類型是requests.models.Response,響應體是str字符串類型,Cookies是RequestsCookieJar類型。

????????用get()方法實現GET請求并不稀奇,requests庫更方便的地方在于,用一句話就能實現POST、PUT等其他類型的請求 ,示例如下:

r = requests.post('http://httpbin.org/post')
r = requests.put('http://httpbin.org/put')
r = requests.delete('http://httpbin.org/delete')
r = requests.head('http://httpbin.org/get')
requests.options('http://httpbin.org/get')

????????這里分別用post()、put()、delete()等方法實現了POST、PUT、DELETE等請求。相比urllib,是不是簡單很多?這其實只是requests庫強大功能的一小部分。

三、GET請求

????????GET請求是HTTP協議里特別常見的一種請求方式。接下來,咱們就深入了解一下,怎么用requests庫來發起GET請求。

3.1 基本示例

????????第一步,搭建一個最為簡單的GET請求,請求的目標鏈接是http://httpbin.org/get。這個網站能識別客戶端發起的請求類型,要是檢測到是GET請求,就會把對應的請求信息返回過來。

import requests
r = requests.get('http://httpbin.org/get')
print(r.text)

運行結果如下:

{"args": {},"headers": {"Accept": "*/*","Accept-Encoding": "gzip, deflate","Host": "httpbin.org","User-Agent": "python-requests/2.10.0"},"origin": "122.4.215.33","url": "http://httpbin.org/get"
}

????????從結果能看出,我們順利發起了GET請求,返回內容里有請求頭、URL、IP等信息。那么,當發起GET請求,需要添加額外信息時,通常該怎么做呢?舉個例子,現在要添加兩個參數,一個是name,值為germey,另一個是age,值為22 。?

????????要構造這個請求鏈接,是不是直接寫成:

r = requests.get('http://httpbin.org/get?name=germey&age=22')

????????這樣做可行,但不夠人性化。一般情況下,這類信息數據會用字典來存儲。那么,該如何構造鏈接呢?利用params參數就可以,示例如下:

import requests
data = {'name': 'germey','age': 22
}
r = requests.get("http://httpbin.org/get", params=data)
print(r.text)

運行結果如下:

{"args": {"age": "22","name": "germey"},"headers": {"Accept": "*/*","Accept-Encoding": "gzip, deflate","Host": "httpbin.org","User-Agent": "python-requests/2.10.0"},"origin": "122.4.215.33","url": "http://httpbin.org/get?age=22&name=germey"
}

????????運行程序后能發現,請求鏈接自動生成了,就是http://httpbin.org/get?age=22&name=germey。另外,網頁返回內容的數據類型是str,不過它遵循JSON格式規范。所以,要是想把返回結果解析成字典格式,直接調用json()方法就能實現。?

示例如下:

import requests
r = requests.get("http://httpbin.org/get")
print(type(r.text))
print(r.json())
print(type(r.json()))

運行結果如下:

<class 'str'>
{
??? "headers": {
??????? "Accept-Encoding": "gzip, deflate",
??????? "Accept": "*/*",
??????? "Host": "httpbin.org",
??????? "User-Agent": "python-requests/2.10.0"
??? },
??? "url": "http://httpbin.org/get",
??? "args": {},
??? "origin": "182.33.248.131"
}
<class 'dict'>

????????可以發現,調用json()方法,能將返回結果為JSON格式的字符串轉化為字典。但需要注意,如果返回結果不是JSON格式,就會出現解析錯誤,拋出json.decoder.JSONDecodeError異常。

3.2 抓取網頁

????????上面請求的鏈接,返回內容是JSON格式字符串。既然如此,請求普通網頁時,自然也能獲取到對應內容。下面,我們以知乎的“發現”頁面為例展開說明:?

import requests
import re
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
}
r = requests.get("https://www.zhihu.com/explore", headers=headers)
pattern = re.compile('explore-feed.*?question_link.*?>(.*?)</a>', re.S)
titles = re.findall(pattern, r.text)
print(titles)

????????這里,我們在請求中添加了headers信息,里面有User - Agent字段,這個字段用來標識瀏覽器。要是不加上這一項,知乎就不讓我們抓取頁面內容。之后,我們用最基礎的正則表達式,把頁面上所有問題內容匹配出來了。正則表達式的知識,我們會在后面深入講解,這里先借助這個實例,給大家做個初步介紹 。?


運行結果如下:

['\n為什么很多人喜歡提及「拉丁語系」這個詞?\n', '\n在沒有水的情況下水系寶可夢如何戰斗?\n', '\n有哪些經驗可以送給 Kindle 新人?\n', '\n谷歌的廣告業務是如何賺錢的?\n', "\n程序員該學習什么,能在上學期間掙錢?\n", '\n有哪些原本只是一個小消息,但回看發現是個驚天大新聞的例子?\n', "\n如何評價今敏?\n", '\n源氏是怎么把那么長的刀從背后拔出來的?\n', "\n年輕時得了絕癥或大病是怎樣的感受?\n", "\n年輕時得了絕癥或大病是怎樣的感受?\n"]

????????我們發現,這里成功提取出了所有的問題內容。


3.3 抓取二進制數據

????????上面例子里,我們抓取了知乎的一個頁面,得到的是HTML文檔。那要是想抓取圖片、音頻、視頻這類文件,該怎么做呢?圖片、音頻、視頻這些文件,本質都是二進制碼。因為它們有特定保存格式,配合對應的解析方法,我們才能看到這些豐富多彩的多媒體內容。所以,要抓取這些文件,就得獲取它們的二進制碼 。?

????????下面以GitHub的站點圖標為例來看:

import requests
r = requests.get("https://github.com/favicon.ico")
print(r.text)
print(r.content)

????????這次抓取的是站點圖標,就是瀏覽器每個標簽上顯示的小圖標。我們打印了Response對象的text和content這兩個屬性。運行程序后,前兩行顯示的是r.text的結果,最后一行是r.content的結果。能看到,r.text結果出現亂碼,r.content結果前面有個b,這表明它是bytes類型數據。因為圖片屬于二進制數據,r.text打印時會把圖片數據轉成str類型,相當于直接將圖片轉為字符串,亂碼也就不可避免了。?

????????接著,我們將剛才提取到的圖片保存下來:

import requests
r = requests.get("https://github.com/favicon.ico")
with open('favicon.ico', 'wb') as f:f.write(r.content)

????????這里用到了open()方法。使用它的時候,第一個參數要設定為文件名稱,第二個參數表示以二進制寫入模式打開文件,這樣就能往文件里寫入二進制數據。程序運行完畢,會發現在文件夾里多了一個名為favicon.ico的圖標。同樣道理,獲取音頻和視頻文件,也能采用這種方法。?

3.4 添加headers

和urllib.request一樣,requests也能借助headers參數來傳遞請求頭信息。就拿上面抓取知乎頁面的例子來說,如果不設置headers參數傳遞請求頭信息,就無法正常發起請求。

import requests
r = requests.get("https://www.zhihu.com/explore")
print(r.text)

運行結果如下:

<html><body><h1>500 Server Error</h1>An internal server error occured.</body></html>

但如果加上headers并添加User-Agent信息,就沒問題了:

import requests
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
}
r = requests.get("https://www.zhihu.com/explore", headers=headers)
print(r.text)

????????當然,我們可以在headers這個參數中任意添加其他的字段信息。

四、POST請求

????????前面,我們認識了最基礎的GET請求。在HTTP請求里,還有一種常見的請求方式,那就是POST請求。用requests庫實現POST請求,操作起來同樣不復雜。?

示例如下:

import requests
data = {'name': 'germey', 'age': '22'}
r = requests.post("http://httpbin.org/post", data=data)
print(r.text)

????????這里還是請求http://httpbin.org/post,該網站可以判斷如果請求是POST方式,就把相關請求信息返回。

運行結果如下:

{"args": {},"data": "","files": {},"form": {"age": "22","name": "germey"},"headers": {"Accept": "*/*","Accept-Encoding": "gzip, deflate","Content-Length": "18","Content-Type": "application/x-www-form-urlencoded","Host": "httpbin.org","User-Agent": "python-requests/2.10.0"},"json": null,"origin": "182.33.248.131","url": "http://httpbin.org/post"
}

????????從結果能看到,我們順利拿到了返回數據。返回結果里的form部分,正是我們提交的數據,這就說明POST請求成功發送出去了。?

五、響應

????????發送請求之后,肯定會得到響應結果。就像上面的例子,我們通過text和content屬性,獲取到了響應內容。其實,除了這兩種,借助其他屬性和方法,還能獲取更多信息,像狀態碼、響應頭,以及Cookies等內容。?

示例如下:

import requests
r = requests.get('http://www.jianshu.com')
print(type(r.status_code), r.status_code)
print(type(r.headers), r.headers)
print(type(r.cookies), r.cookies)
print(type(r.url), r.url)
print(type(r.history), r.history)

????????在這里,通過打印status_code屬性,就能得到請求的狀態碼;打印headers屬性,可獲取響應頭信息;打印cookies屬性,能拿到Cookies數據;打印url屬性,會顯示請求的URL;而打印history屬性,就能看到請求歷史記錄。?

運行結果如下:

<class 'int'> 200
<class 'requests.structures.CaseInsensitiveDict'> {'X-Runtime': '0.006363', 'Connection': 'keep-alive', 'Content-Type': 'text/html; charset=utf-8', 'X-Content-Type-Options': 'nosniff', 'Date': 'Sat, 27 Aug 2016 17:18:51 GMT', 'Server': 'nginx', 'X-Frame-Options': 'DENY', 'Content-Encoding': 'gzip', 'Vary': 'Accept-Encoding', 'ETag': 'W/"3abda885e0e123bfde06dgb61e696159"', 'X-XSS-Protection': '1;mode-block', 'X-Request-Id': 'a8a3c4d5-f660-422f-8df9-49719ddgb5d4', 'Transfer-Encoding': 'chunked','set-Cookie':'read mode=day; path=/', 'default font=font2; path=/','session id=xxx; path=/; HttpOnly', 'Cache-Control':'max-age=0, private, must-revalidate'}
<class'requests.cookies.RequestsCookieJar'> <RequestsCookieJar[<Cookie session id=xxx for www.jianshu.com/>, <Cookie default font=font2 for www.jianshu.com/>, <Cookie read mode=day for www.jianshu.com/>]>
<class'str'> http://www.jianshu.com/
<class 'list'> []

????????由于session id太長,這里就簡寫了。從運行結果能看出,通過headers屬性獲取到的數據類型是CaseInsensitiveDict,通過cookies屬性獲取到的數據類型則是RequestsCookieJar。

????????在判斷請求是否成功時,狀態碼是常用的依據。requests庫還內置了一個狀態碼查詢對象,叫requests.codes 。

示例如下:

import requests
r = requests.get('http://www.jianshu.com')
exit() if not r.status_code == requests.codes.ok else print('Request Successfully')

????????在這兒,我們把請求的返回碼和requests庫內置的成功返回碼作比較。要是二者匹配,就說明請求正常響應,程序會輸出成功請求的消息;要是不匹配,程序就會終止。這里,我們用requests.codes.ok獲取到的成功狀態碼為200。?

????????當然,requests.codes里可不只有ok這一個條件碼。下面,給大家列出各類返回碼以及對應的查詢條件。?

# 信息性狀態碼
100: ('continue',),
101: ('switching protocols',),
102: ('processing',),
103: ('checkpoint',),
122: ('uri too long', "request uri too long"),
# 成功狀態碼
200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '√'),
201: ('created',),
202: ('accepted',),
203: ('non_authoritative_info', 'non_authoritative_information'),
204: ('no_content',),
205: ('reset_content', 'reset'),
206: ('partial_content', 'partial'),
207: ('multi_status','multiple_status','multi_stati','multiple_stati'),
208: ('already_reported',),
226: ('im_used',),
# 重定向狀態碼
300: ('multiple_choices',),
301: ('moved_permanently','moved', '\\o-'),
302: ('found',),
303: ('see_other', 'other'),
304: ('not_modified',),
305: ('use_proxy',),
306: ('switch_proxy',),
307: ('temporary_redirect', 'temporary_moved', 'temporary'),
308: ('permanent_redirect','resume_incomplete','resume',),
# 客戶端錯誤狀態碼
400: ('bad_request', 'bad'),
401: ('unauthorized',),
402: ('payment_required', 'payment'),
403: ('forbidden',),
404: ('not_found', '-0-'),
405: ('method_not_allowed', 'not_allowed'),
406: ('not_acceptable',),
407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'),
408: ('request_timeout', 'timeout'),
409: ('conflict',),
410: ('gone',),
411: ('length_required',),
412: ('precondition_failed', 'precondition'),
413: ('request_entity_too_large',),
414: ('request_uri_too_large',),
415: ('unsupported_media_type', 'unsupported_media','media_type'),
416: ('requested_range_not_satisfiable','requested_range', 'range_not_satisfiable'),
417: ('expectation_failed',),
418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'),
421: ('misdirected_request',),
422: ('unprocessable_entity', 'unprocessable'),
423: ('locked',),
424: ('failed_dependency', 'dependency'),
425: ('unordered_collection', 'unordered'),
426: ('upgrade_required', 'upgrade'),
428: ('precondition_required', 'precondition'),
429: ('too_many_requests', 'too_many'),
431: ('header_fields_too_large', 'fields_too_large'),
444: ('no_response', 'none'),
449: ('retry_with','retry'),
450: ('blocked_by_windows_parental_controls', 'parental_controls'),
451: ('unavailable_for_legal_reasons', 'legal_reasons'),
499: ('client_closed_request', 'client_closed_request'),
# 服務端錯誤狀態碼
500: ('internal_server_error','server_error', '/o\\', 'X'),
501: ('not_implemented',),
502: ('bad_gateway',),
503: ('service_unavailable', 'unavailable'),
504: ('gateway_timeout',),
505: ('http_version_not_supported', 'http_version'),
506: ('variant_also_negotiates',),
507: ('insufficient_storage',),
509: ('bandwidth_limit_exceeded', 'bandwidth'),
510: ('not_extended',),
511: ('network_authentication_required', 'network_auth', 'network_authentication')

????????舉個例子,要是你想知道請求結果是不是404狀態,就可以用`requests.codes.not_found`去做對比。?

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

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

相關文章

Go 學習筆記 · 進階篇 · 第一天:接口與多態

&#x1f436;Go接口與多態&#xff1a;繼承沒了&#xff0c;但自由炸裂&#xff01; 最近翻 Go 的代碼&#xff0c;突然看到這么一段&#xff1a; type Animal interface {Speak() string }我一愣&#xff0c;咦&#xff1f;這不就是 Java 里常見的“接口”嗎&#xff1f; …

信息學奧賽一本通 1929:【04NOIP普及組】火星人 | 洛谷 P1088 [NOIP 2004 普及組] 火星人

【題目鏈接】 ybt 1929&#xff1a;【04NOIP普及組】火星人 洛谷 P1088 [NOIP 2004 普及組] 火星人 【題目考點】 1. 深搜回溯 2. STL next_permutation函數 頭文件<algorithm> 函數定義&#xff1a;next_permutation(lb, ub, cmp) lb&#xff1a;區間下界&#xff…

借助 AI 工具使用 Python 實現北京市店鋪分布地理信息可視化教程

一、項目概述 本項目通過 Python 的pyecharts庫&#xff0c;結合 AI 工具輔助代碼編寫與邏輯梳理&#xff0c;實現北京市店鋪數量分布及區域連線的地理信息可視化&#xff0c;最終生成交互式地圖圖表。 二、準備工作 1. 環境與工具 Python 環境&#xff1a;確保已安裝 Pyth…

Python項目打包指南:PyInstaller與SeleniumWire的兼容性挑戰及解決方案

前言 前段時間做一個內網開發的需求&#xff0c;要求將selenium程序打包成.exe放在內網的win7上運行&#xff0c;在掘金搜了一圈也沒有發現相關文章&#xff0c;因此將過程中踩到的坑記錄分享一下。 本文涵蓋了具體打包操作、不同模塊和依賴項的兼容性解決方案&#xff0c;以…

(一)棧結構、隊列結構

01-線性結構-數組-棧結構 線性結構&#xff08;Linear List)是由n&#xff08;n>0)個數據元素&#xff08;結點&#xff09; a[0], a[1], a[2], a[3],...,a[n-1]組成的有限序列 數組 通常數組的內存是連續的&#xff0c;所以在知道數組下標的情況下&#xff0c;訪問效率是…

【學Rust寫CAD】35 alpha_mul_256(alpha256.rs補充方法)

源碼 // Calculates (value * alpha256) / 255 in range [0,256], // for [0,255] value and [0,256] alpha256. pub fn alpha_mul_256(self,value: u32) -> Alpha256 {let prod value * self.0;Alpha256((prod (prod >> 8)) >> 8) }代碼分析 這個函數 alph…

C# 與 相機連接

一、通過組件連接相機 需要提前在VisionPro里面保存一個CogAcqFifoTool相機工具為 .vpp 定義一個相機工具 CogAcqFifoTool mAcq null;將保存的相機工具放入mAcq中 string path “C:\Acq.vpp”; mAcq (CogAcqFifoTool)CogSerializer.LoadObjectFrommFile(path);給窗口相機…

Java并發編程高頻面試題

一、基礎概念 1. 并行與并發的區別&#xff1f; 并行&#xff1a;多個任務在多個CPU核心上同時執行&#xff08;物理上同時&#xff09;。并發&#xff1a;多個任務在單CPU核心上交替執行&#xff08;邏輯上同時&#xff09;。類比&#xff1a;并行是多個窗口同時服務&#x…

LiT and Lean: Distilling Listwise Rerankers intoEncoder-Decoder Models

文章&#xff1a;ECIR 2025會議 一、動機 背景&#xff1a;利用LLMs強大的能力&#xff0c;將一個查詢&#xff08;query&#xff09;和一組候選段落作為輸入&#xff0c;整體考慮這些段落的相關性&#xff0c;并對它們進行排序。 先前的研究基礎上進行擴展 [14,15]&#xff0c…

Python高級爬蟲之JS逆向+安卓逆向1.2節: 變量與對象

目錄 引言&#xff1a; 1.2.1 Python中的變量 1.2.2 變量的命名與可讀性 1.2.3 Python中的對象 1.2.4 跟大神學高級爬蟲安卓逆向 引言&#xff1a; 大神薯條老師的高級爬蟲安卓逆向教程&#xff1a; 這套爬蟲教程會系統講解爬蟲的初級&#xff0c;中級&#xff0c;高級知…

可發1區的超級創新思路(python 實現):一種輕量化的動態稀疏門控網絡

首先聲明,該模型為原創!原創!原創!且該思路還未有成果發表,感興趣的小伙伴可以借鑒! 一、應用領域 視頻異常檢測、生成視頻檢測。 二、模型解析 該模型由1.關鍵幀動態選擇機制、2.關鍵幀動態選擇機制以及3.關鍵幀動態選擇機制三大核心組件構成,形成端到端的視頻異常…

使用NVM下載Node.js管理多版本

提示&#xff1a;我解決這個bug跟別人思路可能不太一樣&#xff0c;因為我是之前好用&#xff0c;換個項目就不好使了&#xff0c;倦了 文章目錄 前言項目場景一項目場景二解決方案&#xff1a;下載 nvm安裝 nvm重新下載所需Node 版本nvm常用命令 項目結構說明 前言 提示&…

MySQL數據庫經典面試題解析

1. MySQL 索引使用有哪些注意事項呢? 可以從三個維度回答這個問題:索引哪些情況會失效,索引不適合哪些場景,索引規則 索引哪些情況會失效 查詢條件包含or,可能導致索引失效如何字段類型是字符串,where時一定用引號括起來,否則索引失效like通配符可能導致索引失效。聯合…

C#結合SQLite數據庫使用方法

一、關于SQLite SQLite 是一個輕量級的嵌入式關系型數據庫管理系統&#xff08;RDBMS&#xff09;。與傳統的數據庫管理系統&#xff08;如 MySQL、PostgreSQL 或 SQL Server&#xff09;不同&#xff0c;SQLite 并不需要運行單獨的服務器進程&#xff0c;它的數據庫存儲在一個…

深入解析 MySQL 中的日期時間函數:DATE_FORMAT 與時間查詢優化

深入解析 MySQL 中的日期時間函數&#xff1a;DATE_FORMAT 與時間查詢優化 在數據庫管理和應用開發中&#xff0c;日期和時間的處理是不可或缺的一部分。MySQL 提供了多種日期和時間函數來滿足不同的需求&#xff0c;其中DATE_FORMAT函數以其強大的日期格式化能力&#xff0c;…

如何深刻理解Reactor和Proactor

前言&#xff1a; 網絡框架的設計離不開 I/O 線程模型&#xff0c;線程模型的優劣直接決定了系統的吞吐量、可擴展性、安全性等。目前主流的網絡框架&#xff0c;在網絡 IO 處理層面幾乎都采用了I/O 多路復用方案(又以epoll為主)&#xff0c;這是服務端應對高并發的性能利器。 …

筆試專題(七)

文章目錄 乒乓球筐&#xff08;哈希&#xff09;題解代碼 組隊競賽題解代碼 刪除相鄰數字的最大分數&#xff08;線性dp&#xff09;題解代碼 乒乓球筐&#xff08;哈希&#xff09; 題目鏈接 題解 1. 兩個哈希表 先統計第一個字符串中的字符個數&#xff0c;再統計第二個字…

清晰易懂的 Flutter 卸載和清理教程

以下是為 Flutter 徹底卸載與清理教程&#xff0c;覆蓋 Windows、macOS、Linux 系統&#xff0c;步驟清晰無殘留&#xff0c;確保完全刪除 Flutter SDK、依賴工具及 IDE 配置。 一、通用步驟&#xff1a;確認 Flutter 安裝方式 Flutter 通常通過以下方式安裝&#xff1a; 手動…

關于反卷積

&#x1f9e0; 什么是反卷積&#xff1f; 反卷積&#xff08;Deconvolution&#xff09;&#xff0c;通常也稱為轉置卷積&#xff08;Transpose Convolution&#xff09;&#xff0c;是一種用于擴展輸入特征圖的操作&#xff0c;通常用于生成圖像或上采樣任務中。與標準卷積操…

【機器學習】ROC 曲線與 PR 曲線

目錄 一、混淆矩陣&#xff1a;分類評估的基礎 二. ROC 曲線 (Receiver Operating Characteristic Curve) 三. PR 曲線 (Precision-Recall Curve) 3.1 核心思想 4. 何時使用 ROC 曲線和 PR 曲線&#xff1f; 實驗結果 6. 總結 在機器學習的分類任務中&#xff0c;我們訓…