標籤:

用 php 抓取 https 加密的鏈接

剛剛看到一個用 java 抓 zhihu 用戶的文章

一時興起,準備寫一個用 php 抓的腳本= =

然後在第一步就遇到了蛋疼的問題

我以前從來沒用過 curl

好在有官方文檔,跟著來也不算難

然而。。。

zhihu 是 https 加密過的.....

翻了下 php 的官方手冊,寫的不甚詳細

在請教了萬能的 stackoverflow 之後【面向 stackoverflow編程 。。

終於找到了請求 https 加密鏈接的方法。

===================

# 首先說一下,我一開始搜到的方法,都是直接粗暴地禁用 ssl ,雖然這樣的確可以用

# 但是有著強迫症的我沒法忍受人家明明開了 ssl 你還非不用。。。

= =好像 CURLOPT_VERIFYPEER 設置為 FALSE 是代表不驗證 SSL 證書和 host name 的合法性.

也就是說信任所有證書頒發機構

也就是說把這個設置為 FALSE 以後, HTTPS 實質上無法抵禦中間人攻擊。

所以為了安(qiang)全(po)著(zheng)想,還是設置為 TRUE 吧。

直接貼圖,一步一步解釋。

#18 初始化 curl#19 設置鏈接#20 設置 HTTP HEADER ,其實打開瀏覽器,按開 F12 然後把 Request Headers 里除了 cookie 以外的部分一行一行複製進去就好了(這個是個數組,每一行是一項)

#21 設置 cookie ,講道理我覺得這個理論上應該可以放在 HTTPHEADER 里沒必要單獨拿出來的吧,不過我沒試過,手冊里說要單獨拿出來就拿出來吧,把剛剛剩下的 cookie 放進來

#22 如果這一項設置成 TRUE ,那麼最後執行 curl_exec 的時候會返回結果,否則只會返回 TRUE 、 FALSE, 而把結果粗暴的直接顯示在頁面上(相當於自動幫你 echo 了)。所以如果需要對返回的數據做進一步地處理,一定要設置成 TRUE 。#23 這一項如果設置成 FALSE ,那麼 #24 和 #25 都不需要了,相當於此時 https 的作用僅用於防止最簡單的 http 流量劫持。#24 #25 這兩項我並不知道有啥差別,反正目前設置成一樣的能正常工作。最後再來講這個證書是咋來的(圖比較多)#26 設置編碼格式,由於知乎使用了gzip壓縮,如果不設置這一項,拿到的數據就是亂碼。當然也可以拿到數據以後再解碼,不過我覺得這樣設置比較方便= =#27 #28 #29 輸出數據及調試語句

然後就是說這個證書的問題= =

curl 需要的證書只是一個根證書,然後從這個根證書下來的信任鏈上的所有證書都被信任。

所以可以定期維護一個根證書文件(本文中使用的是 Mozilla 的 CA 列表,也就是火狐使用的 CA 列表)。

根據官網上的教程

找個喜歡的地方放證書文件,然後可以用這個命令下載(也可以手動下載替換)

curl --remote-name --time-cond cacert.pem https://curl.haxx.se/ca/cacert.pem

使用命令下載的好處就是你可以把它放在 crontab 里定時更新,不需要老是手動更新。

相應的,上面 #24 中的證書路徑也要替換為下載下來的這個文件

#25 我目前測試下來是可以直接注釋掉也沒有問題。。。

======= 以下為 原先暴力取得證書的方法 =======

以 Chrome Stable x64 v57 版本為例

打開知乎,按 F12 ,然後選擇這個

security 選項卡下的 view certificate 按鈕

選中 證書路徑 選項卡 下的根證書(最頂上那個),然後點查看證書

選擇 詳細信息,點 複製到文件

會彈出一個 證書導出嚮導,其他的步驟就 下一步下一步 ,然後自己選一個喜歡的目錄存放就好

但是這一步需要注意,選擇 Base64 編碼格式的證書,不然 PHP 不識別。

導出以後在 PHP 里用就行了

來看一下效果

=== EOF ===

我終於淪落到開始寫科普類文章的地步了【捂臉


推薦閱讀:

PHP開發微博,需要注意哪些問題?或者是需要用到哪些技術便於開發?
為什麼C++ 程序員看不起php?
Linux下php-fpm進程過多導致內存耗盡問題解決
Zend opcode是如何被執行的?是要編譯為機器碼再執行嗎?

TAG:PHP | cURL | SSL |