本文截圖及運行環境均在MAC OS X 10.9.5上實現,但基本步驟與win 7環境上相同(其實我是先在win7折騰了一把,而後爲了寫這篇教程,又在OS X 上面從新搞了一遍)html
scrapy版本爲1.0數據庫
參考文獻以及下載連接:json
本爬蟲參考代碼打包下載數據結構
經過上一篇內容咱們已經將scrapy環境配置完畢,下面咱們來實現一個demo來爬取南京郵電大學新聞頁面的內容。框架
scrapy startproject njupt #其中njupt是項目名稱,能夠按照我的喜愛來定義
輸入以上命令以後,就會看見命令行運行的目錄下多了一個名爲njupt
的目錄,目錄的結構以下:dom
|---- njupt | |---- njupt | |---- __init__.py | |---- items.py #用來存儲爬下來的數據結構(字典形式) | |---- pipelines.py #用來對爬出來的item進行後續處理,如存入數據庫等 | |---- settings.py #爬蟲配置文件 | |---- spiders #此目錄用來存放建立的新爬蟲文件(爬蟲主體) | |---- __init__.py | |---- scrapy.cfg #項目配置文件
至此,工程建立完畢。scrapy
本文以抓取南郵新聞爲例,須要存儲三種信息:ide
南郵新聞標題函數
南郵新聞時間post
南郵新聞的詳細連接
items內部代碼以下:
# -*- coding: utf-8 -*- import scrapy class NjuptItem(scrapy.Item): #NjuptItem 爲自動生成的類名 news_title = scrapy.Field() #南郵新聞標題 news_date = scrapy.Field() #南郵新聞時間 news_url = scrapy.Field() #南郵新聞的詳細連接
至於爲何每一句都用scrapy.Field()
,這個等請關注個人後續教程,如今只要記住按照以上的格式來添加新的要提取的屬性就能夠了~。
spider是爬蟲的主體,負責處理requset response 以及url等內容,處理完以後交給pipelines進行進一步處理。
設置完items以後,就在spiders目錄下新建一個njuptSpider.py
文件,內容以下:
# -*- coding: utf-8 -*- import scrapy from njupt.items import NjuptItem import logging class njuptSpider(scrapy.Spider): name = "njupt" allowed_domains = ["njupt.edu.cn"] start_urls = [ "http://news.njupt.edu.cn/s/222/t/1100/p/1/c/6866/i/1/list.htm", ] def parse(self, response): news_page_num = 14 page_num = 386 if response.status == 200: for i in range(2,page_num+1): for j in range(1,news_page_num+1): item = NjuptItem() item['news_url'],item['news_title'],item['news_date'] = response.xpath( "//div[@id='newslist']/table[1]/tr["+str(j)+"]//a/font/text()" "|//div[@id='newslist']/table[1]/tr["+str(j)+"]//td[@class='postTime']/text()" "|//div[@id='newslist']/table[1]/tr["+str(j)+"]//a/@href").extract() yield item next_page_url = "http://news.njupt.edu.cn/s/222/t/1100/p/1/c/6866/i/"+str(i)+"/list.htm" yield scrapy.Request(next_page_url,callback=self.parse_news) def parse_news(self, response): news_page_num = 14 if response.status == 200: for j in range(1,news_page_num+1): item = NjuptItem() item['news_url'],item['news_title'],item['news_date'] = response.xpath( "//div[@id='newslist']/table[1]/tr["+str(j)+"]//a/font/text()" "|//div[@id='newslist']/table[1]/tr["+str(j)+"]//td[@class='postTime']/text()" "|//div[@id='newslist']/table[1]/tr["+str(j)+"]//a/@href").extract() yield item
其中
name
爲爬蟲名稱,在後面啓動爬蟲的命令當中會用到。
allowed_domains
爲容許爬蟲爬取的域名範圍(若是鏈接到範圍之外的就不爬取)
start_urls
代表爬蟲首次啓動以後訪問的第一個Url,其結果會被自動返回給parse
函數。4.
parse
函數爲scrapy框架中定義的置函數,用來處理請求start_urls
以後返回的response
,由咱們實現
news_page_num = 14
和page_num = 386
別表示每頁的新聞數目,和一共有多少頁,原本也能夠經過xpath爬取下來的,可是我實在是對咱們學校的網站製做無語了,html各類混合,因而我就偷懶手動輸入了。
以後經過item = NjuptItem()
來使用咱們以前定義的item,用來存儲新聞的url、標題、日期。(這裏面有一個小技巧就是經過|
來接連xpath能夠一次返回多個想要抓取的xpath)
經過yield item
來將存儲下來的item
交由後續的pipelines
處理
以後經過生成next_page_url
來經過scrapy.Request
抓取下一頁的新聞信息
scrapy.Request
的兩個參數,一個是請求的URL另一個是回調函數用於處理這個request
的response
,這裏咱們的回調函數是parse_news
parse_news
裏面的步驟和parse
差很少,固然你也能夠改造一下parse
而後直接將其當作回調函數,這樣的話一個函數就ok了
初次編寫能夠直接編輯njupt
目錄下的pipelines.py
文件。pipelines主要用於數據的進一步處理,好比類型轉換、存儲入數據庫、寫到本地等。
本爬蟲pipelines以下:
import json class NjuptPipeline(object): def __init__(self): self.file = open('njupt.txt',mode='wb') def process_item(self, item, spider): self.file.write(item['news_title'].encode("GBK")) self.file.write("\n") self.file.write(item['news_date'].encode("GBK")) self.file.write("\n") self.file.write(item['news_url'].encode("GBK")) self.file.write("\n") return item
其實pipelines
是在每次spider
中yield item
以後調用,用於處理每個單獨的item
。上面代碼就是實現了在本地新建一個njupt.txt
文件用於存儲爬取下來的內容。
settings.py
文件用於存儲爬蟲的配置,有不少種配置,因爲是入門教程,不須要配置不少,咱們這裏就添加一下剛纔編寫的pipelines就好了。文件內容以下。
BOT_NAME = 'njupt' SPIDER_MODULES = ['njupt.spiders'] NEWSPIDER_MODULE = 'njupt.spiders' ITEM_PIPELINES = { 'njupt.pipelines.NjuptPipeline':1, }
以上步驟所有完成以後,咱們就啓動命令行,而後切換運行目錄到njupt
的spider
目錄下,經過如下命令啓動爬蟲
scrapy crawl njupt
通過一段時間的風狂爬取,爬蟲結束。會報一些統計信息
最後讓咱們來查看一下爬取成果
至此,大功告成~