Go開發(fā)的分布式爬蟲框架 yispider

yispider一款分布式爬蟲平臺(tái)瞬沦,幫助你更好的管理和開發(fā)爬蟲笋粟。
內(nèi)置一套爬蟲定義規(guī)則(模版)狞谱,可使用模版快速定義爬蟲糙置,也可當(dāng)作框架手動(dòng)開發(fā)爬蟲 .
.
碼云地址:https://gitee.com/bilibala/YiSpider
github地址:https://github.com/2young2simple/yispider

架構(gòu)

目前框架分為2個(gè)部分:

1.爬蟲部分(spider節(jié)點(diǎn)):

內(nèi)部結(jié)構(gòu)參考python scrapy框架摄闸,主要由 schedule,page process,pipline 4個(gè)部分組成善镰,單個(gè)爬蟲單獨(dú)調(diào)度器妹萨,單獨(dú)上下文管理,目前內(nèi)置2中pipline的方式,控制臺(tái)和文件,節(jié)點(diǎn)信息注冊(cè)在etcd上用于manage節(jié)點(diǎn)發(fā)現(xiàn)炫欺。

  • core:負(fù)責(zé)爬蟲生命周期乎完、上下文的管理,負(fù)責(zé)爬蟲的運(yùn)行品洛。
  • schedule:負(fù)責(zé)爬蟲請(qǐng)求的調(diào)度树姨。(目前只有一種基于channel的調(diào)度器,無法單個(gè)爬蟲多worker運(yùn)行毫别,可自行實(shí)現(xiàn)基于redis娃弓,或者mq服務(wù)的調(diào)度器即可實(shí)現(xiàn))
  • process (page process):負(fù)責(zé)請(qǐng)求結(jié)果的處理。
  • pipline: 結(jié)果的輸出輸出到不同渠道,如控制臺(tái)岛宦,文件台丛,消息隊(duì)列,數(shù)據(jù)庫(kù)等等
  • register:負(fù)責(zé)服務(wù)的注冊(cè)(目前只支持etcd)
  • http: 提供一些http接口

2.管理部分(manage節(jié)點(diǎn)):

負(fù)責(zé)spider節(jié)點(diǎn)的管理砾肺,用etcd進(jìn)行spider節(jié)點(diǎn)的發(fā)現(xiàn)挽霉。通過http與spider節(jié)點(diǎn)通訊。

開始使用

1. Json模版

http接口調(diào)用
curl -d '{"id":"douban-movie","Name":"douban-movie","request":[{"url":"https://movie.douban.com/j/new_search_subjects?sort=T\u0026range=0,10\u0026tags=\u0026start={0-100,20}","method":"get","type":"","data":null,"header":null,"cookies":{"url":"","data":""},"process_name":"movie"}],"process":[{"name":"movie","reg_url":null,"type":"json","template_rule":{"Rule":null},"json_rule":{"Rule":{"casts":"casts","cover":"cover","id":"id","node":"array|data","rate":"rate","star":"star","title":"title","url":"url"}},"add_queue":null}],"pipline":"file","depth":0,"end_count":0}' "http://127.0.0.1:7774/task/addAndRun"

豆瓣電影模版

 {
    "id": "douban-movie",
    "Name": "douban-movie",
    "request": [
        {
            "url": "https://movie.douban.com/j/new_search_subjects?sort=T&range=0,10&tags=&start={0-10,20}",
            "method": "get",
            "process_name": "movie"
        }
    ],
    "process": [
        {
            "name": "movie",
            "type": "json",
            "json_rule": {
                "Rule": {
                    "casts": "casts",
                    "cover": "cover",
                    "id": "id",
                    "node": "array|data",
                    "rate": "rate",
                    "star": "star",
                    "title": "title",
                    "url": "url"
                }
            },
            "add_queue": null
        }
    ],
    "pipline": "file",
    "depth": 0,
    "end_count": 0
}

