使用Scrapy構(gòu)建一個網(wǎng)絡(luò)爬蟲

記得n年前項目需要一個靈活的爬蟲工具,就組織了一個小團(tuán)隊用Java實現(xiàn)了一個爬蟲框架,可以根據(jù)目標(biāo)網(wǎng)站的結(jié)構(gòu)、地址和需要的內(nèi)容,做簡單的配置開發(fā),即可實現(xiàn)特定網(wǎng)站的爬蟲功能。因為要考慮到各種特殊情形,開發(fā)還耗了不少人力。后來發(fā)現(xiàn)了Python下有這個Scrapy工具,瞬間覺得之前做的事情都白費了。對于一個普通的網(wǎng)絡(luò)爬蟲功能,Scrapy完全勝任,并把很多復(fù)雜的編程都包裝好了。本文會介紹如何Scrapy構(gòu)建一個簡單的網(wǎng)絡(luò)爬蟲。

一個基本的爬蟲工具,它應(yīng)該具備以下幾個功能:

通過HTTP(S)請求,下載網(wǎng)頁信息

解析網(wǎng)頁,抓取需要的內(nèi)容

保存內(nèi)容

從現(xiàn)有頁面中找到有效鏈接,從而繼續(xù)抓取下一個網(wǎng)頁

我們來看下Scrapy怎么做到這些功能的。首先準(zhǔn)備Scrapy環(huán)境,你需要安裝Python(本文使用v2.7)和pip,然后用pip來安裝lxml和scrapy。個人強烈建議使用virtualenv來安裝環(huán)境,這樣不同的項目之間不會沖突。詳細(xì)步驟這里就不贅述了。對于Mac用戶要注意,當(dāng)使用pip安裝lxml時,會出現(xiàn)類似于的下面錯誤:

Error: #include “xml/xmlversion.h” not found

解決這個問題,你需要先安裝Xcode的command line tools,具體的方法是在命令行執(zhí)行下面的命令即可。

1

$xcode-select--install

環(huán)境安裝好之后,我們來用Scrapy實現(xiàn)一個簡單的爬蟲,抓取本博客網(wǎng)站的文章標(biāo)題,地址和摘要。

創(chuàng)建工程

1

$scrapystartprojectmy_crawler

該命令會在當(dāng)前目錄下創(chuàng)建一個名為”my_crawler”的工程,工程的目錄結(jié)構(gòu)如下


8my_crawler

|-my_crawler

||-spiders

|||-__init__.py

||-items.py

||-pipelines.py

||-setting.py

|-scrapy.cfg

設(shè)置待抓取內(nèi)容的字段,本例中就是文章的標(biāo)題,地址和摘要

修改”items.py”文件,在”MyCrawlerItem”類中加上如下代碼:

Python


8# -*- coding: utf-8 -*-

importscrapy

classMyCrawlerItem(scrapy.Item):

title=scrapy.Field()# 文章標(biāo)題

url=scrapy.Field()# 文章地址

summary=scrapy.Field()# 文章摘要

pass

編寫網(wǎng)頁解析代碼

