天天看點

pyspider爬蟲教程(1):HTML和CSS選擇

雖然以前寫過 如何抓取web頁面 和 如何從 web 頁面中提取資訊。但是感覺還是需要一篇 step by step

的教程,不然沒有一個總體的認識。不過,沒想到這個教程居然會變成一篇譯文,在這個爬蟲教程系列文章中,會以實際的例子,由淺入深讨論爬取(抓取和解析)的一些關鍵問題。

在 教程一 中,我們将要爬取的網站是豆瓣電影:http://movie.douban.com/

你可以在: http://demo.pyspider.org/debug/tutorial_douban_movie 獲得完整的代碼,和進行測試。

開始之前

由于教程是基于 pyspider 的,你可以安裝一個 pyspider(quickstart,也可以直接使用 pyspider 的 demo 環境: http://demo.pyspider.org/。

你還應該至少對網際網路是什麼有一個簡單的認識:

網際網路是一個由許多互相連結的超文本頁面(以下簡稱網頁)組成的系統。

網頁使用網址(url)定位,并連結彼此

網頁使用 http 協定傳輸

網頁使用 html 描述外觀和語義

是以,爬網頁實際上就是:

找到包含我們需要的資訊的網址(url)清單

通過 http 協定把頁面下載下傳回來

從頁面的 html 中解析出需要的資訊

找到更多這個的 url,回到 2 繼續

選取一個開始網址

既然我們要爬所有的電影,首先我們需要抓一個電影清單,一個好的清單應該:

包含足夠多的電影的 url

通過翻頁,可以周遊到所有的電影

一個按照更新時間排序的清單,可以更快抓到最新更新的電影

我們在 http://movie.douban.com/ 掃了一遍,發現并沒有一個清單能包含所有電影,隻能退而求其次,通過抓取分類下的所有的标簽清單頁,來周遊所有的電影: http://movie.douban.com/tag/

建立一個項目

在 pyspider 的 dashboard 的右下角,點選 “create” 按鈕

pyspider爬蟲教程(1):HTML和CSS選擇

替換 on_start 函數的 self.crawl 的 url:

@every(minutes=24 * 60) 

def on_start(self): 

    self.crawl('http://movie.douban.com/tag/', callback=self.index_page)  

self.crawl 告訴 pyspider 抓取指定頁面,然後使用 callback 函數對結果進行解析。

@every 修飾器,表示 on_start 每天會執行一次,這樣就能抓到最新的電影了。

點選綠色的 run 執行,你會看到 follows 上面有一個紅色的 1,切換到 follows 面闆,點選綠色的播放按鈕:

pyspider爬蟲教程(1):HTML和CSS選擇

tag 清單頁

在 tag 清單頁 中,我們需要提取出所有的 電影清單頁 的 url。你可能已經發現了,sample handler 已經提取了非常多大的 url,所有,一種可行的提取清單頁 url 的方法就是用正則從中過濾出來:

import re 

... 

    @config(age=10 * 24 * 60 * 60) 

    def index_page(self, response): 

        for each in response.doc('a[href^="http"]').items(): 

            if re.match("http://movie.douban.com/tag/\w+", each.attr.href, re.u): 

                self.crawl(each.attr.href, callback=self.list_page)  

由于 電影清單頁和 tag清單頁長的并不一樣,在這裡建立了一個 callback 為 self.list_page

@config(age=10 * 24 * 60 * 60) 在這表示我們認為 10 天内頁面有效,不會再次進行更新抓取

由于 pyspider 是純 python 環境,你可以使用 python 強大的内置庫,或者你熟悉的第三方庫對頁面進行解析。不過更推薦使用 css選擇器。

電影清單頁

再次點選 run 讓我們進入一個電影清單頁(list_page)。在這個頁面中我們需要提取:

電影的連結,例如,http://movie.douban.com/subject/1292052/

下一頁的連結,用來翻頁

css選擇器

css選擇器,顧名思義,是 css 用來定位需要設定樣式的元素 所使用的表達式。既然前端程式員都使用 css選擇器 為頁面上的不同元素設定樣式,我們也可以通過它定位需要的元素。你可以在 css 選擇器參考手冊 這裡學習更多的 css選擇器 文法。

在 pyspider 中,内置了 response.doc 的 pyquery 對象,讓你可以使用類似 jquery 的文法操作 dom 元素。你可以在 pyquery 的頁面上找到完整的文檔。

css selector helper

在 pyspider 中,還内置了一個 css selector helper,當你點選頁面上的元素的時候,可以幫你生成它的 css選擇器 表達式。你可以點選 enable css selector helper 按鈕,然後切換到 web 頁面:

pyspider爬蟲教程(1):HTML和CSS選擇

開啟後,滑鼠放在元素上,會被黃色高亮,點選後,所有擁有相同 css選擇器 表達式的元素會被高亮。表達式會被插入到 python 代碼目前光标位置。建立下面的代碼,将光标停留在單引号中間:

def list_page(self, response): 

    for each in response.doc('').items():  

點選一個電影的連結,css選擇器 表達式将會插入到你的代碼中,如此重複,插入翻頁的連結:

    for each in response.doc('html>body>div#wrapper>div#content>div.grid-16-8.clearfix>div.article>div>table tr.item>td>div.pl2>a').items(): 

        self.crawl(each.attr.href, callback=self.detail_page) 

    # 翻頁 

    for each in response.doc('html>body>div#wrapper>div#content>div.grid-16-8.clearfix>div.article>div.paginator>a').items(): 

        self.crawl(each.attr.href, callback=self.list_page)  

翻頁是一個到自己的 callback 回調

電影詳情頁

再次點選 run,follow 到詳情頁。使用 css selector helper 分别添加電影标題,打分和導演:

def detail_page(self, response): 

    return { 

        "url": response.url, 

        "title": response.doc('html>body>div#wrapper>div#content>h1>span').text(), 

        "rating": response.doc('html>body>div#wrapper>div#content>div.grid-16-8.clearfix>div.article>div.indent.clearfix>div.subjectwrap.clearfix>div#interest_sectl>div.rating_wrap.clearbox>p.rating_self.clearfix>strong.ll.rating_num').text(), 

        "導演": [x.text() for x in response.doc('a[rel="v:directedby"]').items()], 

    } 

注意,你會發現 css selector helper 并不是總是能提取到合适的 css選擇器 表達式。你可以在 chrome dev tools 的幫助下,寫一個合适的表達式:

pyspider爬蟲教程(1):HTML和CSS選擇

右鍵點選需要提取的元素,點選審查元素。你并不需要像自動生成的表達式那樣寫出所有的祖先節點,隻要寫出那些能區分你不需要的元素的關鍵節點的屬性就可以了。不過這需要抓取和網頁前端的經驗。是以,學習抓取的最好方法就是學會這個頁面/網站是怎麼寫的。

你也可以在 chrome dev tools 的 javascript console 中,使用 $$(a[rel="v:directedby"]) 測試 css selector。

開始抓取

使用 run 單步調試你的代碼,對于用一個 callback 最好使用多個頁面類型進行測試。然後儲存。

回到 dashboard,找到你的項目

将 status 修改為 debug 或 running

按 run 按鈕 

pyspider爬蟲教程(1):HTML和CSS選擇

作者:佚名

來源:51cto

繼續閱讀