【Sasila】一個(gè)簡單易用的爬蟲框架

現(xiàn)在有很多爬蟲框架潮孽,比如scrapy娜搂、webmagicpyspider都可以在爬蟲工作中使用笙蒙,也可以直接通過requests+beautifulsoup來寫一些個(gè)性化的小型爬蟲腳本罕扎。但是在實(shí)際爬取過程當(dāng)中聚唐,爬蟲框架各自有優(yōu)勢(shì)和缺陷。比如scrapy腔召,它的功能強(qiáng)大杆查,但過于強(qiáng)大的功能也許反而讓新手無所適從,并且它采用twisted異步框架開發(fā)臀蛛,對(duì)新手來說源碼難以理解根灯,項(xiàng)目難于調(diào)試。所以我模仿這些爬蟲框架的優(yōu)勢(shì)掺栅,以盡量簡單的原則,搭配gevent(實(shí)際上是grequests)開發(fā)了這套輕量級(jí)爬蟲框架纳猪。

  • downloader是下載器氧卧。
  • processor是解析器。
  • scheduler是調(diào)度器氏堤。
  • pipeline是數(shù)據(jù)處理器沙绝。
  • 將下載器,解析器鼠锈,調(diào)度器闪檬,數(shù)據(jù)處理器注入核心core成為spider對(duì)象。
  • 通過manager管理spider對(duì)象
  • manager透過webapi提供外部訪問/控制接口

主要特點(diǎn)

  • 框架代碼結(jié)構(gòu)簡單易用购笆,易于修改粗悯。新手、老鳥皆可把控同欠。
  • 采用gevent實(shí)現(xiàn)并發(fā)操作样傍,與scrapy的twisted相比,代碼更容易理解铺遂。
  • 完全模塊化的設(shè)計(jì)衫哥,強(qiáng)大的可擴(kuò)展性。
  • 使用方式和結(jié)構(gòu)參考了scrapywebmagic襟锐。對(duì)有接觸過這兩個(gè)框架的朋友非常友好撤逢。
  • 不采用命令行來啟動(dòng)爬蟲,方便調(diào)試。
  • 對(duì)數(shù)據(jù)的解析模塊并沒有集成蚊荣,可以自由使用beautifulsoup初狰、lxmlpyquery妇押、html5lib等等各種解析器進(jìn)行數(shù)據(jù)抽取跷究。
  • 集成代理換IP功能。
  • 支持高并發(fā)采集數(shù)據(jù)敲霍。
  • 支持分布式俊马。
  • 支持增量爬取。
  • 支持爬取js動(dòng)態(tài)渲染的頁面(加載SeleniumDownLoader即可)肩杈。
  • 提供webapi對(duì)爬蟲進(jìn)行管理柴我、監(jiān)控。
  • 提供即時(shí)爬蟲的集成思路和結(jié)構(gòu)扩然。

安裝

pip install sasila

準(zhǔn)備

  • 請(qǐng)準(zhǔn)備好您的redis服務(wù)器進(jìn)行調(diào)度艘儒。
  • 并在settings.py文件中 寫入您的redis服務(wù)器地址
REDIS_HOST = 'localhost'
REDIS_PORT = 6379

構(gòu)建processor(解析器)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup as bs
from sasila.system_normal.processor.base_processor import BaseProcessor
from sasila.system_normal.downloader.http.spider_request import Request
from sasila.system_normal.spider.spider_core import SpiderCore

class Mzi_Processor(BaseProcessor):
    spider_id = 'mzi_spider'
    spider_name = 'mzi_spider'
    allowed_domains = ['mzitu.com']
    start_requests = [Request(url='http://www.mzitu.com/', priority=0)]

    @checkResponse
    def process(self, response):
        soup = bs(response.m_response.content, 'lxml')
        print soup.title.string
        href_list = soup.select('a')
        for href in href_list:
            yield Request(url=response.nice_join(href['href']))

寫法與scrapy幾乎一樣

  • 所有的解析器都繼承自 BaseProcessor ,默認(rèn)入口解析函數(shù)為def process(self, response)夫偶。
  • 為該解析器設(shè)置spider_id和spider_name,以及限定域名界睁。
  • 初始爬取請(qǐng)求為 start_requests,構(gòu)建Request對(duì)象兵拢,該對(duì)象支持GET翻斟、POST方法,支持優(yōu)先級(jí)说铃,設(shè)置回調(diào)函數(shù)等等所有構(gòu)建request對(duì)象的一切屬性访惜。默認(rèn)回調(diào)函數(shù)為 process
  • 可以使用@checkResponse裝飾器對(duì)返回的 response 進(jìn)行校驗(yàn)并記錄異常日志腻扇。你也可以定義自己的裝飾器债热。
  • 解析函數(shù)因?yàn)槭褂?yield 關(guān)鍵字,所以是一個(gè)生成器幼苛。當(dāng) yield 返回 Request 對(duì)象窒篱,則會(huì)將 Request 對(duì)象推入調(diào)度器等待調(diào)度繼續(xù)進(jìn)行爬取。若 yield 不是返回 Request 對(duì)象則會(huì)進(jìn)入 pipeline 舶沿, pipeline 將對(duì)數(shù)據(jù)進(jìn)行清洗入庫等操作舌剂。

