pyspider + RabbitMQ 使用记

南笙酒味 提交于 2019-12-06 00:58:27

接到一个爬虫任务,项目比较巨大,原来想用 Requests 配合正则做爬虫。后来得知了 pyspider 这个神器,才知道之前的想法 low 爆了。pyspider GitHub

按照 GitHub 上的安装教程安装好以后,我们就可以通过 pyspider 命令来启动这个神器,然后在浏览器中打开 http://localhost:5000/ 就可以看到界面了。首先是一个 Dashboard,我们在这里可以创建爬虫项目,点击 Create 然后输入项目名就可以看到代码了。

关于项目的帮助可以看文档,在 GitHub 上可以找到该项目的 Docs 链接,我们现在上来直接看代码,我用中文做下注释。

from pyspider.libs.base_handler import *
# 引入 pyspider 的 base_handler,这个是用来当基类的。
# 以下就是我们写的类。
class Handler(BaseHandler):
    crawl_config = {
    }
    # 这个是作为整个项目的全局参数的设置,比如 proxy。
    @every(minutes=24 * 60)
    # 这句话是定时启动的意思,这里就是说每一天启动一次。
    # 以下为爬虫的入口
    def on_start(self):
    # 抓 http://scrapy.org/ 的页面,将返回的内容交给 index_page 函数来处理。
        self.crawl('http://scrapy.org/', callback=self.index_page)

    @config(age=10 * 24 * 60 * 60)
    # 每十天重启一次
    def index_page(self, response):
        for each in response.doc('a[href^="http"]').items():
        # 这里将 on_start 抓取 scrapy 首页的返回结果进行过滤,采用了 CSS 选择器选择了 href 的值为 http 开头的所有 a 标签。
        # 此处循环内的 each 即为网页中的 a 标签。
            self.crawl(each.attr.href, callback=self.detail_page)
            # 再次调用 crawl 函数,对 a 标签的 href 中目标网址进行抓取,返回给 detail_page 函数来处理。

    def detail_page(self, response):
        return {
            "url": response.url,
            # 返回 url 和网页 title 组成的字典。
            "title": response.doc('title').text(),
        }

作者自己写的中文教程里面已经把很多操作都讲清楚了,我就不抄来了。

对于 ajax 请求的内容可以直接 crawl 那个 ajax 请求的 URL,返回的 response.json 就变成了一个 Python 的字典。

当每个函数 return 的时候,return 的内容被传递到了 BaseHandler 这个基类中的 on_result 函数,其代码如下:

    def on_result(self, result):
        """Receiving returns from other callback, override me."""
        if not result:
            return
        assert self.task, "on_result can't outside a callback."
        if self.is_debugger():
        # 当在浏览器中调试运行时:
            pprint(result)
        if self.__env__.get('result_queue'):
        # 当被当作任务执行时,即在 Dashboard 中设置为 RUNNING 时,
            self.__env__['result_queue'].put((self.task, result))

然后我们就可以通过重写 on_result 函数,来将所有函数的返回值进行处理,再输出到 RabbitMQ 的队列中。

队列的另一端是数据库写入脚本,该脚本一条一条地从队列中取出消息,然后一个字段一个字段地插入到数据库,不用担心数据库写入时的冲突问题了。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!