dilidili模版

   {
    "id": "dilidili",
    "Name": "dilidili",
    "request": [
        {
            "url": "http://www.dilidili.wang/{gaoxiao|kehuan|yundong|danmei|zhiyuxi|luoli|zhenren|zhuangbi|youxi|tuili|qingchun|kongbu|jizhan|rexue|qingxiaoshuo|maoxian|hougong|qihuan|tongnian|lianai|meishaonv|lizhi|baihe|paomianfan|yinv}/",
            "method": "get",
            "process_name": "animelist"
        }
    ],
    "process": [
        {
            "name": "animelist",
            "type": "template",
            "template_rule": {
                "Rule": {
                    "content": "text|dd div",
                    "desc": "text|dd p",
                    "href": "attr.href|dt a",
                    "img": "attr.src|dt a img",
                    "node": "array|.anime_list dl",
                    "title": "text|dd h3 a"
                }
            },
            "add_queue": [
                {
                    "url": "http://www.dilidili.wang{href}",
                    "method": "get",
                    "process_name": "animeinfo"
                }
            ]
        },
        {
            "name": "animeinfo",
            "type": "template",
            "template_rule": {
                "Rule": {
                    "episode": "texts|.time_con .swiper-slide .clear li a em",
                    "episode-link": "attrs.href|.time_con .swiper-slide .clear li a",
                    "title": "text|.detail dl dd h1"
                }
            },
            "add_queue": [
                {
                    "url": "{episode-link}",
                    "method": "get",
                    "process_name": "episodeinfo"
                }
            ]
        },
        {
            "name": "episodeinfo",
            "reg_url": null,
            "type": "template",
            "template_rule": {
                "Rule": {
                    "player": "attr.src|.player_main iframe",
                    "title": "text|#intro2 h1",
                    "url": "attr.href|link[rel=\"canonical\"]"
                }
            },
            "add_queue": null
        }
    ],
    "pipline": "file",
    "depth": 0,
    "end_count": 0
}

2. 代碼模版 編寫

豆瓣電影

package main

import (
    "YiSpider/spider/model"
    "YiSpider/spider"
    spider2 "YiSpider/spider/spider"
)

func main(){

    task := &model.Task{
        Id:"douban-movie",
        Name:"douban-movie",
        Request:[]*model.Request{
            {
                Method:"get",
                Url:"https://movie.douban.com/j/new_search_subjects?sort=T&range=0,10&tags=&start={0-10000,20}",
                ProcessName:"movie",
            },
        },
        Process: []model.Process{
            {
                Name:"movie",
                Type:"json",
                JsonRule:model.JsonRule{
                    Rule:map[string]string{
                        "node":"array|data",
                        "rate":"rate",
                        "star":"star",
                        "id":"id",
                        "url":"url",
                        "title":"title",
                        "cover":"cover",
                        "casts":"casts",
                    },
                },
            },
        },
        Pipline:"file",
    }

    app := spider.New()
    app.AddSpider(spider2.InitWithTask(task))
    app.Run()
}

dilidili番劇

package main

import (
    "YiSpider/spider/model"
    "YiSpider/spider"
    spider2 "YiSpider/spider/spider"
)

func main(){

    task := &model.Task{
        Id:"dilidili",
        Name:"dilidili",
        Request:[]*model.Request{
            {
                Method:"get",
                Url:"http://www.dilidili.wang/{gaoxiao|kehuan|yundong|danmei|zhiyuxi|luoli|zhenren|zhuangbi|youxi|tuili|qingchun|kongbu|jizhan|rexue|qingxiaoshuo|maoxian|hougong|qihuan|tongnian|lianai|meishaonv|lizhi|baihe|paomianfan|yinv}/",
                ProcessName:"animelist",
            },
        },
        Process: []model.Process{
            {
                Name:"animelist",
                Type:"template",
                TemplateRule:model.TemplateRule{
                    Rule:map[string]string{
                        "node":"array|.anime_list dl",
                        "img":"attr.src|dt a img",
                        "title":"text|dd h3 a",
                        "href":"attr.href|dt a",
                        "content":"text|dd div",
                        "desc":"text|dd p",
                    },
                },
                AddQueue:[]*model.Request{
                    {
                        Method:      "get",
                        Url:         "http://www.dilidili.wang{href}",
                        ProcessName: "animeinfo",
                    },
                },
            },
            {
                Name:"animeinfo",
                Type:"template",
                TemplateRule:model.TemplateRule{
                    Rule:map[string]string{
                        "episode":"texts|.time_con .swiper-slide .clear li a em",
                        "title":"text|.detail dl dd h1",
                        "episode-link":"attrs.href|.time_con .swiper-slide .clear li a",
                    },
                },
                AddQueue:[]*model.Request{
                    {
                        Method:      "get",
                        Url:         "{episode-link}",
                        ProcessName: "episodeinfo",
                    },
                },
            },
            {
                Name:"episodeinfo",
                Type:"template",
                TemplateRule:model.TemplateRule{
                    Rule:map[string]string{
                        "url":"attr.href|link[rel=\"canonical\"]",
                        "title":"text|#intro2 h1",
                        "player":"attr.src|.player_main iframe",
                    },
                },
            },
        },

        Pipline:"file",
    }


    app := spider.New()
    app.AddSpider(spider2.InitWithTask(task))
    app.Run()

}
  1. 純代碼編寫

