構(gòu)建自己的數(shù)據(jù)王國(guó)
- 新建項(xiàng)目
- 明確目標(biāo)
- 制作爬蟲(chóng)
- 保存數(shù)據(jù)
一、新建項(xiàng)目(scrapy startproject)
- 在爬取前,必須創(chuàng)建一個(gè)新的scrapy項(xiàng)目,進(jìn)入自定義的項(xiàng)目目錄中,運(yùn)行下列命令:
scrapy startproject myspider
- 其中,myspider為項(xiàng)目名稱(chēng),可以看到將會(huì)創(chuàng)建一個(gè)myspider文件夾,目錄結(jié)構(gòu)大致如下:

這些文件的主要作用列舉如下:
- scrapy.cfg:項(xiàng)目的配置文件
- myspider/:項(xiàng)目的python模塊,將會(huì)從這里引用代碼
- myspider/items.py:項(xiàng)目的目標(biāo)文件
- myspider/pipelines.py:項(xiàng)目的管道文件
- myspider/settings.py:項(xiàng)目的設(shè)置文件
- myspider/spiders/:存儲(chǔ)爬蟲(chóng)代碼目錄
二、 明確目標(biāo)(myspider/items.py)
準(zhǔn)備抓取網(wǎng)站http://www./channel/teacher.shtml網(wǎng)站里的所有講師的姓名、職稱(chēng)和個(gè)人信息。
- Item用來(lái)定義結(jié)構(gòu)化數(shù)據(jù)字段,用以保存爬取到的數(shù)據(jù),有點(diǎn)像python中的dict,但是提供了一些額外的保護(hù)減少錯(cuò)誤。
- 可以在myspider/items.py中創(chuàng)建一個(gè)Item類(lèi),并且通過(guò)在Item類(lèi)中繼續(xù)定義多個(gè)Field類(lèi)(該類(lèi)是繼承了dict)來(lái)完善該Item類(lèi)
- 接下來(lái),創(chuàng)建一個(gè)ItcastItem類(lèi),和構(gòu)建item模型(model)。
import scrapy
class ItcastItem(scrapy.Item):
name = scrapy.Field()
level = scrapy.Field()
info = scrapy.Field()
三、 制作爬蟲(chóng)(spiders/itcastspider.py)
爬蟲(chóng)功能要分兩步:
1、爬數(shù)據(jù)
- 在當(dāng)前目錄下輸入命令,將在myspider/spiders目錄下創(chuàng)建一個(gè)名為itcast的爬蟲(chóng),并指定爬取域的范圍:
scrapy genspider itcast ""
- 打開(kāi)myspider/spiders目錄里的itcast.py,默認(rèn)增加了下列代碼:
import scrapy
class ItcastSpider(scrapy.Spider):
name = 'itcast'
allowed_domains = ['']
start_urls = ['http://www./channel/teacher.shtml']
def parse(self, response):
pass
其實(shí)也可以由我們自行創(chuàng)建itcast.py并編寫(xiě)上面的代碼,只不過(guò)使用命令可以免去編寫(xiě)固定代碼的麻煩。
要建立一個(gè)spider,你必須用scrapy.spider類(lèi)創(chuàng)建一個(gè)子類(lèi),并確定了三個(gè)強(qiáng)制的屬性和一個(gè)方法。
- name = ‘itcast’:這個(gè)爬蟲(chóng)的識(shí)別名稱(chēng),必須是唯一的,在不同的爬蟲(chóng)必須定義不同的名字
- allow_domains=[]:是搜索的域名范圍,也就是爬蟲(chóng)的約束區(qū)域,規(guī)定爬蟲(chóng)只爬取這個(gè)域名下的網(wǎng)頁(yè),不存在的URL會(huì)被忽略
- start_urls=[]:爬取的URL元祖/列表,爬蟲(chóng)從這里開(kāi)始抓取數(shù)據(jù),所以,第一次下載的數(shù)據(jù)將會(huì)從這些urls開(kāi)始,其他子URL將會(huì)從這些起始URL中繼承性生成。
- parse(self,response):解析的方法,每個(gè)初識(shí)URL完成下載后將被調(diào)用,調(diào)用的時(shí)候傳入從每一個(gè)URL傳回的Response對(duì)象來(lái)作為唯一參數(shù)主要作用如下:
- 負(fù)責(zé)解析返回的網(wǎng)頁(yè)數(shù)據(jù)(reponse.body),提取結(jié)構(gòu)化數(shù)據(jù)(生成item)
- 生成需要下一頁(yè)的URL請(qǐng)求
- 將start_urls的值修改為需要爬取的第一個(gè)url
start_urls=['http://www./channel/teacher.shtml']
def parse(self, response):
filename="teacher.html"
with open(filename,'wb') as f:
f.write(response.body)
- 然后在myspider/myspider目錄下執(zhí)行
scrapy crawl itcast
- 運(yùn)行后,打印的日志出現(xiàn)[scrapy.core.engine] INFO: Spider closed (finished),代表執(zhí)行完成。
2、取數(shù)據(jù)
- 爬取整個(gè)網(wǎng)頁(yè)源碼完畢,接下來(lái)是提取過(guò)程,首先觀察頁(yè)面源碼:

<div class="li_txt">
<h3> xxx </h3>
<h4> xxxxx </h4>
<p> xxxxxxx </p>
- 之前在myspider/items.py里定義了一個(gè)MyspiderItem類(lèi),這里引入進(jìn)來(lái)
from myspider.items import MyspiderItem
- 然后將我們得到的數(shù)據(jù)封裝到一個(gè)MyspiderItem對(duì)象中,可以保存每個(gè)老師的屬性:
def parse(self, response):
# filename="teacher.html"
# with open(filename,'wb') as f:
# f.write(response.body)
items=[]
for each in response.xpath("http://div[@class='li_txt']"):
item=MyspiderItem()
name=each.xpath("h3/text()").extract()[0]
level=each.xpath("h4/text()").extract()[0]
info=each.xpath("p/text()").extract()[0]
item['name']=name
item['level']=level
item['info']=info
items.append(item)
return items
四、 保存數(shù)據(jù)
我們暫時(shí)先不處理管道。
scrapy保存信息的最簡(jiǎn)單的方法主要有四中,-o輸出指定格式的文件,命令如下:
#json格式,默認(rèn)為unicode編碼
scrapy crawl itcast -o teachers.json
scrapy crawl itcast -o teachers.jsonl
scrapy crawl itcast -o teachers.csv
scrapy crawl itcast -o teachers.xml
|