Tag Archives: spyder

Spyder介绍

Spyder这个项目本来也没打算要写,但是最近因为一些业务上的需求,需要重新使用,就顺手写一点介绍。Spyder是一个用python2写出来的页面抓取工具,代码托管在Github上。原先Spyder是需要mysql才行的,这次改版我把管理界面和采集器本身进行了一次分离。因此这一次只来说说采集器的本身,Web管理界面等到下一次再说吧。

在src目录里spyder可以采集器,web为web管理界面,libs放了一些通用的函数在里面。用Spyder前,你需要安装lxml。这个是一个非常有用的库,可以对采集回来的html数据进行dom操作。

Spyder中最基础的单元为Seed,也就是所谓的种子。一个种子他包含了你需要采集的需求。看下这例子:

import os, sys
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)));
if parentdir not in sys.path:
    sys.path.insert(0, parentdir)

from spyder.seed import Seed

config = {
    'listtype': u'html',
    'tries': 5,
    'frequency': 7200,
    'lang': u'zhCN',
    'seed_name': u'抓取在线人数',
    'enabled': 1,
    'rule': {
        'urlformat': 'http://www.douyu.tv/directory/all?offset=$page&limit=30',
        'pageparent': '',
        'maxpage': 25,
        'step': 30,
        'startpage': 0,
        'contenturl': '',
        'listparent': 'div[id="item_data"] ul li',
        'urltype': 'createLink',#链接模式
        'contentparent': 'a[class="list"]',
        'zero': 1,
        'entryparent': '',
        'filters': [
            #filterid, value, fetch_all, type(content/list)
        ],
        'extrarules':[
            ('title', 'h1[class="title"].text()', 0, 'list'),
            ('view', 'span[class="view"].text()', 0, "list"),
            ('name', 'span[class="nnt"].text()', 0, "list"),
            ('game', 'span[class="zbName"].text()', 0, "list"),
        ]
    },
    'timeout': 5,
    'sid': 1000L
}

seed = Seed(config);

上面就是一个抓取某网站直播在线人数的配置文本。这里包含了listtype(列表页面类型:html, json, feed)、tries(尝试次数,默认为5次)、seed_name(种子名称)、sid(种子ID,必须要分配一个)、enable(是否启用)、rule(采集配置)。
rule中包含了基础的采集信息和过滤器以及额外需要抓取的数据。 先来说说基础的

  1. 生成列表链接
  2. urlformat 列表页面模板,这个需要和下面的urltype结合在一起使用。一般来说需要抓取的列表页面都是有规则的。所以我在urltype中设定了三种模式inputLink(自定义模式)、createLink(根据设定的step, maxpage, startpage,来生成列表链接)、dateLink(根据设定的日期格式)。 在这些列表中可选参数是$page。这个用于指定需要填充的位置。比如上面例子中的,就是createLink类型。根据所指定的规则,他会生成为:
    http://www.douyu.tv/directory/all?offset=0&limit=30
    http://www.douyu.tv/directory/all?offset=30&limit=30

  3. 提取列表及获取文章链接
  4. 在你生成列表链接之后,就可以开始抓取了。抓取下来的都是html页面。这个时候你需要配置需要采集的列表区域以及文章链接。这里需要涉及listparent,contentparent。这里的配置很简单,如果你熟悉jquery的话,那么配置起来相当简单。

上面已经简单的描述了如何去获取列表内容。在这里,可能我会囉嗦几句关于配置正则方面的东西。先来说下extrarules。这里面包含了你需要采集的其他信息。rule本身只是去抓取页面和获取文章链接,其余信息是都没有的。所以你需要配置extrarules让Spyder知道你需要从页面上获取哪里信息。

('title', 'h1[class="title"].text()', 0, 'list'),

上面这个就是一个简单的extrarules中的一条。 分别对应name,parent, fetchall, type。 name就是在你后期获取数据时候的一个key。第二个为抓取正则,这个正则如同上面一样,都是和jquery差不多。获取文字用text(),如果你要获取html就用html()。这个就可以在浏览器先试成功之后,再复制粘帖进来。第三个为是否全部抓取,第四个为类型(list列表, content 文章)。

除了extrarules还有一个叫做filters,过滤器功能可以用做替换,可以改文本内容。这个下次时候我在述说。

通过上面的配置,一个采集的种子已经配置完成了。

第二步就是数据的采集过程了。

import os, sys
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)));
if parentdir not in sys.path:
    sys.path.insert(0, parentdir)

from spyder.seed import Seed
from spyder.document import Grab

seed = Seed(config);
data = Grab(seed);

你只要引用document中的Grab就可以了。他会采集完成后的数据全部放在items中。你可以只需要进行数据遍历即可。

以上简单介绍了一个Spyder,它与其他采集器不一样的地方在于灵活,配置方便。可以用于各种情况。项目在一年前写的,但是集成了相当多的功能,比如图片存储转换链接,存储到数据库,可扩展插件等等。目前我正在所以对代码进行一次整理,这篇文章也算是对原有代码逻辑的一次梳理。