現(xiàn)在有很多爬蟲框架潮孽,比如scrapy娜搂、webmagic、pyspider都可以在爬蟲工作中使用笙蒙,也可以直接通過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)參考了scrapy和webmagic襟锐。對(duì)有接觸過這兩個(gè)框架的朋友非常友好撤逢。
- 不采用命令行來啟動(dòng)爬蟲,方便調(diào)試。
- 對(duì)數(shù)據(jù)的解析模塊并沒有集成蚊荣,可以自由使用beautifulsoup初狰、lxml、pyquery妇押、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è)置好了 downloader 和 scheduler偷霉,如果不滿意迄委,可以自己進(jìn)行定制。
可以為spider設(shè)置 downloader 和 pipeline 甚至 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í)爬蟲是可以通過api調(diào)用,傳入需要爬取的頁面或者需求龙屉,即時(shí)爬取數(shù)據(jù)并返回結(jié)果∧耪常現(xiàn)階段開發(fā)并不完善满俗。僅提供思路參考。示例核心代碼在 sasila.system_instant 中作岖。
為啥叫Sasila唆垃?
作為一個(gè)wower,你可以猜到嗎ヾ( ̄▽ ̄)
環(huán)境
現(xiàn)已支持python 3.X
聯(lián)系方式
如果對(duì)使用有疑問,或者有想法痘儡,歡迎加入討論群:602909155交流~