寫在開頭
現(xiàn)在scrapy的安裝教程都明顯過時(shí)了,隨便一搜都是要你安裝一大堆的依賴,什么裝python(如果別人連python都沒裝,為什么要學(xué)scrapy....)wisted, zope interface,pywin32.........現(xiàn)在scrapy的安裝真的很簡單的好不好!
代碼我放github上了,可以參考:
https://github.com/hk029/doubanbook
為什么要用scrapy
我之前講過了requests,也用它做了點(diǎn)東西,(【圖文詳解】python爬蟲實(shí)戰(zhàn)——5分鐘做個(gè)圖片自動(dòng)下載器)感覺它就挺好用的呀,那為什么我還要用scrapy呢?
因?yàn)椋核「?!好!用?/strong>就這么簡單,你只要知道這個(gè)就行了。
我相信所有能找到這篇文章的人多多少少了解了scrapy,我再copy一下它的特點(diǎn)來沒太多意義,因?yàn)槲乙膊粫?huì)在這篇文章內(nèi)深入提。就像你知道系統(tǒng)的sort函數(shù)肯定比你自己編的快排好用就行了,如果需要知道為什么它更好,你可以更深入的去看代碼,但這里,你只要知道這個(gè)爬蟲框架別人就專門做這件事的,肯定好用,你只要會(huì)用就行。
我希望每個(gè)來這里的人,或者每個(gè)在找資料的朋友,都能明確自己的目的,我也盡量將文章的標(biāo)題取的更加的明確。如果這是一篇標(biāo)題為《快速上手》的文章,那你可能就不要太抱希望于能在這篇文章里找到有關(guān)scrapy架構(gòu)和實(shí)現(xiàn)原理類的內(nèi)容。如果是那樣,我可能會(huì)取標(biāo)題為《深入理解scrapy》
好了廢話說了那么多,我們就上手把?
安裝scrapy
一條命令解決所有問題
pip install scrapy
好吧,我承認(rèn)如果用的是windows一條命令可能確實(shí)不夠,因?yàn)檫€要裝pywin32
https://sourceforge.net/projects/pywin32/files/pywin32/
現(xiàn)在sourceforge變的很慢,如果你們不能打開,我在網(wǎng)盤上也放一個(gè)64位的,最新220版本的:
鏈接: http://pan.baidu.com/s/1geUY6Dd 密碼: z2ep
然后就結(jié)束了??!結(jié)束了!!好不好!就這么簡單!
豆瓣讀書9分書榜單爬取
我們考慮下做一個(gè)什么爬蟲呢?簡單點(diǎn),我們做一個(gè)豆瓣讀書9分書:
https://www.douban.com/doulist/1264675/
建立第一個(gè)scrapy工程
把scrapy命令的目錄加入環(huán)境變量,然后輸入一條命令
scrapy startproject doubanbook

然后你的目錄下就有一個(gè)文件夾名為doubanbook目錄,按照提示,我們cd進(jìn)目錄,然后按提示輸入,這里我們爬蟲取名為dbbook,網(wǎng)址就是上面的網(wǎng)址

打開pycharm,新建打開這個(gè)文件夾
關(guān)于pytharm的安裝配置:Pycharm的配置和使用

打開后,我們在最頂層的目錄上新建一個(gè)python文件,取名為main,這是運(yùn)行的主程序(其實(shí)就一行代碼,運(yùn)行爬蟲)

輸入
from scrapy import cmdline
cmdline.execute("scrapy crawl dbbook".split())

然后我們進(jìn)入spider-dbbook,然后把start_urls里面重復(fù)的部分刪除(如果你一開始在命令行輸入網(wǎng)址的時(shí)候,沒輸入http://www.那就不用改動(dòng))然后把a(bǔ)llowed_domains注掉
并且,把parse里面改成
print response.body

好了,到此第一個(gè)爬蟲的框架就搭完了,我們運(yùn)行一下代碼。(注意這里選擇main.py)

運(yùn)行一下,發(fā)現(xiàn)沒打印東西,看看,原來是403

說明爬蟲被屏蔽了,這里要加一個(gè)請(qǐng)求頭部,模擬瀏覽器登錄
在settings.py里加入如下內(nèi)容就可以模擬瀏覽器了
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'

我們再運(yùn)行,發(fā)現(xiàn)網(wǎng)頁內(nèi)容已經(jīng)被爬取下來了

好了,我們的scrapy教程結(jié)束!
如果真這樣結(jié)束,我知道你會(huì)打我。。
編寫xpath提取標(biāo)題名和作者名
這里我們就要得分,標(biāo)題名和作者名
觀察網(wǎng)頁源代碼,用f12,我們可以快速找到,這里不細(xì)講怎么找信息的過程了,具體過程,參考上一個(gè)教程【圖文詳解】python爬蟲實(shí)戰(zhàn)——5分鐘做個(gè)圖片自動(dòng)下載器

根據(jù)先大后小的原則,我們先用bd doulist-subject,把每個(gè)書找到,然后,循環(huán)對(duì)里面的信息進(jìn)行提取

提取書大框架:
'//div[@class="bd doulist-subject"]'
提取題目:
'div[@class="title"]/a/text()'
提取得分:
'div[@class="rating"]/span[@class="rating_nums"]/text()'
提取作者:(這里用正則方便點(diǎn))
'<div class="abstract">(.*?)<br'
編寫代碼
經(jīng)過之前的學(xué)習(xí),應(yīng)該很容易寫出下面的代碼吧:作者那里用正則更方便提取
selector = scrapy.Selector(response)
books = selector.xpath('//div[@class="bd doulist-subject"]')
for each in books:
title = each.xpath('div[@class="title"]/a/text()').extract()[0]
rate = each.xpath('div[@class="rating"]/span[@class="rating_nums"]/text()').extract()[0]
author = re.search('<div class="abstract">(.*?)<br',each.extract(),re.S).group(1)
print '標(biāo)題:' + title
print '評(píng)分:' + rate
print author
print ''
關(guān)鍵這個(gè)代碼在哪里編寫呢?答案就是還記得大明湖……不對(duì),是還記得剛才輸出response的位置嗎?就是那里,那里就是我們要對(duì)數(shù)據(jù)處理的地方。我們寫好代碼,這里注意:
- 不是用etree來提取了,改為scrapy.Selector了,這點(diǎn)改動(dòng)相信難不倒聰明的你
- xpath如果要提取內(nèi)容,需要在后面加上.extract(),略為不適應(yīng),但是習(xí)慣還好。

我們看看結(jié)果,不好看,對(duì)于注重美觀的我們來說,簡直不能忍

加入兩條代碼:
title = title.replace(' ','').replace('\n','')
author = author.replace(' ','').replace('\n','')
再看看結(jié)果,這才是我們想要的嘛

好了,剩下的事情就是如何把結(jié)果寫入文件或數(shù)據(jù)庫了,這里我采用寫入文件,因?yàn)槿绻菍懭霐?shù)據(jù)庫,我又得花時(shí)間講數(shù)據(jù)庫的一些基本知識(shí)和操作,還是放在以后再說吧。
items.py
好了,我們終于要講里面別的.py文件了,關(guān)于這個(gè)items.py,你只要考慮它就是一個(gè)存儲(chǔ)數(shù)據(jù)的容器,可以考慮成一個(gè)結(jié)構(gòu)體,你所有需要提取的信息都在這里面存著。
這里我們需要存儲(chǔ)3個(gè)變量,title,rate,author,所以我在里面加入三個(gè)變量,就這么簡單:
title = scrapy.Field()
rate = scrapy.Field()
author = scrapy.Field()

