【Python】DAY02學(xué)習(xí)日記诵竭,記一次慘絕人寰的debug

解決在啟用Fiddler的環(huán)境里严就,爬蟲報requests.exceptions.SSLError的問題

錯誤原因

image.png

源自:https://www.zhihu.com/question/42104344/answer/158407685

感謝知乎老哥通俗易懂又深刻的解釋!

解決辦法:

1.在requests.get()里設(shè)置參數(shù)verify = FALSE谤草,跳過驗(yàn)證環(huán)節(jié)

response = requests.get(url,verify = False)

但是這樣會報一個很煩人的InsecureRequestWarning,所以需要加上下面的代碼:

import urllib3
urllib3.disable_warnings()

這樣就完美解決了莺奸。

2.理論上可以導(dǎo)出Fiddler的根證書丑孩,使用OpenSSL轉(zhuǎn)換成.pem格式,然后設(shè)置verify的值為證書的路徑灭贷,驗(yàn)證的時候就會去驗(yàn)證Fiddler的根證書温学。但我不知道為什么,我這樣做了甚疟,卻沒有成功仗岖,報的錯誤是:

OSError: Could not find a suitable TLS CA certificate bundle, 
invalid path: Bili_Index/new.pem

參考資料來源:
官方文檔ssl-warnings
http與https代理中的差異及細(xì)節(jié)
HTTP:07---連接管理之(Connection首部
TLS詳解
詳解 HTTPS、TLS览妖、SSL轧拄、HTTP區(qū)別和關(guān)系
python使用requests掛fiddler代理時提示SSLError,HTTPSConnectionPool
知乎-少年曉琦OliverCh的回答)

感謝 !

——前來debug的游客請止步——

因?yàn)橄旅嫒呛翢o意義的廢話。

可算是明白了一杯茶一包煙一個Bug調(diào)一天的感覺了黄痪。
但是作為一個第二天學(xué)習(xí)Python的小萌新紧帕,我不禁思考盔然,第二天就遇到了如此嚴(yán)峻桅打、如此慘絕人寰的問題,是不是應(yīng)該早點(diǎn)苦海無涯回頭是岸愈案?

先來看看報錯信息

