從本章開始,咱們將要進入反反爬蟲篇的內容。javascript
感受若是是第一聽到這個名字的讀者確定是懵逼的狀態。如今咱們先來介紹一下什麼是爬蟲、反爬蟲、反反爬蟲。html
爬蟲其實就是咱們前面所學的代碼,直接使用requests.get("http://xxx.com")
就能拿到網站的源碼。java
可是不少時候,咱們獲取的都是有價值的數據,而網站開發者就不想讓咱們拿到他們的數據,就有了不少反爬蟲的策略,不讓咱們那麼容易的爬取到數據。反爬蟲的策略其實其實主要就是三個方面:python
固然,除了這三個,還有些別的東西,好比說User-Agent
識別這樣的就屬於比較基本的了,咱們這裏就不展開了。web
而反反爬蟲,其實就是針對上面的三個方面給出解決方案:chrome
關於爬蟲、反爬蟲、反反爬蟲的故事,知乎上的這個回答描繪的很是形象。windows
如何應對網站反爬蟲策略?如何高效地爬大量數據? - 申玉寶的回答 - 知乎 www.zhihu.com/question/28…瀏覽器
經過上面的介紹,讀者應該對反反爬蟲有了一個基本的認識了。本章將要對反爬蟲的第一個方案:JS加密,進行反反爬蟲。bash
在介紹反反爬蟲方法以前,咱們先拿百度測試一下。這裏假設咱們想爬一爬百度搜索美女的搜索結果,也就是這個連接:www.baidu.com/s?wd=%E7%BE…(注:這裏URL進行了url編碼)服務器
咱們先用以前超級好用的requests庫試一下。
稍微懂點兒html的就知道,這裏沒看到所謂的美女圖,反而還讓咱們跳轉回www.baidu.com/。
上面咱們用requests.get
什麼都沒看到,但咱們用瀏覽器訪問www.baidu.com/s?wd=%E7%BE…的時候,的的確確看到了搜索結果的。
用requests不行,明顯是百度的後臺識別出來咱們是低劣的爬蟲程序,鄙視咱們,什麼都不給咱們。
既然用瀏覽器能夠,咱們是否是能夠經過Api調用咱們的瀏覽器而後爬取搜索結果呢?
確實是能夠,並且還有種瀏覽器叫:Headless Browser,也就是無頭瀏覽器,沒有界面的瀏覽器。若是有界面的話,咱們可能還要用顯卡去渲染圖形頁面,很是耗費字段,這簡直是專門爲爬蟲開發者設計的。
咱們這裏主要介紹的一款無頭瀏覽器名叫:PhantomJS。雖然它如今已經不更新了,但不妨礙咱們繼續使用它。
咱們首先下載安裝PhantomJS,下載連接爲:phantomjs.org/download.ht…。
下載後解壓能夠看到在bin目錄下面有一個phantomjs
的可執行文件。(若是是windows的話就是phantomjs.exe
)
接下來咱們須要安裝selenium,直接使用pip
命令便可。
pip install selenium
複製代碼
selenium是一個用於Web應用程序測試的工具。它兼容各類瀏覽器,包括:PhantomJS、Chrome、FireFox等。
phantomjs默認的話要用JavaScript寫代碼。安裝了selenium,咱們就可使用python進行操做了。
以上安裝好了以後,咱們再嘗試使用phantomjs爬取一下百度。代碼以下:
from selenium import webdriver
exe_path = "/usr/bin/phantomjs"
driver = webdriver.PhantomJS(executable_path=exe_path)
driver.get("https://www.baidu.com/s?wd=%E7%BE%8E%E5%A5%B3")
driver.save_screenshot("screenshot.png") # 截個圖
print(driver.page_source) # 打印源碼
driver.quit()
複製代碼
這裏須要根據本身phantomjs的下載路徑配置exe_path
。而後首先建立一個driver對象,調用get
訪問頁面,就會自動渲染內部的js,顯示出結果。
注意:在不使用了以後,要調用driver.quit()退出,要否則後臺會有不少phantomjs進程。
這裏咱們調用selenium的截圖方法看下結果。
能夠看到咱們連網頁的截圖都弄出來了。selenium除了截圖以外,還支持不少使用js才能完成的操做,好比說:模擬點擊、滾動等等。若是讀者感興趣能夠本身去研究。
PhantomJS默認的User-Agent使用的是:PhantomJS。若是咱們帶着這個會很容易被網站檢測出來,咱們能夠在建立driver的時候加入配置修改PhantomJS的UA,讓它假裝成Chrome瀏覽器。代碼實現以下:
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap['phantomjs.page.settings.userAgent'] = ('Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36')
exe_path = "/usr/bin/phantomjs"
driver = webdriver.PhantomJS(executable_path=exe_path, desired_capabilities=dcap)
複製代碼
固然,有的時候,你會發現有些網站你用了PhantomJS仍是爬不了,筆者就遇到過這樣的場景。這是由於PhantomJS創建在Qt框架。而Qt實現HTTP棧的方式使它和其餘現代瀏覽器不同。
在Chrome中,發出Http請求的head以下:
GET / HTTP/1.1
Host: localhost:1337
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8,ru;q=0.6 複製代碼
然而在PhantomJS,相同的HTTP請求是這樣的:
GET / HTTP/1.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.9.8 Safari/534.34
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Connection: Keep-Alive Accept-Encoding: gzip Accept-Language: en-US,* Host: localhost:1337 複製代碼
你會注意到PhantomJS頭是不一樣於Chrome(事實證實,其餘全部現代瀏覽器)有一些微妙的不一樣:
在服務器上檢查這些HTTP頭的變化,它應該能夠識別PhantomJS瀏覽器。
若是讀者真的碰到這種狀況的話,就能夠考慮用別的無頭瀏覽器了,好比說Chrome的無頭模式。
Chrome的無頭模式和selenium也能夠結合在一塊兒使用。這裏首先須要下載chromedriver
,而後經過selenium的API使用便可。如下爲簡單的示例,若是讀者對這個感興趣,能夠查閱自行百度查找教程。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
driver = webdriver.Chrome(chrome_options=chrome_options, executable_path='/usr/bin/chromedriver')
複製代碼
這裏還有一款工具叫Splash,它是一個JavaScript渲染服務,基於Twisted和QT5,提供了Http的API。
相比PhantomJS和Chrome的無頭模式,Splash的性能會好不少,並且能夠支持併發渲染,不過須要跑Docker。
兩個比較火的Python爬蟲框架:Scrapy以及PySpider就是使用Splash做爲JS渲染引擎。
這裏筆者只是簡單進行介紹,若是讀者對這個感興趣,能夠查閱自行百度查找教程。