pipelines.py
一般來說,如果你要操作數(shù)據(jù)庫什么的,需要在這里處理items,這里有個(gè)process_item的函數(shù),你可以把items寫入數(shù)據(jù)庫,但是今天我們用不到數(shù)據(jù)庫,scrapy自帶了一個(gè)很好的功能就是Feed exports,它支持多種格式的自動(dòng)輸出。所以我們直接用這個(gè)就好了,pipelines維持不變
settings.py
Feed 輸出需要2個(gè)環(huán)境變量:
FEED_FORMAT :指示輸出格式,csv/xml/json/
FEED_URI : 指示輸出位置,可以是本地,也可以是FTP服務(wù)器
FEED_URI = u'file:///G://douban.csv'
FEED_FORMAT = 'CSV'
FEED_URI改成自己的就行了

dbbook.py修改
其實(shí)也就加了3條命令,是把數(shù)據(jù)寫入item

當(dāng)然,你要使用item,需要把item類引入
from doubanbook.items import DoubanbookItem
下面的yield可以讓scrapy自動(dòng)去處理item
好拉,再運(yùn)行一下,可以看見G盤出現(xiàn)了一個(gè)douban.csv的文件
用excel打開看一下,怎么是亂碼

沒關(guān)系又是編碼的問題,用可以修改編碼的編輯器比如sublime打開一下,

保存編碼為utf-8包含bom,或者用gvim打開:set fileencoding=gbk

再打開,就正常了

爬取剩下頁面
這還只保存了一個(gè)頁面,那剩下的頁面怎么辦呢?難道要一個(gè)個(gè)復(fù)制網(wǎng)址??當(dāng)然不是,我們重新觀察網(wǎng)頁,可以發(fā)現(xiàn)有個(gè)后頁的鏈接,里面包含著后一頁的網(wǎng)頁鏈接,我們把它提取出來就行了。

因?yàn)橹挥羞@里會(huì)出現(xiàn)<span class = 'next'>標(biāo)簽,所以用xpath輕松提取
'//span[@class="next"]/link/@href'
然后提取后 我們scrapy的爬蟲怎么處理呢?
答案還是yield,
yield scrapy.http.Request(url,callback=self.parse)
這樣爬蟲就會(huì)自動(dòng)執(zhí)行url的命令了,處理方式還是使用我們的parse函數(shù)
改后的代碼這樣:

這里要加一個(gè)判斷,因?yàn)樵谧詈笠豁?,“后一頁”的鏈接就沒了。

好了,我們再運(yùn)行一下(先把之前的csv刪除,不然就直接在后面添加了)可以發(fā)現(xiàn),運(yùn)行的特別快,十幾頁一下就運(yùn)行完了,如果你用requests自己編寫的代碼,可以比較一下,用scrapy快很多,而且是自動(dòng)化程度高很多。

我們打開csv,可以看見,有345篇文章了,和豆瓣上一致。

好了,這個(gè)豆瓣9分圖書的爬蟲結(jié)束了,相信通過這個(gè)例子,scrapy也差不多能上手,至少編寫一般的爬蟲是so easy了!
目前,我們已經(jīng)能對(duì)付大多數(shù)網(wǎng)頁的內(nèi)容了,現(xiàn)在爬本小說啥的應(yīng)該都輕輕松松了,但是為什么我說大多數(shù)呢?因?yàn)榇_實(shí)還有一些網(wǎng)頁我們應(yīng)付不來,就是用Ajax動(dòng)態(tài)加載的網(wǎng)頁,這怎么辦呢?且聽下回分解:
【圖文詳解】scrapy爬蟲與Ajax動(dòng)態(tài)頁面——爬取拉勾網(wǎng)職位信息(1)
代碼我放github上了,可以參考:
https://github.com/hk029/doubanbook