ssl.SSLCertVerificationError:[SSL:CERTIFICATE_VERIFY_FAILED]
certificate verify failed:unable to get local issuer certificate (_ssl.c:1056)
During handling of the above exception, another exception occurred:urllib3.exceptions.MaxRetryError:HTTPSConnectionPool(host='www.bilibili.com', port=443):
Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL:CERTIFICATE_VERIFY_FAIL
requests.exceptions.SSLError:HTTPSConnectionPool(host='www.bilibili.com', port=443): Max retries exceeded with url:/ (Caused by SSLError(SSLCertVerificationError
(1, '[SSL: CERTIFICATE_VERIFY_FAILED]

簡單翻譯一下:

SSL證書錯誤:SSL證書驗(yàn)證失斖ξ病:無法獲取本地頒布的證書
在處理上述異常期間,又來了異常:
urllib3中的最大重試錯誤:重試訪問url超過最大連接數(shù):由SSLError引起(SSL證書錯誤[SSL證書驗(yàn)證失敗])
requests中的SSLError:HTTPS連接池:重試訪問url超過最大連接數(shù):由SSLError引起(SSL證書錯誤[SSL證書驗(yàn)證失敗])
(狗屁不通......)

嘗試分析以上的錯誤信息:每個報錯都寫著站绪,SSL證書驗(yàn)證失敗遭铺,但是為什么開著Fiddler代理就會出現(xiàn)這個問題呢?
因?yàn)閞equests的根證書和Fiddler的根證書沖突了,并且requests的證書驗(yàn)證是默認(rèn)開啟的魂挂。

嘗試解決辦法1:關(guān)閉SSL證書驗(yàn)證甫题。

response = requests.get(url,verify=False)

驗(yàn)證失敗那就不驗(yàn)證了嘛。
嘗試結(jié)果:我去涂召,不僅沒有解決坠非,還甩了一個不安全警告。

InsecureRequestWarning: 
Unverified HTTPS request is being made to host 'www.bilibili.com'. 
Adding certificate verification is strongly advised.
See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning,

不安全請求警告:正在向主機(jī)發(fā)出未經(jīng)驗(yàn)證的HTTPS請求果正。強(qiáng)烈建議增加證書驗(yàn)證炎码。
另外這里還有個配套的不安全警告處理措施,就是禁用警告

import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

感覺不太合適的樣子秋泳。

既然甩了一個官方文檔的連接潦闲,那就去看看嘛。
追溯到官方的文檔:https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
在里面迫皱,我注意到這樣的信息:

image.png

HTTP和HTTPS代理
HTTP和HTTPS代理都支持HTTP和HTTPS目標(biāo)歉闰。其中唯一的差別是,是否需要先向代理創(chuàng)建一個TLS(傳輸層協(xié)議)連接卓起。你可以通過指定正確的代理方案來指定你所需要連接的代理新娜。

問題又來了,我雖然把Fiddler當(dāng)工具在用既绩,但我真的不懂HTTP和HTTPS代理是什么概龄,那就了解一下。
找到了一篇好文章:https://www.cnblogs.com/selol/p/5446965.html

image.png

看到上面的圖我深受啟發(fā)饲握,所以Connection首部又是什么啊私杜。
找到了一篇好文章:https://blog.csdn.net/qq_41453285/article/details/95162180

image.png

謎底揭開了。

然后我理解了這兩句話:


image.png

所以服務(wù)器和客戶端達(dá)成keep-alive共識的時候救欧,代理層懵逼了衰粹,我是誰我在哪兒你倆想干啥,得笆怠,關(guān)連接吧铝耻。

接著博主的文章往下看:

image.png

哦哦哦原來如此,盲中繼沒有理解Proxy-Connection這個Conection首部的其他首部字段名蹬刷,并且轉(zhuǎn)發(fā)了這個字段瓢捉。

接著看:

image.png
image.png
image.png

我好像理解了!感謝博主办成!

劃重點(diǎn):HTTPS代理兩側(cè)連接是同步的泡态,要斷一起斷。

把目光轉(zhuǎn)向之前沒看完的官方文檔:

image.png

HTTPS 代理+ HTTPS 目標(biāo)
一個TLS-in-TSL 隧道(迂卢?)將被創(chuàng)建某弦。一個初始的TLS連接將被創(chuàng)建給代理桐汤,然后發(fā)送一個HTTP連接來創(chuàng)建一個通往目標(biāo)的TCP連接,最后創(chuàng)建第二個通往目標(biāo)的TLS連接靶壮。你可以自定義ssl.SSLContext用于通過ProxyManager類的proxy_ssl_context參數(shù)進(jìn)行代理TLS連接怔毛。
(狗屁不通X2)

我勉強(qiáng)理解一下,就是先創(chuàng)建一個初始TLS連接給代理腾降,然后......算了我理解不了馆截,先去搜搜看什么是TSL連接吧。

找到了一篇寫得很好的文章:http://www.reibang.com/p/1fc7130eb2c2

TLS握手過程:

image.png

看完了蜂莉,還沒太理解蜡娶,又找到了另一篇好文章:https://blog.csdn.net/chan70707/article/details/82932153

我好像懂得了什么:


image.png

回頭看看報錯信息:

ssl.SSLCertVerificationError: 
[SSL: CERTIFICATE_VERIFY_FAILED]
 certificate verify failed: unable to get local issuer certificate 

證書驗(yàn)證失敗的原因是:沒有獲取到本地頒布的證書。

對啊映穗,那我為什么不想辦法告訴它怎么獲取證書呢窖张?

嘗試解決辦法2:指定SSL證書。
https://blog.csdn.net/qq_33958297/article/details/82291009
按照這篇文章里的步驟操作了一下蚁滋,失敗了orz宿接。

gProxies = {"http":"http://192.168.1.103:8888","https":"http://192.168.1.103:8888"}
cert = "D:\py文件\Bili_Index\\fiddlerroot.crt"
response = requests.get(url,proxies=gProxies,verify=cert)

(我現(xiàn)在好餓......)

接下來,我把FiddlerRoot證書導(dǎo)出辕录,用OpenSSL把它從.cer轉(zhuǎn)換成.pem睦霎,然后把我的代碼改成了這個樣子:

response = requests.get(url,
                        proxies={"http": "http://127.0.0.1:8888", 
                                     "https":"http:127.0.0.1:8888"},
                        verify="D:\py文件\Bili_Index\\fdlroot.pem")

好了,又一次失敗的嘗試走诞。

不過也有驚喜哦副女,那就是關(guān)了Fiddler,還附送了一個臉生的新錯誤哦:

requests.exceptions.ProxyError: 
HTTPSConnectionPool(host='www.bilibili.com', port=443):
 Max retries exceeded with url:
 / (Caused by ProxyError('Cannot connect to proxy.', NewConnectionError
('<urllib3.connection.HTTPSConnection object at 0x00000251156835C0>: 
Failed to establish a new connection:
 [WinError 10061] 由于目標(biāo)計算機(jī)積極拒絕蚣旱,無法連接碑幅。')))

好家伙,竟然敢拒絕我塞绿。
這下連HTTPS連接都建立不了沟涨。
(算了,休息會兒异吻,回來面向百度debug)

回來了裹赴。
積極百度了一下還是運(yùn)行不了。

草诀浪,我是智障嗎棋返!
我都把Fiddler關(guān)了,還怪人家為什么連不上代理K裢住0米颉!
嗚嗚嗚嗚嗚對不起我的錯春宣。
我這就把Fiddler打開酵颁。

哎,還是熟悉的SSLError月帝。

 SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] 

這還能咋辦呢躏惋,回頭去看看官方文檔吧,嘆氣嚷辅。

image.png

對于HTTPS代理簿姨,我們還支持使用絕對URI將請求轉(zhuǎn)發(fā)到HTTPS目的地,前提是use_forwarding_For_HTTPS參數(shù)設(shè)置為True簸搞。我們強(qiáng)烈建議您僅將此選項(xiàng)用于受信任的代理或公司代理扁位,因?yàn)榇韺⑼耆梢娔恼埱蟆?/p>

這我設(shè)置的沒問題哈,略過這條趁俊。

這一條是關(guān)于上面的InsecureRequestWarning:


image.png

所以官方文檔還得多讀域仇,再翻翻看。

發(fā)現(xiàn)了關(guān)鍵字Certificate Verification:


image.png

上面提示HTTPS連接現(xiàn)在是默認(rèn)驗(yàn)證了寺擂。
雖然可以通過設(shè)置cert_reqs = 'CERT_NONE'來拒絕證書驗(yàn)證暇务,但是還是強(qiáng)烈建議順其自然。
除非另外指定的urllib3將嘗試加載默認(rèn)系統(tǒng)證書商店怔软,最值得信賴的的跨平臺方法是使用certifi包垦细,它提供Mozilla的根證書包。

既然官網(wǎng)都這么說了挡逼,那就整一個括改?


image.png

太慢了,真的太慢了家坎,這下載速度叹谁。

繼續(xù)官方文檔:
一旦你擁有證書,你可以創(chuàng)建一個PoolManager乘盖,在發(fā)送請求的時候驗(yàn)證證書焰檩。

image.png

啊這......跟我好像關(guān)系不是很大嘛。
目前要解決的問題是:
certificate verify failed: unable to get local issuer certificate
可是指定證書給它订框,它還是報這個錯誤析苫。

不活了。

草草草草草草可以了穿扳!
就是加個參數(shù)verify=FALSE衩侥!
能跑出來不過有個不安全警告!
之前沒有跑出來是因?yàn)槲乙还矊懥藘蓚€get():

response = requests.get(url,verify=False)
img = requests.get(iurl,verify=False,timeout = 5).content

但是我剛剛只補(bǔ)了一個verify=False矛物。

總之程序跑出來了茫死,警告的話忽略就行了,去看看Fiddler抓到的包——

image.png

User-Agent:python-requests/2.24.0
Connection:keep-alive
長連接是沒問題的履羞。

好像還發(fā)現(xiàn)了什么奇怪的東西峦萎?


image.png

Host: ocsp.globalsign.com是什么啊......

image.png

驗(yàn)證證書的啊屡久,明白了。

注意到下載完最后一張圖片以后爱榔,Conection依然是Keep-Alive:

image.png

好像這樣也行吧被环,程序能跑,F(xiàn)iddler能抓包详幽,不安全警告可以disable掉筛欢,就是沒有證書驗(yàn)證的環(huán)節(jié)。

但是唇聘,全局設(shè)置不驗(yàn)證ssl證書——

ssl._create_default_https_context =ssl._create_unverified_context

也運(yùn)行不出來版姑,還是報相同的錯誤。

繼續(xù)探索正常驗(yàn)證證書的辦法迟郎。

無意間看到有老哥解釋的原因:

image.png

https://www.zhihu.com/question/42104344/answer/158407685

這個解釋真是清晰明了0铡!谎亩!

最后提到的炒嘲,將fiddler中下載的證書在requests中的參數(shù)設(shè)置,這方法我用過匈庭,不行的啊夫凸。
不如再試試?

試了阱持,報錯報錯報錯報錯......

破案了X舶琛!我寫錯路徑了V匝省鸽扁!

原來寫的絕對路徑:

verify=r"D:\py文件\Bili_Index\fdlroot.pem"

改成相對路徑以后:

verify=r"Bili_Index/fdlroot.pem"

報的錯誤信息變化了耶!

image.png
OSError: Could not find a suitable TLS CA certificate bundle, 
invalid path: Bili_Index/fdlroot.pem

讓我來看看錯誤是什么...invalid path....好的哦镶骗。
可是路徑是我從pycharm里面右鍵copy path的懦尝,所以這其實(shí)是解析路徑的時候出了什么問題吧牵素。

等等......如果其實(shí)證書是無效的呢路媚?

我重新導(dǎo)出一下證書箍鼓,再換成.pem格式。

image.png

reset再重來相寇。

image.png
image.png
image.png

警告多得我很恐慌慰于,總覺得自己在按川川辦公室的核*彈按鈕。

image.png

重新試了一下還是報相同的錯誤唤衫。

應(yīng)該還是證書的問題吧婆赠,搜了一下,驗(yàn)證12306的證書的時候佳励,也會報這個錯誤休里。而我剛剛注意到這里:


image.png
OSError: Could not find a suitable TLS CA certificate bundle, 
invalid path: Bili_Index/new.pem

我死心了蛆挫,全網(wǎng)沒找到辦法,stackoverflow上面有個問題很像但不是份帐。

餓死了璃吧,吃飯去楣导。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末废境,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子筒繁,更是在濱河造成了極大的恐慌噩凹,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件毡咏,死亡現(xiàn)場離奇詭異驮宴,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)呕缭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門堵泽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人恢总,你說我怎么就攤上這事迎罗。” “怎么了片仿?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵纹安,是天一觀的道長。 經(jīng)常有香客問我砂豌,道長厢岂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任阳距,我火速辦了婚禮塔粒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘筐摘。我一直安慰自己卒茬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布蓄拣。 她就那樣靜靜地躺著扬虚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪球恤。 梳的紋絲不亂的頭發(fā)上辜昵,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機(jī)與錄音咽斧,去河邊找鬼堪置。 笑死躬存,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的舀锨。 我是一名探鬼主播岭洲,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼坎匿!你這毒婦竟也來了盾剩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤替蔬,失蹤者是張志新(化名)和其女友劉穎告私,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體承桥,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驻粟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了凶异。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜀撑。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖剩彬,靈堂內(nèi)的尸體忽然破棺而出酷麦,到底是詐尸還是另有隱情,我是刑警寧澤襟衰,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布贴铜,位于F島的核電站,受9級特大地震影響瀑晒,放射性物質(zhì)發(fā)生泄漏绍坝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一苔悦、第九天 我趴在偏房一處隱蔽的房頂上張望轩褐。 院中可真熱鬧,春花似錦玖详、人聲如沸把介。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拗踢。三九已至,卻和暖如春向臀,著一層夾襖步出監(jiān)牢的瞬間巢墅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留君纫,地道東北人驯遇。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像蓄髓,于是被迫代替她去往敵國和親叉庐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354