碼云地址:https://gitee.com/bilibala/YiSpider
github地址:https://github.com/2young2simple/yispider

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末变汪,一起剝皮案震驚了整個(gè)濱河市侠坎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌裙盾,老刑警劉巖实胸,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異番官,居然都是意外死亡庐完,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門徘熔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來门躯,“玉大人,你說我怎么就攤上這事酷师⊙攘梗” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵山孔,是天一觀的道長(zhǎng)懂讯。 經(jīng)常有香客問我,道長(zhǎng)台颠,這世上最難降的妖魔是什么褐望? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上譬挚,老公的妹妹穿的比我還像新娘。我一直安慰自己酪呻,他們只是感情好减宣,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著玩荠,像睡著了一般漆腌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上阶冈,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天闷尿,我揣著相機(jī)與錄音,去河邊找鬼女坑。 笑死填具,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的匆骗。 我是一名探鬼主播劳景,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼碉就!你這毒婦竟也來了盟广?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤瓮钥,失蹤者是張志新(化名)和其女友劉穎筋量,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碉熄,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡桨武,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了具被。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玻募。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖一姿,靈堂內(nèi)的尸體忽然破棺而出七咧,到底是詐尸還是另有隱情,我是刑警寧澤叮叹,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布艾栋,位于F島的核電站,受9級(jí)特大地震影響蛉顽,放射性物質(zhì)發(fā)生泄漏蝗砾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望悼粮。 院中可真熱鬧闲勺,春花似錦、人聲如沸扣猫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽申尤。三九已至癌幕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間昧穿,已是汗流浹背勺远。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留时鸵,地道東北人胶逢。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像饰潜,于是被迫代替她去往敵國(guó)和親宪塔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

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

  • from http://www.infoq.com/cn/articles/etcd-interpretation...
    小樹苗苗閱讀 13,940評(píng)論 3 38
  • 引言 在上篇使用Scrapy爬取知乎用戶信息我們編寫了一個(gè)單機(jī)的爬蟲囊拜,這篇記錄了使用Scrapy-Redis將其重...
    朱曉飛閱讀 6,684評(píng)論 1 24
  • 她渾身油漬某筐,陽光靜靜灑在她花貓般的臉龐 她滿面笑容,將零件輕輕嵌入它空空的胸膛 一聲輕響冠跷,從此她就注定成為它的心臟...
    新鮮的陽光_1364閱讀 186評(píng)論 0 0
  • 會(huì)幼稚到搞怪賣傻南誊,會(huì)開心到當(dāng)街歌唱,會(huì)氣憤到心酸淚涌蜜托。不是我膚淺抄囚,而是一旦涉及到你我的情感都會(huì)純粹。
    湛兮閱讀 198評(píng)論 0 0
  • 七夕的燈火闌珊 有沒有人為你買單 你的孤單是喜歡和不喜歡的恰恰相反 你拿著單反拍著戀人 尋找他們的破綻 這個(gè)七夕應(yīng)...
    荒島書屋i閱讀 240評(píng)論 0 0