爬蟲能干什么呢?一句話概括,正常通過(guò)瀏覽器可以獲取的數(shù)據(jù),爬蟲都可以獲取。這句話可以說(shuō)是包羅萬(wàn)象。一是說(shuō)明了爬蟲的本質(zhì)是一個(gè)服務(wù)端,實(shí)現(xiàn)的功能類似于瀏覽器;二是說(shuō)明了爬蟲的界限,如果不能正常訪問(wèn)到的數(shù)據(jù)就不能通過(guò)爬蟲獲取;三是爬蟲的最高境界,只要是瀏覽器能正常訪問(wèn)的都可以用爬蟲獲取。更多爬蟲的神奇用處。 下面我們講講爬蟲的基本結(jié)構(gòu)和簡(jiǎn)單實(shí)現(xiàn)。這篇文章我不準(zhǔn)備詳細(xì)地講具體怎么寫爬蟲,只是先用一個(gè)非常簡(jiǎn)單的實(shí)現(xiàn),給大家看看爬蟲是個(gè)什么樣子。詳細(xì)的內(nèi)容我們后面一個(gè)一個(gè)慢慢說(shuō)。 一、爬蟲的基本結(jié)構(gòu) 讓我們忽略掉來(lái)自各種各樣的資料對(duì)于爬蟲結(jié)構(gòu)的描述,把問(wèn)題盡可能地描述簡(jiǎn)單一點(diǎn)。前面說(shuō)到,爬蟲是一個(gè)獲取正常瀏覽器可以獲取的數(shù)據(jù)的自動(dòng)化獲取程序。那么,從這個(gè)功能出發(fā),我們需要干的事情其實(shí)就兩件事情:找到我們需要的網(wǎng)頁(yè),然后把他們一個(gè)一個(gè)處理一遍。(這句話很重要,我們?cè)诤竺娴暮竺嬷v到海量數(shù)據(jù)爬取策略的時(shí)候還要回到這句話。)那么問(wèn)題就來(lái)了:一,怎么找到我們需要的網(wǎng)頁(yè)的那個(gè)入口?二,怎么處理我們需要處理的網(wǎng)頁(yè)? 對(duì)于單個(gè)頁(yè)面來(lái)說(shuō),入口的來(lái)源有兩種,一種是已知地址,比如我們?cè)旱木W(wǎng)站的教學(xué)研究人員:教學(xué)研究人員; 另外一種是你可以通過(guò)前面爬下來(lái)的網(wǎng)頁(yè)中獲取入口,比如這個(gè)頁(yè)面上所有老師的個(gè)人主頁(yè)。這一點(diǎn)很重要,后面我們?cè)诎研∨老x逐步變大的時(shí)候還要反復(fù)回到這里。 好的,后面的部分,讓我們通過(guò)解決第二個(gè)問(wèn)題(處理網(wǎng)頁(yè))的過(guò)程,順便看看怎么解決第一個(gè)問(wèn)題(獲取更多入口)。我們一起開(kāi)看看一個(gè)單頁(yè)爬蟲是怎么實(shí)現(xiàn)的。 二、爬蟲實(shí)例:簡(jiǎn)單的單頁(yè)爬蟲 好了,現(xiàn)在我們要處理網(wǎng)頁(yè)了。可是網(wǎng)頁(yè)要怎么處理呢?讓我們回憶一下我們使用瀏覽器的過(guò)程:你先把一個(gè)地址復(fù)制進(jìn)瀏覽器的框框里面,或者點(diǎn)開(kāi)一個(gè)鏈接;然后瀏覽器的進(jìn)度條跑一下(有可能快也有可能慢),然后我們就在瀏覽器里面看到了數(shù)據(jù)。首先,進(jìn)度條跑的過(guò)程完成了一個(gè)對(duì)網(wǎng)頁(yè)的請(qǐng)求,然后瀏覽器把請(qǐng)求下來(lái)的數(shù)據(jù)進(jìn)行處理,然后就輸出出來(lái)。這是一個(gè)極其簡(jiǎn)化但是不太準(zhǔn)確的對(duì)于瀏覽器工作原理的描述。那么爬蟲和瀏覽器有什么不同呢?一般來(lái)說(shuō),我們是只需要解析網(wǎng)頁(yè),而不需要渲染瀏覽器環(huán)境的;另外,我們需要特定網(wǎng)頁(yè)的特點(diǎn)數(shù)據(jù),因此要用一定的方式把數(shù)據(jù)組織并儲(chǔ)存起來(lái)。所以,爬蟲的核心模塊有三個(gè):請(qǐng)求、解析、儲(chǔ)存。 首先我們給一個(gè)入口:教學(xué)研究人員。 這就是我們今天要處理的目標(biāo)網(wǎng)頁(yè)。我們今天要實(shí)現(xiàn)的目的就是把這個(gè)頁(yè)面上所有老師的姓名和個(gè)人主頁(yè)的鏈接(也就是可能的下一次爬蟲的入口)提取出來(lái)。下面開(kāi)始寫爬蟲吧~ 1、請(qǐng)求 這里我們使用的package是requests。這是一個(gè)第三方模塊(具體怎么下載以后再說(shuō)),對(duì)HTTP協(xié)議進(jìn)行了高度封裝,非常好用。所謂HTTP協(xié)議,簡(jiǎn)單地說(shuō)就是一個(gè)請(qǐng)求過(guò)程。我們先不管這玩意是啥,以后再討論。這個(gè)部分,我們要實(shí)現(xiàn)的目的是把網(wǎng)頁(yè)請(qǐng)求(或者說(shuō)下載)下來(lái)。 首先我們導(dǎo)入requests: import requests 下面調(diào)用requests的get函數(shù),把網(wǎng)頁(yè)請(qǐng)求下來(lái): r = requests.get('http://www.wise./people/faculty') 返回的“r”的是一個(gè)包含了整個(gè)HTTP協(xié)議需要的各種各樣的東西的對(duì)象。我們先不管都有啥,先把我們需要的網(wǎng)頁(yè)提取出來(lái): html = r.content 好了,到這一步我們已經(jīng)獲取了網(wǎng)頁(yè)的源代碼。具體源代碼是什么樣的呢?右鍵,點(diǎn)擊“查看源文件”或者“查看源”就可以看到: view-source:http://www.wise./people/faculty 2、解析 當(dāng)然從這一大坨代碼里面找信息太麻煩了。我們可以用瀏覽器提供的另外一個(gè)工具:審查元素。這里我們先不講怎么使用審查元素,先從源代碼里面找。找到的我們需要的信息如下: 這里我們使用bs4來(lái)解析。bs4是一個(gè)非常好的解析網(wǎng)頁(yè)的庫(kù),后面我們會(huì)詳細(xì)介紹。這次的解析先給大家看bs4里面最常用的幾個(gè)BeautifulSoup對(duì)象的方法(method)。我們使用的這幾個(gè)方法,主要是通過(guò)HTML的標(biāo)簽和標(biāo)簽里面的參數(shù)來(lái)定位,然后用特定方法(method)提取數(shù)據(jù)。 首先還是導(dǎo)入package: from bs4 import BeautifulSoup 然后創(chuàng)建一個(gè)BeautifulSoup對(duì)象: soup = BeautifulSoup(html,'html.parser') #html.parser是解析器 下面我們根據(jù)我們看到的網(wǎng)頁(yè)提取。首先提取我復(fù)制的這部分的代碼的第一行,先定位到這部分代碼: div_people_list = soup.find('div', attrs={'class': 'people_list'}) 這里我們使用了BeautifulSoup對(duì)象的find方法。這個(gè)方法的意思是找到帶有‘div’這個(gè)標(biāo)簽并且參數(shù)包含' class = 'people_list' '的HTML代碼。如果有多個(gè)的話,find方法就取第一個(gè)。那么如果有多個(gè)呢?正好我們后面就遇到了,現(xiàn)在我們要取出所有的“a”標(biāo)簽里面的內(nèi)容: a_s = div_people_list.find_all('a', attrs={'target': '_blank'}) 這里我們使用find_all方法取出所有標(biāo)簽為“a”并且參數(shù)包含“ target = ‘_blank‘ ”的代碼,返回一個(gè)列表。“a”標(biāo)簽里面的“href”參數(shù)是我們需要的老師個(gè)人主頁(yè)的信息,而標(biāo)簽里面的文字是老師的姓名。我們繼續(xù): for a in a_s: url = a['href'] name = a.get_text() 這里我們使用BeautifulSoup支持的方法,使用類似于Python字典索引的方式把“a”標(biāo)簽里面“href”參數(shù)的值提取出來(lái),賦值給url(Python實(shí)際上是對(duì)對(duì)象的引用),用get_text()方法把標(biāo)簽里面的文字提起出來(lái)。 事實(shí)上,使用這四個(gè)方法就可以正常地解析大部分HTML了。不過(guò)如果只用這四個(gè)方法,很多程序會(huì)寫的異常原始。所以我們后面再繼續(xù)介紹更多解析方法。 1.儲(chǔ)存 這里我們先弱化一下具體的儲(chǔ)存方法,先輸出到控制臺(tái)上面。我們?cè)趧偛诺拇a的基礎(chǔ)上加一行代碼: for a in a_s: url = a['href'] name = a.get_text() print name,url 使用print關(guān)鍵詞把得到的數(shù)據(jù)print出來(lái)。讓我們看看結(jié)果: 好的,到這里一個(gè)原型就完成了。這就是一個(gè)非常簡(jiǎn)單的爬蟲,總代碼不過(guò)十幾行。復(fù)雜到幾百幾千行的爬蟲,都是在這樣的一個(gè)原型的基礎(chǔ)上不斷深化、不斷完善得到的。 End. |
|