與scrapy相似,sasila同樣提供LinkExtractor的方式來提取鏈接暑椰,以下是用LinkExtractor的方式構(gòu)造processor下載妹子圖的示例**

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from sasila.system_normal.processor.base_processor import BaseProcessor, Rule, LinkExtractor
from sasila.system_normal.downloader.http.spider_request import Request
import os
import uuid

class MezituProcessor(BaseProcessor):
    spider_id = 'mzitu'
    spider_name = 'mzitu'
    allowed_domains = ['mzitu.com', 'meizitu.net']
    start_requests = [Request(url='http://www.mzitu.com/xinggan/')]

    rules = (
        Rule(LinkExtractor(regex_str=r"http://i.meizitu.net/\d{4}/\d{2}/[0-9a-z]+.jpg"),callback="save", priority=3),
        Rule(LinkExtractor(regex_str=r"http://www.mzitu.com/\d+"), priority=1),
        Rule(LinkExtractor(regex_str=r"http://www.mzitu.com/\d+/\d+"), priority=2),
        Rule(LinkExtractor(regex_str=r"http://www.mzitu.com/xinggan/page/\d+"), priority=0),
    )

    def save(self, response):
        if response.m_response:
            if not os.path.exists("img"):
                os.mkdir("img")
            with open("img/" + str(uuid.uuid1()) + ".jpg", 'wb') as fs:
                fs.write(response.m_response.content)
                print("download success!")

LinkExtractor的構(gòu)造方式為

LinkExtractor(regex_str=None, css_str=None, process_value=None)
  • 提供正則表達(dá)式提取方式:regex_str
  • 提供css選擇器提取方式:css_str
  • 也可以自定義process_value來提取鏈接霍转,其中process_value是一個(gè)生成器
  • 若使用此方式構(gòu)造processor,請(qǐng)不要定義默認(rèn)入口函數(shù)def process(self, response)

構(gòu)建pipeline

該pipeline獲取數(shù)據(jù)后將數(shù)據(jù)轉(zhuǎn)為json格式一汽,并輸出到屏幕

from sasila.system_normal.pipeline.base_pipeline import ItemPipeline
import json

class ConsolePipeline(ItemPipeline):
    def process_item(self, item):
        print json.dumps(item).decode("unicode-escape")

構(gòu)建spider(爬蟲對(duì)象)

  • 通過注入 processor 生成spider對(duì)象
from sasila.system_normal.spider.spider_core import SpiderCore

spider = SpiderCore(Mzi_Processor())
  • SpiderCore對(duì)象包含批下載數(shù)量 batch_size避消,下載間隔 time_sleep低滩,使用代理 use_proxy 等一切必要的屬性
SpiderCore(processor=None, downloader=None, use_proxy=False,scheduler=None,batch_size=None,time_sleep=None)
  • 本項(xiàng)目集成使用代理IP的功能,只要在構(gòu)建SpiderCore時(shí)將 use_proxy 設(shè)置為 True,并在腳本同級(jí)目錄下放置proxy.txt文件即可岩喷。你也可以在settings.py文件中寫入代理IP文件路徑恕沫。
PROXY_PATH_REQUEST = 'proxy/path'
  • proxy.txt文件中請(qǐng)寫入代理IP,格式為:IP,端口號(hào)纱意。若該代理IP有賬號(hào)密碼婶溯,在末尾追加賬號(hào)密碼即可。
127.0.0.1,8080
127.0.0.2,8080,user,pwd
127.0.0.3,8080,user,pwd
  • SpiderCore已經(jīng)默認(rèn)設(shè)置好了 downloaderscheduler偷霉,如果不滿意迄委,可以自己進(jìn)行定制。

  • 可以為spider設(shè)置 downloaderpipeline 甚至 scheduler

 spider = spider.set_pipeline(ConsolePipeline())
  • 可以通過該方式啟動(dòng)爬蟲
spider.start()
  • 也可以將spider注入manager進(jìn)行管理
from sasila.system_normal.manager import manager
from sasila import system_web

manager.set_spider(spider)

system_web.start()