在”my_crawler/spiders”目錄下,創(chuàng)建一個名為”crawl_spider.py”文件(文件名可以任意?。4a如下

Python



31# -*- coding: utf-8 -*-

importscrapy

fromscrapy.linkextractorsimportLinkExtractor

fromscrapy.spidersimportCrawlSpider,Rule

frommy_crawler.itemsimportMyCrawlerItem

classMyCrawlSpider(CrawlSpider):

name='my_crawler'# Spider名,必須唯一,執(zhí)行爬蟲命令時使用

allowed_domains=['bjhee.com']# 限定允許爬的域名,可設(shè)置多個

start_urls=[

# 種子URL,可設(shè)置多個

]

rules=(# 對應(yīng)特定URL,設(shè)置解析函數(shù),可設(shè)置多個

Rule(LinkExtractor(allow=r'/page/[0-9]+'),# 指定允許繼續(xù)爬取的URL格式,支持正則

callback='parse_item',# 用于解析網(wǎng)頁的回調(diào)函數(shù)名

follow=True

),

)

defparse_item(self,response):

# 通過XPath獲取Dom元素

articles=response.xpath('//*[@id="main"]/ul/li')

forarticleinarticles:

item=MyCrawlerItem()

item['title']=article.xpath('h3[@class="entry-title"]/a/text()').extract()[0]

item['url']=article.xpath('h3[@class="entry-title"]/a/@href').extract()[0]

item['summary']=article.xpath('div[2]/p/text()').extract()[0]

yielditem

對于XPath不熟悉的朋友,可以通過Chrome的debug工具獲取元素的XPath。

讓我們測試下爬蟲的效果

在命令行中輸入:

1

$scrapycrawlmy_crawler

注意,這里的”my_crawler”就是你在”crawl_spider.py”文件中起的Spider名。

沒過幾秒鐘,你就會看到要抓取的字段內(nèi)容打印在控制臺上了。就是這么神奇!Scrapy將HTTP(S)請求,內(nèi)容下載,待抓取和已抓取的URL隊列的管理都封裝好了。你的主要工作基本上就是設(shè)置URL規(guī)則及編寫解析的方法。

我們將抓取的內(nèi)容保存為JSON文件:

1

$scrapycrawlmy_crawler-omy_crawler.json-tjson

你可以在當(dāng)前目錄下,找到文件”my_crawler.json”,里面保存的就是我們要抓取的字段信息。(參數(shù)”-t json”可以省去)

將結(jié)果保存到數(shù)據(jù)庫

這里我們采用MongoDB,你需要先安裝Python的MongoDB庫”pymongo”。編輯”my_crawler”目錄下的”pipelines.py”文件,在”MyCrawlerPipeline”類中加上如下代碼:

Python


29# -*- coding: utf-8 -*-

importpymongo

fromscrapy.confimportsettings

fromscrapy.exceptionsimportDropItem

classMyCrawlerPipeline(object):

def__init__(self):

# 設(shè)置MongoDB連接

connection=pymongo.Connection(

settings['MONGO_SERVER'],

settings['MONGO_PORT']

)

db=connection[settings['MONGO_DB']]

self.collection=db[settings['MONGO_COLLECTION']]

# 處理每個被抓取的MyCrawlerItem項

defprocess_item(self,item,spider):

valid=True

fordatainitem:

ifnotdata:# 過濾掉存在空字段的項

valid=False

raiseDropItem("Missing {0}!".format(data))

ifvalid:

# 也可以用self.collection.insert(dict(item)),使用upsert可以防止重復(fù)項

self.collection.update({'url':item['url']},dict(item),upsert=True)

returnitem

再打開”my_crawler”目錄下的”settings.py”文件,在文件末尾加上pipeline的設(shè)置:

Python


11ITEM_PIPELINES={

'my_crawler.pipelines.MyCrawlerPipeline':300,# 設(shè)置Pipeline,可以多個,值為執(zhí)行優(yōu)先級

}

# MongoDB連接信息

MONGO_SERVER='localhost'

MONGO_PORT=27017

MONGO_DB='bjhee'

MONGO_COLLECTION='articles'

DOWNLOAD_DELAY=2# 如果網(wǎng)絡(luò)慢,可以適當(dāng)加些延遲,單位是秒

執(zhí)行爬蟲

1

$scrapycrawlmy_crawler

別忘了啟動MongoDB并創(chuàng)建”bjhee”數(shù)據(jù)庫哦?,F(xiàn)在你可以在MongoDB里查詢到記錄了。

總結(jié)下,使用Scrapy來構(gòu)建一個網(wǎng)絡(luò)爬蟲,你需要做的就是:

“items.py”中定義爬取字段

在”spiders”目錄下創(chuàng)建你的爬蟲,編寫解析函數(shù)和規(guī)則

“pipelines.py”中對爬取后的結(jié)果做處理

“settings.py”設(shè)置必要的參數(shù)

其他的事情,Scrapy都幫你做了。下圖就是Scrapy具體工作的流程。怎么樣?開始寫一個自己的爬蟲吧。


學(xué)好python你需要一個良好的環(huán)境,一個優(yōu)質(zhì)的開發(fā)交流群,群里都是那種相互幫助的人才是可以的,我有建立一個python學(xué)習(xí)交流群,在群里我們相互幫助,相互關(guān)心,相互分享內(nèi)容,這樣出問題幫助你的人就比較多,群號是301,還有056,最后是051,這樣就可以找到大神聚合的群,如果你只愿意別人幫助你,不愿意分享或者幫助別人,那就請不要加了,你把你會的告訴別人這是一種分享。如果你看了覺得還可以的麻煩給我點個贊謝謝

。

學(xué)習(xí)是對自己最好的投資,而機會屬于有準(zhǔn)備的人,這是一個看臉的時代,但最終拼的是實力。人和人之間的差距不在于智商,而在于如何利用業(yè)余時間,所以沒有等出來的輝煌,只有干出來的精彩。其實只要你想學(xué)習(xí),什么時候開始都不晚,不要擔(dān)心這擔(dān)心那,你只需努力,剩下的交給時間,而你之所以還沒有變強,只因你還不夠努力,要記得付出不亞于任何人的努力。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容