標籤:隨筆 imp 觀察 start 超級 from 標題 輸入 攻擊
啟動爬蟲
在上一節中,我們已經建立好了我們的scrapy項目,看著這一大堆檔案,想必很多人都會一臉懵逼,我們應該怎麼啟動這個爬蟲呢?
既然我們採用cmd命令建立了scrapy爬蟲,那就得有始有終有逼格,我們仍然採用程式員的正統方式——cmd的方式運行它
scrapy crawl jobbole
當我們在cmd中輸入這條命令後,我們的爬蟲也就開始運行了。但是如果每次都需要這樣才能啟動,不僅費時費力,也難以在IDE中偵錯工具。面對這種情況,我們可以採取使用python來實現自動命令列的啟動。好吧,真香!
於是我們在我們的項目中建立一個main.py檔案
編寫以下代碼
# Author :Albert Shen# -*- coding: utf-8 -*-from scrapy.cmdline import executeimport sysimport osif __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參數來進行。
如果大家嘗試一些其他網頁,可能會出現獲得的網頁與我們想要的網頁不同的情況,這多是因為目標網頁需要登入驗證或採取了反爬蟲策略,這一部分我們將在後續的文章中涉及。
xpath
既然我們已經獲得了網頁的原始碼,那麼我們應該怎麼解析資料呢?可能細心的讀者會注意到response.text的值是一個字串,那麼採用Regex不失為一種可靠的方式。但是作為一個成熟的爬蟲架構,scrapy為我們提供了一種更加簡便準確的方式——xpath。將我們的jobbole.py檔案修改為這樣
# -*- coding: utf-8 -*-import scrapyclass 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的所有文章,解析資料,下載封面圖等。同時我們將使用到Regex以分析字串來獲得我們想要的資料,由於篇幅限制,筆者將不會對Regex進行詳細介紹,建議大家提前瞭解一些Regex的基本知識。
python爬蟲隨筆(2)—啟動爬蟲與xpath