網(wǎng)路爬蟲:不生產(chǎn)內(nèi)容,只是內(nèi)容的搬運工
搜索引擎和聚合類新聞App之所以有源源不斷的新內(nèi)容供予用戶瀏覽,原因就在于有網(wǎng)絡(luò)爬蟲技術(shù)的加持。網(wǎng)絡(luò)爬蟲的應(yīng)用對于用戶來說,是一大福利——我們可以從一個搜索引擎輕松搜索到各個領(lǐng)域的信息。但是,對于原創(chuàng)方來說,就涉及到版權(quán)被侵犯的問題了。工具理性,但不意味著操持工具的人就可以假借“工具理性”肆意侵犯他人的合法權(quán)益,網(wǎng)絡(luò)爬蟲技術(shù)的應(yīng)用還應(yīng)該要在法理之內(nèi)。
一、初識爬蟲
工作的時候,想要查找“產(chǎn)品設(shè)計”,可以直接在搜索引擎上輸入內(nèi)容,就可以直接找到數(shù)以百萬計的資料。
上下班路上,刷新聞類APP的時候,只要愿意,就會有源源不斷的新的信息,足夠刷一路的時間。
搜索引擎和(大多數(shù))新聞類APP都不自己生產(chǎn)內(nèi)容(雖然有些平臺孵化了自己的內(nèi)容,但也只占整個平臺內(nèi)容的很少的一部分,更重要的是,成本非常高)。
那么,他們的大量的內(nèi)容從哪里來?
“我們不生產(chǎn)內(nèi)容,只是內(nèi)容的搬運工”,將互聯(lián)網(wǎng)上的內(nèi)容“搬運”到自己的服務(wù)器上,這就是爬蟲。
首先,我們需要了解一下互聯(lián)網(wǎng)的結(jié)構(gòu)。
互聯(lián)網(wǎng)上的內(nèi)容數(shù)以億計,雖然很復(fù)雜,但說白了就是一張大網(wǎng),網(wǎng)上的每個節(jié)點就是一個網(wǎng)頁,連接網(wǎng)頁的超鏈接(Hyperlinks)相當(dāng)于線,線把所有的節(jié)點連接在一起,形成了一個復(fù)雜的網(wǎng)。
通過點擊超鏈接的文字或者圖片,就可以跳轉(zhuǎn)到對應(yīng)的網(wǎng)頁。爬蟲可以自動訪問到每一個網(wǎng)頁,并把網(wǎng)頁的內(nèi)容保存下來。
世界上第一個網(wǎng)絡(luò)爬蟲由麻省理工學(xué)院的學(xué)生馬修·格雷(Matthew Gray)在1993年寫成,之后的爬蟲盡管越來越復(fù)雜。
比如:可以實現(xiàn)更快的訪問速度、訪問更多的網(wǎng)頁、更好的將網(wǎng)站內(nèi)容解析出來。但爬蟲的基本原理是一樣的,都主要包括三個部分:訪問網(wǎng)頁鏈接,下載網(wǎng)頁內(nèi)容,解析網(wǎng)頁內(nèi)容。
爬蟲的工作過程與我們查找網(wǎng)頁的過程是一樣的。
比如,我們想要查一下豆瓣上最新的電影:首先,在瀏覽器地址欄輸入網(wǎng)址鏈接https://movie.douban.com/,之后,瀏覽器會跳轉(zhuǎn)到豆瓣電影。最后,我們就可以找到當(dāng)前熱映的電影。
同樣的,一個最簡單的爬蟲三步就可以爬取一個網(wǎng)頁——首先,訪問這個網(wǎng)頁,之后,把網(wǎng)頁內(nèi)容下載下來,最后,對下載的內(nèi)容進(jìn)行解析。
二、7行代碼爬取豆瓣電影
最簡單的爬蟲三步就可以爬取一個網(wǎng)頁,那么要寫多少行代碼呢?
我們寫一個爬蟲,爬取豆瓣的“一周口碑榜”,只要7行代碼!
這里我們使用Python語言,至于為什么選擇Python語言,會在后面交代清楚,如果不懂Python也沒有關(guān)系,了解爬蟲是如何工作的就可以了。
代碼如下:
import requests from lxml
import html url=’https://movie.douban.com/’ # 1、需要爬數(shù)據(jù)的網(wǎng)址
page=requests.Session().get(url) # 2、訪問網(wǎng)頁
tree=html.fromstring(page.text) # 3、解析網(wǎng)頁的過程
result=tree.xpath(‘//td[@class=”title”]//a/text()’) #3、解析網(wǎng)頁的過程
print(result) # 打印出結(jié)果
在Python環(huán)境中運行這幾行代碼,就可以獲取“一周口碑榜”了,結(jié)果如下:
[‘迦百農(nóng)’, ‘綠皮書’, ‘馴龍高手3’, ‘速成家庭’, ‘阿麗塔:戰(zhàn)斗天使’, ‘膚色’, ‘死亡天使’, ‘黎明墻’, ‘小小巨人’, ‘出·路’]
其中最關(guān)鍵的是解析網(wǎng)頁內(nèi)容,主要是(‘//td[@class=”title”]//a/text()’)這行代碼,大多數(shù)人可能對比較困惑。
這涉及到HTML網(wǎng)頁的結(jié)構(gòu),可以把網(wǎng)頁理解成一個文件夾,打開一個文件夾,會發(fā)現(xiàn)子文件夾,子文件夾或許還有文件夾。通過打開一個個文件夾,最終找到需要的數(shù)據(jù)。
- ?//td :這個相當(dāng)于大目錄;
- [@class=”title”]:這個相當(dāng)于小目錄;
- ?//a :這個相當(dāng)于最小的目錄;
- /text():這個是提取其中的文字內(nèi)容。
至于是怎么寫出來這行代碼的,可以通過在網(wǎng)頁空白處點擊右鍵,查看源代碼,就可以找到對應(yīng)的td、class=”title”、a等標(biāo)識符。
大多數(shù)程序員寫爬蟲選擇python的理由很簡單.
首先,python有很多的庫,可以直接調(diào)用,比如:上面的代碼就引入了requests、lxml庫,分別實現(xiàn)訪問網(wǎng)頁、對網(wǎng)頁結(jié)構(gòu)解析。有開源的庫,就直接調(diào)用,避免重復(fù)造輪子。
其次,python寫起來很方便,配置也簡單,短短幾行的代碼,就可以直接運行了,如果使用C或者Java,可能配置環(huán)境就要老半天。
三、一個簡答的爬蟲系統(tǒng)
把上面的每個步驟分別實現(xiàn)(模塊化),就可以構(gòu)成一個簡答的爬蟲系統(tǒng)。
使用URL(可以理解為網(wǎng)址鏈接)管理器管理所有的網(wǎng)址鏈接,使用HTML(可以理解為網(wǎng)頁內(nèi)容)下載器下載網(wǎng)頁內(nèi)容,使用HTML解析器對下載的內(nèi)容解析,再加上數(shù)據(jù)存儲模塊、控制整個爬蟲的調(diào)度模塊,就構(gòu)成了一個簡單的爬蟲系統(tǒng)。
爬蟲基本架構(gòu)
更具體的說,URL管理器負(fù)責(zé)管理所有的網(wǎng)址鏈接,記錄下哪些URL已經(jīng)爬取了,哪些還沒有爬取。如果爬取過了,就要避免再次下載,如果沒有,就要加入隊列,等HTML下載器下載。
HTML下載器可以從服務(wù)器下載整個網(wǎng)頁的內(nèi)容,從URL管理器中獲取未爬取的網(wǎng)址鏈接,之后,訪問這些網(wǎng)頁鏈接,下載網(wǎng)頁。
HTML解析器負(fù)責(zé)解析下載好的網(wǎng)頁,主要有兩個任務(wù):一方面,解析出需要的信息,比如上文的“一周口碑榜”;另一方面,解析出新的URL鏈接,交給URL管理器,繼續(xù)下載,這個功能在上面的“7行代碼”沒有實現(xiàn)。
數(shù)據(jù)存儲器實現(xiàn)存儲數(shù)據(jù)的功能,將HTML解析器解析出來的信息存儲起來,否則每次使用都要下載,會浪費大量的時間。圖片、文檔之類的文件可以直接保存到服務(wù)器上,文字類的可以通過數(shù)據(jù)庫存儲起來。
爬蟲調(diào)度器作為系統(tǒng)的大腦,負(fù)責(zé)統(tǒng)籌其他四個模塊的協(xié)調(diào)工作。
無論是大型的還是小型的爬蟲雖然在設(shè)計細(xì)節(jié),性能上有所不同,但都不會脫離這五個模塊。
四、更深入的考慮
乍一看,每個模塊實現(xiàn)起來都很簡單,但細(xì)想,似乎每個模塊都要考慮很多東西。
1. 初始的網(wǎng)址鏈接如何獲得
7行代碼爬取豆瓣電影,直接訪問網(wǎng)址鏈接(https://movie.douban.com/)就可以爬取“一周口碑榜”。對稍大一些的爬蟲系統(tǒng)或者商用爬蟲,就要有更多的考慮了,在保證獲取充足信息的同時,也要保證下載的質(zhì)量。
對搜索引擎公司而言,要盡可能包括互聯(lián)網(wǎng)所有的信息。對垂直領(lǐng)域,更多的偏向業(yè)務(wù)類信息,比如:對新聞類的APP,主要包括一些新聞網(wǎng)站、政府網(wǎng)站等,對Github這類的編程網(wǎng)站,他們可能就不感興趣。
巧婦難為無米之炊,初始的網(wǎng)址鏈接基本要靠人工憑經(jīng)驗獲取,比如:新聞類的APP,他們的初始URL列表里可能就包括新浪、網(wǎng)易、搜狐等門戶網(wǎng)站,也包括各個級別的政府網(wǎng)站,還有人民網(wǎng)、新華社、人民日報等媒體的網(wǎng)站。
2. 如何確定哪些網(wǎng)頁已經(jīng)下載過了
當(dāng)一個頁面下載完成后,從這個網(wǎng)頁中提取出其中的網(wǎng)址鏈接,把它們添加到等待下載的隊列中,就可以獲得更多的網(wǎng)址鏈接。
如果一個網(wǎng)頁已經(jīng)下載過了,重新下載,會消耗大量的時間,并占用存儲空間。更要命的是,如果一直重復(fù)下載,就可能陷入死循環(huán)。
那么,如何知道這網(wǎng)址鏈接是不是已經(jīng)下載過了?
對于小型爬蟲,可以使用列表存儲下載過的網(wǎng)址鏈接,當(dāng)有新的網(wǎng)址鏈接的時候,先查找這個列表中有沒有該網(wǎng)址鏈接。如果有的話,就不用插入,如果沒有的話,就插入列表,等待訪問下載。
對于大型爬蟲,有成百上千個“小爬蟲”(更加專業(yè)的名詞叫做分布式爬蟲),分布在不同的服務(wù)器上,同時爬取網(wǎng)址鏈接,就要考慮更多的東西。
比如:不同爬蟲之間的分工和通信,如何共同維護(hù)上述的列表。
當(dāng)數(shù)據(jù)很大的時候,就要考慮分布式、通信、存儲、帶寬等每個環(huán)節(jié)的限制,無論哪個環(huán)節(jié)沒有做好,都有可能成為系統(tǒng)的瓶頸,這就像是木桶效應(yīng)中的短板。
數(shù)據(jù)量增加10倍,之前的代碼可能要重寫了,工作量可能就要增加100倍,這也是量變引起質(zhì)量的一個很好的例子。
在計算機(jī)領(lǐng)域,這樣的例子隨處可見,當(dāng)數(shù)據(jù)增大到一定量級,原有的算法很可能無法繼續(xù)使用,需要重新開發(fā),隨之而來的是加班、DEBUG以及延期上線。
3. 頁面的解析
爬取豆瓣電影的“一周口碑榜”,需要研究網(wǎng)頁的源代碼,并編寫對應(yīng)的解析代碼。但是網(wǎng)頁的結(jié)構(gòu)不同,用這個代碼爬取知乎,解析不到任何內(nèi)容。
以新聞類的APP為例:一個好的新聞類APP需要爬蟲數(shù)以億計的網(wǎng)頁,并把里面的文字、視頻、圖片分別解析出來,難度可想而知。
好消息是一部分網(wǎng)站會遵守RSS規(guī)范(遵守RSS規(guī)范的網(wǎng)頁結(jié)構(gòu)和代碼都有相似性,以便于訂閱器獲取主要信息),一種類型的爬蟲就可以爬取大量這種類似的網(wǎng)頁。但大部分的網(wǎng)站的結(jié)構(gòu),都是不同的,這需要算法工程師花費大量的時間和精力做解析工作。
五、 反爬蟲
新聞類APP通過爬蟲,獲得大量的優(yōu)質(zhì)資源,讀者也樂意在一個平臺上看到所有的內(nèi)容,但“被爬取”的網(wǎng)站就不太高興了。對于大多數(shù)依靠廣告收入的網(wǎng)站,沒有了流量,連生存都成了問題,更別說盈利了。
一些自成體系的平臺,比如:大型電商平臺,他們希望所有的用戶在自己的平臺上查找信息,所有的商家在自己的平臺上吸引賣家(廣告費可不能付給搜索引擎),同樣不希望爬蟲的騷擾。
搜索引擎希望爬取更多的信息,優(yōu)質(zhì)的內(nèi)容提供商又不希望被爬蟲騷擾,利益沖突難以調(diào)和,于是產(chǎn)生了Robots協(xié)議來解決這個問題。
Robots協(xié)議網(wǎng)站服務(wù)器的一個聲明,通常是保存在網(wǎng)站根目錄下的一個TXT格式的文件,網(wǎng)站通過Robots協(xié)議告訴搜索引擎:哪些頁面可以抓取?哪些頁面不能抓取?
當(dāng)爬蟲訪問一個站點時,它會首先檢查該站點根目錄下是否存在robots.txt,如果存在,爬蟲就會按照該文件中的內(nèi)容來確定訪問的范圍;如果該文件不存在,所有的爬蟲將能夠訪問網(wǎng)站上所有沒有被口令保護(hù)的頁面。
我們使用搜索引擎,經(jīng)常會看到“由于該網(wǎng)站的robots.txt文件存在限制指令(限制搜索引擎抓取),系統(tǒng)無法提供該頁面的內(nèi)容描述”,就是源于這個協(xié)議。
值得注意的是:Robots協(xié)議是國際互聯(lián)網(wǎng)界通行的道德規(guī)范,并沒有強制性約束力。
一些“沒有道德”的爬蟲同樣會爬取有robots.txt限制指令的網(wǎng)站,這時候就需要一些技術(shù)來實現(xiàn)反爬蟲了。
最常見的有三種方式:
1. 網(wǎng)站會根據(jù)IP地址訪問的頻率確定是不是爬蟲
每個電腦都有唯一的IP地址,每個爬蟲也有唯一的IP地址,當(dāng)電腦或者爬蟲訪問網(wǎng)站的時候,網(wǎng)站會記錄這個IP地址。如果同一個IP短時間多次訪問同一個網(wǎng)站,這個網(wǎng)站可能會傾向于認(rèn)為這是個爬蟲,會采取一些措施。
最常見的就是驗證碼、點擊圖片之類的驗證機(jī)制了。
我們使用12306買票的時候總需要點擊圖片,就是一種反爬蟲機(jī)制——因為爬蟲太多,一個爬蟲每秒可以實現(xiàn)成百上千次的點擊,在春運等高峰時段,12306上爬蟲點擊買票的次數(shù)甚至要超過人點擊的數(shù)量。于是,就干脆全部使用驗證機(jī)制。
當(dāng)然,這在反爬蟲的同時,也會給用戶帶來一些不好的體驗。
相比之下,一些比較優(yōu)秀的網(wǎng)站或者APP,會根據(jù)用戶點擊頻率、時間間隔等信息,判斷是不是爬蟲或者誤點擊,之后再確定是否需要驗證。
更好的用戶體驗背后,是更大的開發(fā)成本,更長的開發(fā)周期。
2. 網(wǎng)站也可以根據(jù)用戶請求的Headers來判斷是不是爬蟲
當(dāng)我們使用瀏覽器訪問網(wǎng)站的時候,瀏覽器會自動在訪問請求上添加一些信息,比如:瀏覽器采用的編碼方式、使用的操作系統(tǒng)、瀏覽器版本等信息放在訪問請求的最開始,作為Headers,但爬蟲一般不會附加這些信息。
網(wǎng)站會根據(jù)是否存在Headers信息以及Headers信息的內(nèi)容,判斷對方是不是爬蟲,有必要的話,就拒絕訪問。
3. 動態(tài)頁面的反爬蟲
之前將的HTML網(wǎng)頁都是靜態(tài)的,隨著HTML代碼生成,頁面的內(nèi)容和顯示效果就不會發(fā)生變化了。而動態(tài)網(wǎng)頁則不然,動態(tài)網(wǎng)站是腳本語言(比如PHP)生成的,一些內(nèi)容不是直接可見的,而是要運行一些腳本,才能看到。
網(wǎng)址后綴為htm、html、shtml、xml的網(wǎng)頁是靜態(tài)網(wǎng)頁,而動態(tài)網(wǎng)頁是以·aspx、.asp、.jsp、.php、.perl、.cgi等形式為后綴,并且在動態(tài)網(wǎng)頁網(wǎng)址中有一個標(biāo)志性的符號“?”,這些不同的后綴基本代表了網(wǎng)頁使用的語言。
訪問靜態(tài)網(wǎng)頁,只需要直接訪問鏈接就可以了,訪問動態(tài)網(wǎng)站,還需要執(zhí)行一些特定的操作(比如點擊),才能顯示更多的內(nèi)容,這就增加了爬取的難度,一些簡單的爬蟲就被拒之門外了。
介紹完三種主流的反爬蟲的方式,最后要說的是:反爬蟲技術(shù)也不是一勞永逸的,在反爬蟲的發(fā)展過程中,爬蟲也進(jìn)化出了一系列反“反爬蟲”的方式。
針對反爬蟲驗證IP機(jī)制,爬蟲“進(jìn)化”出了IP代理池,這樣,爬蟲就可以不斷變換自己的IP地址,迷惑反爬蟲。針對Headers驗證,爬蟲也會生成一個Headers信息,甚至針對動態(tài)頁面,也會模擬瀏覽器的行為。
雖然如此,反爬蟲在一定程度上提高了爬蟲的成本,降低了爬蟲的效率,就可以將一大部分爬蟲擋在門外。
從爬蟲與反爬蟲的例子也可以看出:大多數(shù)時候,沒有絕對的有效方式。提高對方的成本,讓對方覺得代價太大,得不償失,就是很好的解決問題的辦法。
六、爬蟲實現(xiàn)冷啟動——勝利即正義?
上面講了爬蟲是怎么運行的,常見的反爬蟲機(jī)制。最后,我們再講一個爬蟲的應(yīng)用場景的例子,可以幫助我們更好理解爬蟲。
冷啟動是每一個產(chǎn)品經(jīng)理、運營人員和創(chuàng)業(yè)者面臨的重大問題。沒有優(yōu)質(zhì)的內(nèi)容,就吸引不了用戶,沒有大量的用戶,就無法吸引優(yōu)質(zhì)的內(nèi)容,就陷入了先有雞還是先有蛋的悖論。
爬蟲,低成本、快速地解決了這個問題!
“我們不生產(chǎn)新聞,我們只是新聞的搬運工”,通過爬蟲,低成本、快速地爬取整個互聯(lián)網(wǎng)的優(yōu)質(zhì)內(nèi)容,并憑借海量數(shù)據(jù),利用算法實現(xiàn)內(nèi)容分類和個性推薦(個性推薦系統(tǒng)會在后序章節(jié)詳細(xì)介紹),吸引大量的用戶,最終通過廣告變現(xiàn)。
事實證明,這是個非常成功的商業(yè)模式。而媒體平臺和新聞網(wǎng)站雇傭大量編輯人員,花費大量時間、金錢寫成的高質(zhì)量內(nèi)容,連說一聲都沒有,就這樣被拿走了,這不是侵犯人家版權(quán)嘛!
于是,多家媒體聯(lián)合發(fā)起侵權(quán)訴訟或抗議聲討,最終迫使這家新聞巨頭支付版權(quán)費,但無論法律上、道德上有多少問題,都不影響這家公司商業(yè)成功的既定事實。
類似的事情同樣發(fā)生在其他垂直領(lǐng)域。
一家新成立的技術(shù)博客平臺,爬取競爭對手上的文章,迅速實現(xiàn)優(yōu)質(zhì)內(nèi)容的聚合。如果原博客主發(fā)現(xiàn)了自己的文章被盜用了,新的平臺就移交賬號并看情況給予少許補償。如果對方不樂意,就注銷賬號,當(dāng)一切都沒有發(fā)生過。憑借這種運營方式,順利實現(xiàn)了冷啟動。
短視頻APP的后來者,也可以通過類似的方式,實現(xiàn)用戶的積累和優(yōu)質(zhì)內(nèi)容的聚合。
勝利即正義?
這似乎是過于武斷的一個評價。
上述的視頻APP做得太過分,引起公憤,最終不得不關(guān)閉自己的平臺。
對于通過爬蟲獲取內(nèi)容的平臺而言,內(nèi)容的獲取也只是萬里長征的第一步,通過運營手段減小生產(chǎn)內(nèi)容的成本,通過利益共享激勵優(yōu)質(zhì)內(nèi)容的產(chǎn)生,通過技術(shù)減小信息成本吸引用戶,更加任重而道遠(yuǎn)。
而版權(quán),也始終是懸于頭頂?shù)倪_(dá)摩克利斯之劍。
本文由@linghu 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理,未經(jīng)許可,禁止轉(zhuǎn)載
題圖來自Unsplash, 基于CC0協(xié)議
每個電腦的IP這個不正確吧,訪問服務(wù)器一般都是公網(wǎng)IP,只能說是一個區(qū)域的IP地址吧
謝謝,我要爬了你這篇文章
三篇文章都是干貨,有理有據(jù),可以加個 l__eon 相互學(xué)習(xí)一下嗎
樓主,我要爬了你這篇文章 ??
想知道那個上述視頻APP是
刷寶
這么好的文章最近怎么評論變少了呢?