Pyspider框架(四)

一、项目环境部署

由于pyspider具有各种组件,因此您只需运行pyspider即可启动独立的第三个免费服务实例。或者使用MySQL或MongoDB和RabbitMQ来部署分布式爬网集群。要在产品环境中部署pyspider,在每个进程中运行组件并在数据库服务中存储数据更可靠和更灵活。

1.依赖安装

  • 要在每个进程中部署pyspider组件,至少需要一个数据库服务。

  • pyspider现在支持MySQL、MongoDB和PostgreSQL。你可以从中选一个。

  • 您需要一个消息队列服务来将这些组件连接在一起。您可以使用RabbitMQ、Beanstalk或Redis作为消息队列。

  • 即使您以前使用pip安装过pyspider。要安装MySQL/MongoDB/RabbitMQ的需求,必须使用pyspider[all]安装。pip install pyspider[all]

如果你正在使用Ubuntu(上面是针对windows而言的),试试:
apt-get install python python-dev python-distribute python-pip libcurl4-openssl-dev libxml2-dev libxslt1-dev python-lxml-----这是安装安装二进制包(直接在ubuntu的真实环境下安装),然后在进行pip install pyspider[all]命令来进行安装(在自己创建的虚拟环境下进行)。

2.项目部署

本文档基于MySQL + Redis(此项目所用的工具)

(1)config.json

尽管可以使用命令行指定参数。配置文件是更好的选择。

{
  "taskdb": "mysql+taskdb://username:password@host:port/taskdb",#username代表登录数据库的用户名,password是登录密码,host是数据库在主机上的ip地址,port是数据库端口号,taskdb是使用的数据库名。
  "projectdb": "mysql+projectdb://username:password@host:port/projectdb",
  "resultdb": "mysql+resultdb://username:password@host:port/resultdb",
  "message_queue": "redis://host:6379/db",
  "webui": {
    "username": "some_name",
    "password": "some_passwd",
    "need-auth": true
  }
}

通过运行pyspide --helppyspider webui --help,您可以获得完整的子命令选项。“webui”在JSON中是子命令的配置。您可以为其他类似的组件添加参数。

(2)Database Connection URI

“taskdb”“projectdb”“resultdb”使用数据库连接URI,格式如下:

mysql:
    mysql+type://user:passwd@host:port/database
sqlite:
    # relative path
    sqlite+type:///path/to/database.db
    # absolute path
    sqlite+type:////path/to/database.db
    # memory database
    sqlite+type://
mongodb:
    mongodb+type://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
    more: http://docs.mongodb.org/manual/reference/connection-string/
sqlalchemy:
    sqlalchemy+postgresql+type://user:passwd@host:port/database
    sqlalchemy+mysql+mysqlconnector+type://user:passwd@host:port/database
    more: http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html
local:
    local+projectdb://filepath,filepath

type:
    should be one of `taskdb`, `projectdb`, `resultdb`.
(3) Message Queue URL

您可以使用连接URL指定消息队列:

rabbitmq:
    amqp://username:password@host:5672/%2F
    Refer: https://www.rabbitmq.com/uri-spec.html
beanstalk:
    beanstalk://host:11300/
redis:
    redis://host:6379/db
    redis://host1:port1,host2:port2,...,hostn:portn (for redis 3.x in cluster mode)
builtin:
    None

提示:您需要创建自己编码utf8的数据库。pyspider不会自动为您创建数据库。创建数据库和相应的表之后,进行config.json文件配置。最后运行,在webui界面上创建自己的项目。

3.running

您应该使用子命令单独运行组件。您可以在命令后添加&使其在后台运行,并使用screen或nohup来防止ssh会话结束后退出。建议使用Supervisor管理组件。

# start **only one** scheduler instance
pyspider -c config.json scheduler

# phantomjs
pyspider -c config.json phantomjs

# start fetcher / processor / result_worker instances as many as your needs
pyspider -c config.json --phantomjs-proxy="localhost:25555" fetcher
pyspider -c config.json processor
pyspider -c config.json result-worker

# start webui, set `--scheduler-rpc` if scheduler is not running on the same host as webui
pyspider -c config.json webui
create table scrapydoc (
id int primary key auto_increment,
title varchar(128),
url varchar(256) unique,
html mediumblob,
content mediumblob,
`index` int
);#这是创建在结果数据库中表,来记录需要的信息。

注意:当运行出现ImportError: No module named mysql.connector的时候,解决文档如下:https://segmentfault.com/q/1010000006507996/a-1020000006603879(对于这个错误就是就是直接pip install mysql-connector);如果还出现ImportError: No module named redis的话,解决文档如下:(就是直接pip install redis即可)https://blog.csdn.net/hq86937375/article/details/86609939

二、案例

爬取scrapy文档小案例

1.数据库的表设计:

