pyspider + RabbitMQ 使用记 - 下

首先我们需要安装 RabbitMQ,然后通过服务启动它,默认为注册到本机的5672端口。我们的爬虫和数据库写入脚本都需要连接到 RabbitMQ,一边往队列中写入数据,另一边从队列中取出数据,然后插入到数据。

Python 中使用 RabbitMQ 可以通过调用 pika 这个库,安装过程见官方文档,对于 RabbitMQ 本身也有中文教程

本项目用到的模型是一对一的,用 pika 写很容易,代码如下:

import pika
# 导入库
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
# 设置一个新连接,连接到本地的 RabbitMQ 服务端。
channel = connection.channel()
# 注册到 books 队列
channel.queue_declare(queue='books')
channel.basic_publish(exchange='', routing_key='books', body='Whats up')
# 发送消息 body
connection.close()
# 

在 basic_publish 这个函数中,我们设置 exchange 为空,而 routing-key 为 books,此时 basic_publish 会默认把我们的 body 信息根据 routing-key 的内容发送到 books 的队列中。

这里 exchange 其实是一个信息中转站,如下图,P 为我们要发送的信息,X 就是信息中转站,我们通过 exchange 字段来设置我们的目标中转站,然后由 exchange 来决定我们的信息要往哪里走。 exchange

而 routing-key 的设置也很有讲究,可以参考教程中 Routing 一节。

到此,我们已经写好生产者了,接下来我们看消费者。

import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='books')


def callback(ch, method, properties, body):
    print body

channel.basic_consume(callback, queue='books', no_ack=True)
# 注册回调函数,当有消息取出时,程序调用 callback 函数,其中 body 就是取出的消息。
channel.start_consuming()

这里我们在回调函数中可以直接打印 body 到控制台。

最后贴一下代码,爬虫端:

#!/usr/bin/env python
# -*- encoding: utf-8 -*-

from pyspider.libs.base_handler import *
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='books')


class Handler(BaseHandler):
    crawl_config = {}

    def on_start(self):
        self.crawl('http://scrapy.org/', callback=self.index_page)
    
    def on_result(self, result):
        # 重写 on_result 函数
        if not result:
            return
        assert self.task, "on_result can't outside a callback."
        result['callback'] = self.task['process']['callback']
        if self.is_debugger():
            pprint(result)
            channel.basic_publish(exchange='', routing_key='books', body=result)
        if self.__env__.get('result_queue'):
            channel.basic_publish(exchange='', routing_key='books', body=result)
            self.__env__['result_queue'].put((self.task, result))
        
    @config(priority=5)
    def index_page(self, response):
        url_list = []
        for each in response.doc('a[href^="http"]').items():
            url_list.append(each.attr.href)
        return url_list

消费者端:

import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'spider.settings')
import django
django.setup()
from django.core.exceptions import ObjectDoesNotExist
from importer.models import Books

import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='books')


def callback(ch, method, properties, body):
    new_book = Books()
    new_book.url = body
    new_book.save()
    print body + ' saved!'

channel.basic_consume(callback, queue='books', no_ack=True)
channel.start_consuming()

本例中调用了 django 的 BOOKS 的数据库模型,在队列中取出消息后,存入 BOOKS 表中,字段为url。

转载于:https://my.oschina.net/shinedev/blog/488480

pyspider错误"subprocess-exited-with-error"表示在运行pyspider时,遇到一个或多个子进程出现错误,导致整个命令无法完成。这种错误通常与操作系统或Python版本相关。为了解决这个问题,你可以采取以下几个步骤: 1. 确认你的电脑上是否安装了所需的依赖库。你可以使用pip install命令来安装所需的库。确保你已经安装了pyspider的所有依赖库,并且它们的版本是兼容的。 2. 确保你的操作系统是最新的,并且已经安装了最新版本的Python。有些依赖库只能在特定版本的Python上运行。你可以通过运行python --version命令来查看你当前的Python版本。如果你的Python版本过旧,你可能需要更新到最新的版本。 3. 如果以上步骤都无法解决问题,你可以尝试重新安装Python。你可以使用python -m ensurepip命令来重新安装Python。这将确保你有最新的pip和setuptools库。 如果你使用的是Windows操作系统,还可以尝试下载并安装与你的Python版本对应的pycurl库。你可以在https://www.lfd.uci.edu/~gohlke/pythonlibs/#pycurl网站上找到Python版本对应的pycurl文件。下载后,你可以使用pip install命令来安装pycurl库。 总结起来,要解决pyspider错误"subprocess-exited-with-error",你可以尝试安装所需的依赖库、更新Python版本、重新安装Python或下载并安装适用于你的Python版本的pycurl库。<span class="em">1</span><span class="em">2</span><span class="em">3</span>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值