前言
最近我體驗(yàn)了一次全棧(偽)開發(fā)App的經(jīng)歷,獲益良多,我想把過程記錄一下,一是回顧與鞏固,二是拋磚引玉,如有謬誤以求大神指點(diǎn)。
首先,我們需要明確我們最終的目標(biāo)是什么。
比如現(xiàn)在我要做一個(gè)簡單的游戲評(píng)測資訊的App。
那么我首先需要【數(shù)據(jù)來源】然后需要一個(gè)提供數(shù)據(jù)接口的【服務(wù)端】,我將先完成這二者,然后才開始App的開發(fā)。
因此我將分為三步[Python爬蟲]->[Ruby服務(wù)端]->[iOS客戶端]來完成這個(gè)App。
而爬蟲技術(shù),將作為先遣部隊(duì),為我們攻下第一個(gè)數(shù)據(jù)堡壘。
開始
許多語言都有成熟的爬蟲框架,我選擇的是使用Python語言的Scrapy框架,這是一個(gè)非常完善而且功能強(qiáng)大的爬蟲框架,我們只需要用到最基礎(chǔ)的功能。Scrapy擁有非常棒的中文文檔 安裝和入門教程文檔一應(yīng)俱全,我就不贅述了。
安裝好之后,我們打開終端,開始創(chuàng)建令人激動(dòng)的爬蟲
scrapy startproject yxReview
cd yxReview
scrapy genspider yx_review www.ali213.net/news/pingce
完成后結(jié)構(gòu)大致如圖

就這樣,基礎(chǔ)的框架和代碼已經(jīng)被生成了,接著我們用編輯器打開yxReview目錄,首先在items.py文件下新建一個(gè)item。
我們可以先打開網(wǎng)頁游俠評(píng)測分析一下

簡單起見,我們目前只抓取4個(gè)屬性,創(chuàng)建代碼:
class ArticleItem(scrapy.Item):
title = scrapy.Field()
cover_image = scrapy.Field()
summary = scrapy.Field()
score = scrapy.Field()
然后我們進(jìn)入目錄下的spiders文件夾,打開yx_review.py
如下編輯
# -*- coding: utf-8 -*-
import scrapy
from yxReview.items import ArticleItem
class YxReviewSpider(scrapy.Spider):
name = "yx_review"
allowed_domains = ["www.ali213.net"]
start_urls = (
'http://www.ali213.net/news/pingce/',
)
def parse(self, response):
items = []
for sel in response.xpath('//div[@class="t3_l_one_l"]'):
item = ArticleItem()
item["cover_image"] = sel.xpath("div[@class='one_l_pic']/a/img/@src").extract()
item["title"] = sel.xpath("div[@class='one_l_con']/div[@class='one_l_con_tit']/a/text()").extract()
item["summary"] = sel.xpath("div[@class='one_l_con']/div[@class='one_l_con_con']/text()").extract()
items.append(item)
index = 0
for scoreSel in response.xpath('//div[@class = "t3_l_one_r"]'):
item = items[index]
item["score"] = scoreSel.xpath("div/span/text()").extract()
index = index + 1
yield item
print items
這里主要是parse方法,返回請(qǐng)求到的HTML然后解析出我們需要的數(shù)據(jù)裝進(jìn)ArticleItem里,然后將items傳輸?shù)?code>pipeline中。
傳輸管道
在爬蟲scrapy中,pipeline是一個(gè)重要的概念,它相當(dāng)于一個(gè)“加工器”,可以連接多個(gè)自定義的pipeline,完成數(shù)據(jù)的后續(xù)處理工作,比如進(jìn)行篩選分類,或者持久化到本地等等,按優(yōu)先級(jí)串連。
在本例中,為了簡便,我將創(chuàng)建一個(gè)管道將數(shù)據(jù)簡單處理并保存到本地文件中。
打開pipelines.py,編輯如下
# -*- coding: utf-8 -*-
from scrapy import signals
from scrapy.contrib.exporter import JsonItemExporter
class YxreviewPipeline(object):
@classmethod
def from_crawler(cls, crawler):
pipeline = cls()
crawler.signals.connect(pipeline.spider_opened, signals.spider_opened)
crawler.signals.connect(pipeline.spider_closed, signals.spider_closed)
return pipeline
def spider_opened(self, spider):
self.file = open('items.json', 'wb')
self.exporter = JsonItemExporter(self.file)
self.exporter.start_exporting()
def spider_closed(self, spider):
self.exporter.finish_exporting()
self.file.close()
def process_item(self, item, spider):
self.checkData(item, "title")
self.checkData(item, "summary")
self.checkData(item, "cover_image")
self.checkData(item, "score")
self.exporter.export_item(item)
return item
def checkData(self ,item, field):
if len(item[field]) > 0:
newText = item[field][0].encode("utf-8")
item[field] = newText.strip()
else:
item[field] = ""
前面三個(gè)方法,相當(dāng)于給當(dāng)前的pipeline提供了一個(gè)JsonItemExporter的插件,用于將所有爬取的item導(dǎo)出為JSON格式的文件之中。
另外需要說明的是,這里自定義了一個(gè)checkData方法,作為一個(gè)簡單的數(shù)據(jù)類型驗(yàn)證,以及將之前解析的內(nèi)容轉(zhuǎn)換成字符串并且進(jìn)行了utf-8編碼的轉(zhuǎn)碼,保障中文內(nèi)容的正確顯示。
完成后,打開工程目錄下的items.json文件,可以看到數(shù)據(jù)已經(jīng)以JSON格式保存了下來。

告一段落
至此,爬蟲的任務(wù)可以告一段落,當(dāng)然,在實(shí)際應(yīng)用中還需要解決更多的問題,比如分頁爬取,反爬蟲的應(yīng)對(duì)等等,迫于文章篇幅暫且不表,算作擴(kuò)展閱讀吧 :)
下一篇,我們將使用ruby on rails編寫服務(wù)端,提供移動(dòng)端的REST API接口。
系列鏈接
從零開始開發(fā)一個(gè)App(1)- Scrapy爬蟲
從零開始開發(fā)一個(gè)App(2)- 簡易R(shí)EST API服務(wù)端
從零開始開發(fā)一個(gè)App(3)- iOS客戶端