跳到主要內容

抓抓爬爬的好幫手 PHP CURL

好一個抓爬仔 PHP cURL

現在好流行 “自己的 OO 自己 O” 前次的會議中,看到傳播學院的學生實實在在的貫徹了這個理論,“自己的網頁自己”該學生由於不想一頁一頁的存需要的網頁,自己寫了一個小爬蟲來爬這些網頁的資料存成 CSV 檔。只能在心裡說:同學,留口飯給我們吃啦!

對於爬資料,PHP 裡面除了使用 fopen 的方式抓取網頁,還有一個厲害的抓爬仔函式庫 cURL (client URL)。這個函式庫支援 libcurl,允許我們使用來與不同類型的 Server 做溝通。在 ubuntu 下預設是沒有安裝這個套件,可透過 apt-get 來安裝。

$ sudo apt-get install php5-curl

cURL 函式

使用 PHP cURL 的方法很簡單,只要初始化、設定、執行、關閉四個步驟就好,活用和複雜的部分是在設定這個步驟裡的參數設定。

  1. 初始化

    curl_init() 函式初始化一個 cURL session,會傳回一個 cURL handle 作為後面設定執行等函式使用。初始化的時候可以直接指定 URL ,或保留空白由後面設定中在指定。
  2. 設定

    使用 curl_setopt() 函式設定 cURL session handle 的項目內容,這裡有非常非常多的項目參數可以設定,可以參考 官方網站 curl_setopt 的項目參數說明本文後面僅列出常用的參數。
  3. 執行

    curl_exec() 函式執行一個已經設定好參數的 cURL session。執行成功時會回傳 TRUE 失敗時回傳 FALSE,如果參數裡包含 CURLOPT_RETURNTRANSFER 設定為 TRUE 時,執行成功後會回傳內容。
  4. 關閉

    curl_close() 函式會關閉指定的 cURL session,並釋放資源及刪除 cURL handle。
一個簡單的範例:

// 建立一個新的 cURL session
$ch = curl_init();

// 設置 URL 及其他參數
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch, CURLOPT_HEADER, 0);

// 抓取 URL 內容
curl_exec($ch);

// 關閉 cURL session 釋放系統資源
curl_close($ch);

cURL 傳送常用項目參數

Option Note
CURLOPT_RETURNTRANSFER 將獲得的資料傳回
CURLOPT_TIMEOUT 允許 cURL 執行的最長秒數
CURLOPT_CONNECTTIMEOUT 允許和伺服器連線的最長秒數
CURLOPT_POST 啟用後會送出一個常規的 POST 請求
CURLOPT_POSTFIELDS POST 請求時的參數,可以是陣列或字串
CURLOPT_USERAGENT 在 HTTP 請求中加入 user-agent 字串,可用來模擬瀏覽器或其他爬蟲
CURLOPT_COOKIE 設定 HTTP 請求中「Set-Cookie:」部分的內容,以分號 ; 作為參數間的分隔
CURLOPT_COOKIEJAR cURL 收到的 HTTP 請求中 Set-Cookie 存放為檔案的檔案位置
CURLOPT_COOKIEFILE cURL 發出的 HTTP 請求的 Cookie 檔案存放位置
CURLOPT_REFERER 設定 HTTP 請求中「Referer:」部分的值
CURLOPT_FOLLOWLOCATION 遞迴跟隨 「Location:」,可用來跟隨被重新導向的頁面資料
CURLOPT_MAXREDIRS 指定最大重新導向的數量,這個選項是與 CURLOPT_FOLLOWLOCATION 一起使用的。
CURLOPT_VERBOSE 啟用時會報告 cURL 每一件意外的事情
CURLOPT_STDERR 設置一個錯誤輸出地址,值是一個資源類型
抓取資料很有趣也很有挑戰性,會隨著我們的目標不同而有不同的抓法及解析方法,有空再繼續補充了!

留言

這個網誌中的熱門文章

Word的合併列印如何出現「千分位」符號

