在上一節中,咱們已經建立好了咱們的scrapy項目,看着這一大堆文件,想必不少人都會一臉懵逼,咱們應該怎麼啓動這個爬蟲呢?html
既然咱們採用cmd命令建立了scrapy爬蟲,那就得善始善終有逼格,咱們仍然採用程序員的正統方式——cmd的方式運行它前端
scrapy crawl jobbole
當咱們在cmd中輸入這條命令後,咱們的爬蟲也就開始運行了。可是若是每次都須要這樣才能啓動,不只費時費力,也難以在IDE中調試程序。面對這種狀況,咱們能夠採起使用python來實現自動命令行的啓動。好吧,真香!java
因而咱們在咱們的項目中建立一個main.py文件python
編寫如下代碼程序員
# Author :Albert Shen # -*- coding: utf-8 -*- from scrapy.cmdline import execute import sys import os if __name__ == '__main__': sys.path.append(os.path.dirname(os.path.abspath(__file__))) execute(["scrapy", "crawl", "jobbole"])
運行main.py,咱們就會發現,scrapy成功開始運行,並將運行結果輸出到了console窗口,此時咱們也就能夠充分利用IDE的優點,進行便捷的調試與運行。正則表達式
既然咱們的爬蟲已經能夠運行了,那麼應該如何編寫邏輯才能爬取到咱們想要的數據呢?編程
首先咱們打一個斷點後端
此時你們注意response對象的text變量,看起來是否很像網頁的html代碼。爲了確認這個猜想是否正確,咱們能夠將text變量的值複製出來,拷貝到一個html文件中,打開發現確實是目標網頁的html源代碼。瀏覽器
這是由於當程序開始運行,scrapy獲取網頁數據後,調用了此文件中的parse函數,同時將獲取到的數據傳遞給了resposne參數。這正是scrapy框架的強大之處,將前面一系列與目標網頁相關的操做進行了封裝,咱們只須要關心怎麼從網頁源代碼中得到想要的信息便可,因此咱們後續的操做將主要圍繞這response參數來進行。app
若是你們嘗試一些其餘網頁,可能會出現得到的網頁與咱們想要的網頁不一樣的狀況,這可能是由於目標網頁須要登陸驗證或採起了反爬蟲策略,這一部分咱們將在後續的文章中涉及。
既然咱們已經得到了網頁的源代碼,那麼咱們應該怎麼解析數據呢?可能細心的讀者會注意到response.text的值是一個字符串,那麼採用正則表達式不失爲一種可靠的方式。可是做爲一個成熟的爬蟲框架,scrapy爲咱們提供了一種更加簡便準確的方式——xpath。將咱們的jobbole.py文件修改成這樣
# -*- coding: utf-8 -*- import scrapy class JobboleSpider(scrapy.Spider): name = 'jobbole' allowed_domains = ['blog.jobbole.com'] start_urls = ['http://blog.jobbole.com/all-posts/'] def parse(self, response): articles = response.xpath('//a[@class="archive-title"]/text()').extract() print(articles) pass
運行程序,打斷點調試,咱們發現,articles變量是一個list,包含20個字符串,正好就是目標網頁的20篇文章的標題。經過一行即能實現精確的目標數據提取,正是依靠xpath。
在學習xpath以前,讀者最好能對前端,尤爲是HTML語言有必定了解,至少須要知道一些基本的概念。
HTML語言是一種超級文本標記語言,與後端的C,java,python等不一樣,HTML不是編程語言,而是標記語言,是經過一系列標籤來描述網頁。若是對此沒有概念的讀者能夠簡單的將其理解爲HTML語言是經過一句句話告訴瀏覽器,首先我在這要放一段文字,而後要在這那一張圖片等等,相似於畫圖。
HTML標記標籤一般被稱爲HTML標籤。是由尖括號<>包圍的關鍵字,如<html>,<h1></h1>等。標籤之間的部分被稱爲元素,同時每一個標籤也有屬性,例如
<a href="http://www.w3school.com.cn">This is a link</a>
其中<a></a>標籤表示這是一個連接,This is a link 是顯示給閱讀者的字符,href是它的一個屬性,表示目標網址是http://www.w3school.com.cn。真實的顯示效果以下圖所示
點擊它就能跳轉到目標網頁。
若是想要深刻的瞭解HTML的知識,能夠在w3school上進行學習:http://www.w3school.com.cn/
xpath正是基於此的。經常使用的xpath語法以下圖所示(來源:w3school)
w3school關於xpath的教程:http://www.w3school.com.cn/xpath/index.asp
舉一些例子
你們若是想要深刻了解xpath,也建議到w3school進行進一步學習。若是對前端實在不熟悉的讀者,也能夠跟着筆者這個系列的教程,相信通過一段時間的練習,也可以熟練掌握相關知識。
有了上面的知識,咱們來分析一下咱們是怎麼獲得目標網頁的全部標題的呢?
在瀏覽器中打開目標網頁http://blog.jobbole.com/all-posts/,按f12(Chrome瀏覽器)打開開發者工具
1.咱們能夠在想要查看的元素處右擊,選擇「檢查」
2.在開發者攻擊中點擊2位置的圖標,而後點擊咱們想要查看的元素
Chrome就會自動跳轉到目標元素的源代碼處。
<a class="archive-title" target="_blank" href="http://blog.jobbole.com/114331/" title="受 SQLite 多年青睞,C 語言到底好在哪兒?">受 SQLite 多年青睞,C 語言到底好在哪兒?</a>
目標元素幾個比較重要的信息爲
1.這是一個<a></a> (連接)
2.目標元素包含多個屬性,其中一個屬性爲class,值爲archive-title,一個屬性爲href,值爲點擊這個標題將會跳轉的目標網頁的網址
3.包含一個屬性爲title,其值與標籤之間的「元素」值相同。
articles = response.xpath('//a[@class="archive-title"]/text()').extract()
咱們上述代碼中的 //a[@class="archive-title"] 表示取整個文檔中全部( // 表示整個文檔中的全部節點)包含class屬性(中括號[]表示對前面標籤的限制,如包含什麼屬性),且屬性值爲「archive-title」的a節點(標籤)。
咱們能夠搜索網頁的全部代碼,就會發現全部包含 archive-title 字符串的只有20處,正好是本頁全部文章的標題<a></a> 標籤的class屬性值,也就是說咱們僅憑這一句話就精確地選到了咱們想要的數據。
/text()表示咱們想要得到這些標籤的「元素」值(即標籤之間的內容,也就是會在網頁上顯示出來的內容),若是想要得到標籤的某個屬性值,如href,則可使用以下語句
response.xpath('//a[@class="archive-title"]/@href').extract()
由於咱們取的是屬性,因此必定不要忘了@來表示屬性,若是沒有a,則會認爲是目標a標籤下的href標籤,顯然是錯誤的。
extract()表示得到 提取出來的數據的data變量,即咱們指定的標籤中的內容。若是以爲這一句難以理解,讀者也能夠將程序中的.extract()刪除,觀察結果。
彩蛋:在開發者工具中,右擊源代碼,咱們能夠選擇複製目標標籤的xpath。同理,因爲動態網頁等緣由,這種方式得到的xpath可能與scrapy得到的網頁不匹配。這種方式能夠幫助你們更深刻的理解xpath,但在後續的編程過程當中,筆者仍是建議你們本身進行分析。
As Albert says: 既然寫程序是爲了偷懶,那寫程序的時候就不要偷懶了。
在這一節中,咱們瞭解瞭如何快捷地啓動scrapy,xpath基本語法,並嘗試進行了scrapy爬蟲的初次嘗試。在後面的章節中,咱們將會對整篇網頁進行解析,並採用深度優先搜索遍歷jobbole的全部文章,解析數據,下載封面圖等。同時咱們將使用到正則表達式以分析字符串來得到咱們想要的數據,因爲篇幅限制,筆者將不會對正則表達式進行詳細介紹,建議你們提早了解一些正則表達式的基本知識。