create table res_scrapydoc (
id int primary key auto_increment,
title varchar(128),
url varchar(256) unique,
html mediumblob,
content mediumblob,
`index` int  "为每个爬取的url添加一个序号,以便区别,
但是数据库中不一定按顺序显示,因为每个url爬取的优先级不同"
);

注意:表名的取名不要和项目名一样上面这个表放到结果数据库中。(对于pyspider框架要在数据库中设置3个数据库)

2. 脚本代码如下

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2019-06-19 12:19:32
# Project: scrapydoc

from pyspider.libs.base_handler import *


class Handler(BaseHandler):
    crawl_config = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 \
            (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36',
        'itag': '1.5',
        'etag': False,
        'last_modified': False
    }#这里是全局配置,在这里写相当于在所有的crawl中进行相应的设置。

    @every(minutes=24 * 60)
    def on_start(self):
        self.crawl('https://docs.scrapy.org/en/latest/index.html', callback=self.index_page)

    @config(age=10 * 24 * 60 * 60)
    def index_page(self, response):
        #解析出所有的标题url
        urls = response.etree.xpath('//div[@class="wy-menu wy-menu-vertical"]//li/a/@href')
        urls = ['%s%s'%('https://docs.scrapy.org/en/latest/',x) for x in urls]
        #print(urls)
        title = response.etree.xpath('//div[@id="scrapy-version-documentation"]/h1/text()')[0]
        #print(title)
        html = response.text#如果是中文,要进行编码设置。
        content = response.etree.xpath('string(//div[@itemprop="articleBody"])')#加string是获取内容,不加则是一个内容对象。
        #print(content)
        #产生新的任务
        for index, url in enumerate(urls):
            self.crawl(url, callback=self.detail_page, save={'index': index+1})
        return {
            'title': title,
            'html': html,
            'content': content,
            'url': response.url,
            'index': 0
        }

    @config(priority=2)
    def detail_page(self, response):
        title = response.etree.xpath('//div[@itemprop="articleBody"]//h1/text()')[0]
        print(title)
        html = response.text
        content = response.etree.xpath('string(//div[@class="wy-grid-for-nav"]//div[@class="section"])')
        print(content)
        return {
            "url": response.url,
            "title": title,
            "content": content,
            "html": html,
            "index": response.save['index']
        }

3. 自己编写的继承ResultWorker的py文件代码如下(这里创建的是my_resultworker.py文件)

from pyspider.result import ResultWorker


class MyResultworker(ResultWorker):
    def on_result(self, task, result):
        if not result:
            return
        #放我们要存的数据
        #可以写我们自己的接口
        self.resultdb._replace(tablename='res_scrapydoc', **self.resultdb._stringify(result))

        # self.resultdb.dbcur.execute('insert into scrapydoc (`title`, `url`, `html`, `content`, `index`) values (%s, %s, %s, %s, %s)', (result['title'], result['url'], result['html'], result['content'], result['index']))
        #调用父类的方法,使用webui界面查看
        super().on_result(task, {'title': result['title']})



4. config.json文件代码如下

{
  "taskdb": "mysql+taskdb://admin:Root110qwe@192.168.212.131:3306/ps_task",
  "projectdb": "mysql+projectdb://admin:Root110qwe@192.168.212.131:3306/ps_project",
  "resultdb": "mysql+resultdb://admin:Root110qwe@192.168.212.131:3306/ps_result",
  "message_queue": "redis://192.168.212.131:6379/0",
  "webui": {
    "username": "admin",
    "password": "admin",
    "need-auth": true
  },
  "result_worker": {
    "result_cls": "my_resultworker.MyResultworker"
  }#将my_resultworker.py中的MyResultworker注册打这个文件中
}

注意:对于做以上的项目案例步骤是
(1)首先写三个数据库,对于结果数据库创建一个接受结果数据的数据表,但是这个表不能和项目名重名。
(2)进行配置config.json文件
(3)编写爬取相应网站的脚本代码
(4)写完脚本代码后,return后面的结果会存储到ResultWorker里面,所以这里根据自己的需求来写自己的一个类,但这个类必须继承ResultWorker
(5)将自己接受结果的类进行注册(在config.json文件中注册)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容

  • 前言 pyspider是支持WebUI的,支持任务监控,项目管理,以及多种数据库的一个强大的爬虫框架,这个真的很好...
    Wangthirteen阅读 58,057评论 -1 22
  • PySpider 简介 PySpider是一个国人编写的强大的网络爬虫系统并带有强大的WebUI。采用Python...
    米扑阅读 2,711评论 1 4
  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    小迈克阅读 2,984评论 1 3
  • 一、为什么要使用pyspider? 我们很好奇,我们明明有了Scrapy框架,为什么还要使用pyspider框架呢...
    田小田txt阅读 1,127评论 0 0
  • 今日得闲,睡了半日,看了半部歌剧魅影,整理了一半手机内存,和好友聊了一个半多小时,散步半小时,没有画画,没有练习英...
    timeflies12阅读 186评论 0 0