收錄待用,修改轉載已取得騰訊雲授權
一、引言
在實際工作中,難免會遇到從網頁爬取數據信息的需求,如:從微軟官網上爬取最新發布的系統版本。很明顯這是個網頁爬蟲的工作,所謂網頁爬蟲,就是需要模擬瀏覽器,向網絡服務器發送請求以便將網絡資源從網絡流中讀取出來,保存到本地,並對這些信息做些簡單提取,將我們要的信息分離提取出來。
在做網頁爬蟲工作時會發現並不是所有網站都是一樣,比如有些網址就是一個靜態頁面、有些需要登錄后才能獲取到關鍵信息等等。此外,python簡單而又強大,又有不少第三方庫可以讓我們輕松拿到瀏覽器中所看到的內容。因而,本文將根據網站特性進行分類介紹幾種使用python完成網頁爬蟲的方法。
二、靜態頁面
在做爬蟲工作時,什么類型的網站最容易爬取數據信息呢?不需要登錄等處理,直接用Get方法請求URL即可從服務器獲取到返回數據,如我們訪問一些博客文章,一個Get請求就可以拿到博客文章里的內容。下面將舉例介紹如何爬蟲這種類型頁面內容該如何爬取。
示例
1、需求說明:假設我們需要及時感知到電腦管家官網上相關產品下載鏈接的變更,這就要求我們寫個自動化程序從官網上爬取到電腦管家的下載鏈接。
2、分析過程:在瀏覽器中打開https://guanjia.qq.com,按下F12, 查看網絡請求,內容如下圖。這里只有一個Get請求,沒有登錄,也不涉及加密過程。此外,點擊Elements,可以很容易的從源碼中找到下載鏈接。
圖1
3、解決方案: requests是python的第三方庫,可以發送網絡請求數據並獲取服務器返回的源碼。使用requests庫獲取到html文件,然后利用正則等字符串解析手段或者BeautifulSoup庫(第三方庫)完成信息提取。下面代碼展示的是利用requests庫和BeautifulSoup庫完成信息提取。
圖2 源碼截圖
知識點
1、有些網絡服務器反感爬蟲,會對請求頭做個簡單判別,直接拒絕那些明顯是由自動化程序發起的請求。就例如圖2中的代碼,python使用的默認請求頭User-Agent值為Python-urllib/3.4,而瀏覽器訪問時User-Agent值為:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.3。為了避免自動化程序被拒絕,在請求時可以修改請求頭,讓自動化程序更像一個瀏覽器。
2、在網頁爬取時,可能會遇到公司網絡不允許訪問外網的情況,這時就需要設置代理IP: requests.get("https://guanjia.qq.com", proxies={“http”:“127.0.0.1:8087”})
3、BeautifulSoup庫是HTML/XML解析器,它可以很好的處理不規范標記並生成剖析樹,通常用來分析爬蟲抓取的web文檔,可以大大節省編程時間。
三、POST表單
前面介紹的是通過HTTP協議的Get方法去請求信息,對應網站不涉及post表單。表單是含有標簽,是要交互的數據區域,你可能需要輸入文字、做下拉選擇等,完成與服務器的交互。下面將給個簡單的示例讓大家理解post表單情況。
示例
1、需求說明:訪問網址,並輸出服務器返回內容。
2、分析過程:在瀏覽器中打開http://pythonscraping.com/pages/cookies/welcome.php,展示在面前的是個登錄界面, 按下F12,可看到如下圖的信息。很明顯這是一個表單。點擊登錄后查看Network,會發現看到一個post請求以及請求參數。當登錄完成后,即可訪問http://pythonscraping.com/pages/cookies/profile.php,查看網址中詳細內容。
3、解決方案:仍然使用強大的requests庫完成post表單操作,下面將僅展示post登錄那里,登錄過后的頁面內容解析和第二部分一致,這里不再詳細贅述。
知識點
1、需要注意cookie的追蹤。一旦網站驗證了你的登錄權證,它將會將登陸權證保存在瀏覽器的cookie中,若是我們一直自己處理cookie的追蹤,在面對復雜網址時將會比較麻煩,降低開發效率。我們可以使用Session對象解決這個問題,就如上述截圖代碼中。Session會持續跟蹤會話信息,包括cookie,header。可以調用session.cookie.get_dict()查看當前session cookie值。
2、在表單中存在“隱含”字段,該字段是對瀏覽器可見,但是對用戶不可見。一般而言,“隱含”字段是在每次Get請求時生成,每次打開同個網址,同個“隱含”值不一樣。這個處理有一定的反爬蟲效果。至於“隱含”字段是否作為post參數,可以手動在瀏覽器下完成表單請求,觀察請求參數是否包含某個“隱含”參數。如下圖:網址包含“隱含”字段,並在post時帶上。
第二部分介紹的header、代理IP同樣適用於這里。
四、HTTP基本接入認證
基本認證是一種用來允許Web瀏覽器后者其他客戶端程序在請求時,提供用戶名和口令形式的身份憑證的一種登錄驗證方式。把“用戶名+冒號+密碼”用BASE64算法加密后的字符串放到httprequest中的headerAuthorization中發送給服務端。在發明cookie之前,HTTP基本認證是處理網站登錄最常用的方法,目前一些安全性比較高網址還在使用這種方式。
示例
1、需求說明:訪問某網站(涉及內部,不對外公布)。
2、分析過程:在瀏覽器中輸入該網址,看到如下頁面。這時候需要輸入用戶名和密碼才能得到所需要的數據。否則會返回錯誤代碼401,要求用戶重新提供用戶名和密碼。此外用fiddle抓取中間數據時,header中有如下信息:,很明顯這是一個HTTP基本認證。
3、解決方案:這個實際是個post請求,和普通post的請求區別是:在每次請求數據時,需要用BASE64加密用戶名和密碼,並附加到請求頭中。requests庫提供了一個auth模塊專門用於處理HTTP認證,這樣就不用程序自己做加密處理。下面給出具體代碼:
知識點
目前有多種http登錄驗證方法,其中最廣泛應用的是基本驗證和摘要驗證,auth模塊也提供摘要驗證處理方法,具體使用方法我也沒有研究過,請各位查詢相關資料。
五、JavaScript動態頁面
前面介紹了靜態頁面和含有post表單網站的爬蟲方式,相對比較簡單。而實際在做網頁爬蟲工作時頁面情況更加多樣復雜。如:
1、網頁中包含javascript代碼,需要經過渲染處理才能獲取原始數據;
2、網站具有一定反爬蟲能力,有些cookie是需要客戶端腳本執行JS后才會產生,而requests模塊又不能執行JS代碼,如果我們按照第三部分操作來post表單,會發現部分少了部分cookie,導致請求被拒絕。在當前知名網站反爬蟲工作做的比較好,很難找到簡單post表單就可以。
那有什么好的方式解決這種類型網站的爬蟲呢?
“python+ selenium + 第三方瀏覽器“。
示例
1、需求說明:登錄微軟官網https://connect.microsoft.com/site1304/Downloads,自動下載微軟最近發布iso文件。
2、分析過程:
(1) 當我們使用python request庫去獲取服務器源碼時,發現python獲取的源碼和瀏覽器上渲染出的場景不一樣,Python拿到是JS源碼。如下圖:
Python有個第三方庫PyV8,該庫可以執行JS代碼,但執行效率低,此外微軟官網還涉及JS加密的Cookie,若是采用requests + Pyv8 + BeautifulSoup 三種庫組合方式處理,那代碼會顯得臃腫雜亂。
那是否有其他更為簡潔易懂的方式呢?
有, selenium。
(2)“Selenium+ 第三方瀏覽器”,可以讓瀏覽器自動加載頁面,由瀏覽器執行JS從而獲取到需要的數據,這樣我們的python代碼就無需實現瀏覽器客戶端的功能。可以說,“Selenium + 第三方瀏覽器”組成了一個強大的網絡爬蟲,可以處理cookie、javascript等頁面爬取情況。第三方瀏覽器分有界面(chrome)和無界面(PhantomJS),有界面瀏覽器就是可以直接看到瀏覽器被打開以及跳轉的過程。無界面瀏覽器會將網站加載到內存並執行頁面上的JS,不會有圖形界面。可以自己喜好或者需求選擇第三方瀏覽器。
3、解決方案:采用“selenium+ chrome”方式完成需求。
(1)下載安裝python的selenium庫;
(2)下載chromeDriver到本地;
(3)利用webdriver api完成對頁面的操作。下面給出一個示例,完成微軟官網的登錄。示例代碼在初始化webdriver時設置了網絡代理、指定了瀏覽器下載文件保存路徑、讓chrome提示下載進度等信息。
知識點
在實例化webdriver時,可以通過參數對瀏覽器做些設置,如設置網絡代理、瀏覽器下載文件保存路徑等。若是不傳參數,則默認繼承本地瀏覽器設置。若是對瀏覽器啟動時屬性進行設置,則就利用到了ChromeOption類。具體信息可參考chromedriver官網。
“python + selenium + 第三方瀏覽器”可以處理多種爬蟲場景,包括靜態頁面,post表單,以及JS等。應用場景很強大,使用selenium操作瀏覽器進行模擬點擊的方式就可以讓我們省心很多,不需要擔心有什么“隱藏字段”、cookie追蹤等。但對於包含驗證碼網頁的操作,這種方式也不好處理,主要困難在於圖像識別。
六、總結
本文主要針對各網站特點給出不同的爬蟲方式,可以應對大量場景的數據爬取。在實際工作中使用頻率最多還是“靜態頁面”、“javascript動態頁面”這兩種。當然,若是頁面包含驗證碼,那就需要結合圖像識別工具做些事情了,這種情況相對也比較難處理,圖像識別准確率受到圖片內容影響。
這里是個人的一些小總結,不知道大家是否有其他更好的方法呢?
大家若是有其他比較好的爬蟲案例,歡迎在評論區留言,大家一起學習交流!
想知道更多測試相關干貨 請關注我們的微信公眾號:騰訊移動品質中心TMQ。