今天樓下的同事突然問我一個問題,合併列印的時候如何顯示「千分位符號」(逗號),就是12 , 300。在Excel我們可以很容易的為儲存格裡的數字加上千分位的標記,但是儲存格實際儲存的還是只有數字,那個千分位符號是Excel給我們看的一種「格式」。 當我們在Word裡使用Excel做好的報表來合併列印的時候,Word會最真實的將這個數字欄位給讀出來,呈現在合併列印的欄位數值裡,無論在Excel理事不是有設定千分位符號,在Word合併列印後卻沒有出現,所以我們同樣的必須給他加上格式。 Word裡加上格式並不如Excel裡按一下就完成,加上逗號的千分位格式方法如後: 1.在Word裡插入合併列印的欄位變數。 2.在變數上按滑鼠右鍵,選擇「切換功能變數代碼」(也可以直接按Alt+F9),變數會由 << 經費 >> 變成 { MERGEFIELD "經費" } 。 3.加上格式就是把 { MERGEFIELD "經費" } 在}前加入數字格式參數 /##,###,會成為 { MERGEFIELD "經費" /# ##,### }(這裡指定五位數,以此類推) #:這個格式項目會指定要在結果中顯示的必要位數;如果結果不含該位數的數字,則 Word 會顯示一個空格。 0:這個格式項目會指定要在結果中顯示的必要位數;如果結果不含該位數的數字,則 Word 會顯示 0 (零)。 4.預覽內容,就可以發現千分位(逗號)出現,如果數值有零的話,最好可以換成 /# ##,## 0 ,避免空格出現。 數字格式參數請參考 Microsoft Office Online 。

在DOS下檔案名稱加上日期

由於要完成檔案自動備份的需求,以減少每日使用人工的麻煩,也可以避免人為疏失造成的遺漏,需要定時拷貝某個檔案至遠端,在檔名加上日期以避免檔案覆蓋的情形。由於近來接觸Linux較多,自然比較熟悉Linux的Shell語法,回到Windows裡卻想不到解決的方法。 開始使用電腦時,已經活生生的跳過了DOS的年代,雖然會使用Copy語法,卻不知怎麼加上系統日期,參拜估狗大師後得到了解答,使用%DATE%環境變數。 在DOS中使用date會顯示目前日期,但會要求輸入新的日期時間不符合需求,雖然加上"/T"不會詢問新時間,但因為date是指令無法使用在copy的語法中,所以我們使用%DATE%環境變數,所以在我們要加上日期的檔案上加上此環境變數:copy test.txt test_%DATE%.txt 結果並不如我們想像,使用echo看%DATE%的傳回值,會出現"2007/12/4",使用於copy語法裡系統回應「命令語法不正確」,我們必須去除「/」的符號,這就需要用到環境變數的擴充功能了! 用echo來測試: # echo %DATE:~0,4% : 取環境變數%DATE%的值,由第一碼開始取四碼(可以取出"西元年"的值)。 # echo %DATE:~5,2% :取環境變數%DATE%的值,由第六碼開始取二碼(可以取出"月"的值)。 # echo %DATE:~8,2% :取環境變數%DATE%的值,由第九碼開始取二碼(可以取出"日"的值)。 原先的 #copy test.txt test_%DATE%.txt 要更改成 #copy test.txt test %DATE:~0,4% %DATE:~5,2% %DATE:~8,2% .txt 拷貝後的檔案為test_20071204.txt

DOS下連線/中斷網路磁碟機

最近實在是不得不和DOS多一點親近,在Linux中我們可以mount遠端電腦NFS分享出來的資料夾來做存取,輕易的備份我們需要的資料後再unmount,很Easy~:) 原本想在Windows下更應該輕而易舉的完成「連線網路磁碟機」用來將資料備份至遠端的電腦(或是遠端儲存設備)。沒錯,的確可以簡單的連線網路磁碟機,但當我們設定排程自動執行批次檔(*.bat)來進行遠端備份的工作時,windows就發揮他暈倒的功力......很抱歉,登出以後,剛剛建立的「連線網路磁碟機」就自動"中斷"了,批次檔裡寫的檔案路徑形同無效路徑。 只好繼續參拜估狗大神,以期保佑永不當機...不對,是在DOS下連線到網路磁碟機啦! DOS下我們要使用連線網路磁碟機,必須使用 net use 指令。 連線網路磁碟機: # net use x: \\ComputerName\ShareName "Password" / user: DottedDomain\UserName x :要對應至本機磁碟的代號 \\ComputerName\ShareName :遠端電腦及分享資料夾名稱 /user:DottedDomain\UserName :連線使用者名稱 例如: # net use z: \\192.168.0.10\sharefolder 連線至192.168.0.10的sharefolder對應至本機的z磁碟 # net use z: \\192.168.0.10\sharefolder "test" /user:192.168.0.10\Jeffy 連線至192.168.0.10的sharefolder對應至本機的z磁碟,連線時使用"Jeffy"連線密碼為"test" 連線網路磁碟機後,及可以直接切換磁碟機代號進入遠端連線的資料夾,進行copy或其他指令動作,完成任務後再中斷網路磁碟。 中斷網路磁碟機: # net use x: /delete x :連線的網路磁碟機代號 更詳盡的net use使用方式和參數請見 Microsoft Net use 。