Scrapy 是一個基于 Python 的網絡爬蟲,可以用來從網站提取資訊。它快速簡單,可以像浏覽器一樣浏覽頁面。
但是,請注意,它不适合使用JavaScript來操縱使用者界面的網站和應用程式。 Scrapy隻加載HTML。它沒有任何設施能夠執行網站可以使用來定制使用者體驗JavaScript。
安裝
我們使用Virtualenv來安裝scrapy。這使我們能夠安裝scrapy而不影響其他系統安裝的子產品。
現在建立一個工作目錄并在該目錄中初始化一個虛拟環境。
現在安裝Scrapy
檢查它正在工作。以下代碼顯示将scrapy的版本顯示為1.4.0。
編寫一個Spider
Scrapy的工作原理是加載一個叫做spider的Python子產品,它是一個從scrapy.Spider繼承而來的類。
讓我們來寫一個簡單的spider類來加載Reddit的頂部文章。
首先,建立一個名為redditspider.py的檔案,并添加以下内容。這是一個完整的spider類,盡管對我們沒有任何幫助。一個spider類至少要求如下:
一個name來識别這個spider類
一個start_urls清單變量,包含從哪個URL開始爬行。
一個parse()方法,它可以是無操作的,如圖所示
這個類現在可以執行如下:
關閉日志記錄
正如你所看到的,這個Spider運作并列印一大堆消息,這對調試很有用。但是,由于它掩蓋了out程式的輸出,現在讓我們關閉它。
将這幾行添加到檔案的開頭:
現在,當我們運作Spider,我們不應該看到令人的混淆資訊。
解析響應
現在我們來分析一下scraper的反應。這是在parse()方法中完成的。在此方法中,我們使用response.css()方法在HTML上執行CSS樣式選擇并提取所需的元素。
為了确定要提取的CSS選擇,我們使用Chrome的DOM Inspector工具來選取元素。在reddit的首頁,我們看到每個文章都被包裝在<div class =“thing”> ... </ div>中。
是以,我們從頁面中選擇所有的div.thing,并使用它進一步工作。
我們還在Spider類中實作了下面的輔助方法來提取所需的文本。
以下方法從元素中提取所有文本為清單,用空格連接配接元素,并從結果中去除前導和後面的空白。
這個方法從第一個元素中提取文本并傳回。
提取所需的元素
一旦這些輔助方法到位,讓我們從每個Reddit文章中提取标題。在div.thing内,标題在div.entry> p.title> a.title :: text裡是能被利用的。如前所述,可以從任何浏覽器的DOM Inspector中确定所需元素的CSS選擇。
結果使用python的yield語句傳回給調用者。 yield的工作方式如下 - 執行一個包含yield語句的函數将傳回一個生成器給調用者。調用者重複執行該生成器,并接收執行結果直到生成器終止。
在我們的例子中,parse()方法在每個調用中傳回一個字典對象,其中包含一個鍵(标題)給調用者,傳回直到div.thing清單結束。
運作Spider并收集輸出。
現在讓我們再次運作Spider。顯示了豐富輸出的一部分(在重新設定日志語句之後)。
很難看到真正的産出。讓我們将輸出重定向到一個檔案(posts.json)
這裡是posts.json的一部分
提取所有必需的資訊
我們還要提取每個文章的subreddit名稱和投票數。為此,我們隻更新yield語句傳回的結果。
生成的posts.json:
總結
本文提供了如何從使用Scrapy的網站中提取資訊的基本視圖。要使用scrapy,我們需要編寫一個Spider子產品,來訓示scrapy抓取一個網站并從中提取結構化的資訊。這些資訊可以以JSON格式傳回,供下遊軟體使用。