訪問 http://127.0.0.1:5000/slow_spider/start?spider_id=mzi_spider 來啟動(dòng)爬蟲类少。
訪問 http://127.0.0.1:5000/slow_spider/stop?spider_id=mzi_spider 來停止爬蟲叙身。
訪問 http://127.0.0.1:5000/slow_spider/detail?spider_id=mzi_spider 來查看爬蟲詳細(xì)信息。

針對(duì)需要登錄才能爬取的處理辦法

  • 可以為downloader加載登錄器(loginer),在使用downloader的時(shí)候使用loginer進(jìn)行登錄獲取cookies,再進(jìn)行爬取
  • 也可以自己定義一個(gè)cookie池硫狞,批量進(jìn)行登錄并將登錄成功的cookies放進(jìn)cookie池中隨時(shí)進(jìn)行取用信轿。項(xiàng)目中暫時(shí)沒有這些功能。歡迎pull request~

架構(gòu)

  • 任務(wù)由 scheduler 發(fā)起調(diào)度残吩,downloader 抓取網(wǎng)頁內(nèi)容财忽, processor 執(zhí)行預(yù)先編寫的py腳本,輸出結(jié)果或產(chǎn)生新的提鏈任務(wù)(發(fā)往 scheduler)泣侮,形成閉環(huán)即彪。
  • 每個(gè)腳本被認(rèn)為是一個(gè)spider,spiderid確定一個(gè)任務(wù)旁瘫。
  • downloader
    1.method, header, cookie, proxy,timeout 等等抓取調(diào)度控制。
    2.可以通過適配類似 phantomjs 的webkit引擎支持渲染琼蚯。
  • processor
    1.靈活運(yùn)用pyquery酬凳,beautifulsoup等解析頁面。
    2.在腳本中完全控制調(diào)度抓取的各項(xiàng)參數(shù)遭庶。
    3.可以向后鏈傳遞信息宁仔。
    4.異常捕獲。
  • scheduler
    1.任務(wù)優(yōu)先級(jí)峦睡。
    2.對(duì)任務(wù)進(jìn)行監(jiān)控翎苫。
    3.對(duì)任務(wù)進(jìn)行去重等操作。
    4.支持增量榨了。
  • webApi
    1.對(duì)爬蟲進(jìn)行增刪改查等操作煎谍。
非及時(shí)爬蟲流程圖

即時(shí)爬蟲

即時(shí)爬蟲是可以通過api調(diào)用,傳入需要爬取的頁面或者需求龙屉,即時(shí)爬取數(shù)據(jù)并返回結(jié)果∧耪常現(xiàn)階段開發(fā)并不完善满俗。僅提供思路參考。示例核心代碼在 sasila.system_instant 中作岖。

即時(shí)爬蟲-獲取數(shù)據(jù)流程圖
即時(shí)爬蟲-授權(quán)流程圖

為啥叫Sasila唆垃?

作為一個(gè)wower,你可以猜到嗎ヾ( ̄▽ ̄)

環(huán)境

現(xiàn)已支持python 3.X

聯(lián)系方式

如果對(duì)使用有疑問,或者有想法痘儡,歡迎加入討論群:602909155交流~

項(xiàng)目地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辕万,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子沉删,更是在濱河造成了極大的恐慌渐尿,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丑念,死亡現(xiàn)場離奇詭異涡戳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)脯倚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門渔彰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人推正,你說我怎么就攤上這事恍涂。” “怎么了植榕?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵再沧,是天一觀的道長。 經(jīng)常有香客問我尊残,道長炒瘸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任寝衫,我火速辦了婚禮顷扩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘慰毅。我一直安慰自己隘截,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布汹胃。 她就那樣靜靜地躺著婶芭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪着饥。 梳的紋絲不亂的頭發(fā)上犀农,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音宰掉,去河邊找鬼井赌。 笑死谤逼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的仇穗。 我是一名探鬼主播流部,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼纹坐!你這毒婦竟也來了枝冀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤耘子,失蹤者是張志新(化名)和其女友劉穎果漾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谷誓,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绒障,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了捍歪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片户辱。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖糙臼,靈堂內(nèi)的尸體忽然破棺而出庐镐,到底是詐尸還是另有隱情,我是刑警寧澤变逃,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布必逆,位于F島的核電站,受9級(jí)特大地震影響揽乱,放射性物質(zhì)發(fā)生泄漏名眉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一凰棉、第九天 我趴在偏房一處隱蔽的房頂上張望损拢。 院中可真熱鬧,春花似錦渊啰、人聲如沸探橱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至哗讥,卻和暖如春嚷那,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背杆煞。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國打工魏宽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腐泻,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓队询,卻偏偏與公主長得像派桩,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蚌斩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容