美文网首页
Scrapy爬虫以及Scrapyd爬虫部署

Scrapy爬虫以及Scrapyd爬虫部署

作者: 尽情的嘲笑我吧 | 来源:发表于2018-03-13 22:59 被阅读0次

    原文链接:http://blog.csdn.net/Marksinoberg/article/details/79546273

    [图片上传失败...(image-7a4563-1520953147513)]

    昨天用Shell配合Python做了一个离线的作业控制系统,功能是有了,但是拓展性着实有点差,对小脚本小工具来说效果还可以,但是对于大型的爬虫类以及需要灵活控制的项目,可能就不太适合了。

    毕设要做的课题已经确定是“网络爬虫程序”了,所以对爬虫的控制这一点是必不可少的,因此来总结一下今天学习的Scrapy以及Scrapyd。从开发,到部署一条龙的实现一下。

    既然是一条龙,那么就把整体的流程走一下,详见下文。

    环境

    我的编码环境如下:

    • OS: windows10
    • Python:Python3.6
    • Scrapy: Scrapy 1.5.0
    • Scrapyd: twistd (the Twisted Windows runner) 17.9.0

    具体的安装方式很简单,Python3.6自带了超好用的包管理工具pip,因此安装起来就很方便了。

    pip install scrapy
    # 如果已经安装了scrapy ,现在想升级的话也可以使用下面的命令
    #pip install scrapy --upgrade
    
    pip install scrapyd
    pip install scrapyd-client
    

    经过一段时间的等待,我们环境所依赖的应该就安装好了。

    Scrapy爬虫框架

    Scrapy有一个中文的Docs,讲的已经是很清晰了。需要参考细节的可以看看下面的链接 http://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/overview.html

    环境已经搭建好了,下面开始正式的编码。完成目标: 统计CSDN博客部分文章的信息(如标题,发表时间,浏览量,评论量等)

    创建项目

    随便找一个目录,就可以开始了。具体的命令如下:

    scrapy startproject csdn
    # 意思是使用scrapy自带的templates下的basic模板创建一个project名为csdn的爬虫项目
    

    创建完之后,我们会发现刚才的文件夹下多了一些文件,目录结构大致如下:

    E:\CODE\PYTHON\ENVS\SCRAPYLEARN\CODES\CSDN
    │  scrapy.cfg
    │
    └─csdn
        │  csdn.article.json
        │  items.py
        │  middlewares.py
        │  pipelines.py
        │  settings.py
        │  __init__.py
        │
        ├─spiders
        │  │  csdn_spider.py
        │  │  __init__.py
    
    
    

    scrapy.cfg文件以windows下的ini格式存储了我们的项目的配置信息,一般不怎么用改动,但是里面的信息很重要,这一点明确下还是比较好的。比如:

    
    [settings]
    default = csdn.settings
    
    [deploy]
    #url = http://localhost:6800/  # 部署爬虫项目的时候这个注释记得打开
    project = csdn
    

    剩下的文件,基本功能如下:

    settings.py # 爬虫细节配置,基本上默认的就够了。但是有些可能也要手动改下,比如ROBOT协议是否要遵守(默认遵守,我们也可以手动打开来无视这个“君子协议”)
    items.py    # 定义爬取目标的数据结构,注意是结构哈。拓展部分见文档,
    pipelines.py # 数据持久化的问题,具体是文件系统,数据库还是web存储服务商视具体情况而定
    middlewares.py # 中间件服务,对这个例子来说,用不到
    spider/ # 这个目录是我们要特别注意的,因为我们的爬虫代码的细节都要在这里面实现。
    
    

    创建爬虫

    因为今天我们要做的是关于CSDN文章的爬虫,所以这里为了见名之意,就起了个名为csdn_spider.py,这一步可以手动创建,也可以借助scrapy的genspider自命令来实现。后者实际上是使用的scrapy的自带的爬虫模板自动生成的。

    # 记得在爬虫的根目录(包含了scrapy.cfg文件的那层哈)
    scrapy genspider csdn
    

    具体的继承细节这类的直接看文档来的更清晰,这不再过多赘述,就直接贴代码了。

    import scrapy
    from csdn.items import CsdnItem
    
    
    class CsdnSpider(scrapy.Spider):
        name = "csdn"
        allowed_domains = ["csdn.net"]
    
        start_urls = ["http://blog.csdn.net/marksinoberg/"]
    
        def parse(self, response):
            # print(response.request)
            # //*[@id="papelist"]/div/nav/ul/li
            # urls = response.xpath('//*[@id="papelist"]/div/nav/ul/li')
            pageurls = response.xpath('//*[@id="papelist"]/div/nav/ul/li/a/@href').extract()
            for url in pageurls:
                pageurl = "http:" + url
                yield scrapy.Request(url=pageurl, callback=self.parse_out_article_url)
        
        def parse_out_article_url(self, response):
            # //*[@id="article_list"]/div[18]/div
            articleurls = response.xpath('//*[@id="article_list"]/div/div/h1/span/a/@href').extract()
            for url in articleurls:
                articleurl = "http:" + url
                yield scrapy.Request(articleurl, callback=self.parse_each_article)
        
        def parse_each_article(self, response):
            title = response.xpath("/html/head/title/text()").extract_first()
            postdate = response.xpath('//*[@id="article_details"]/div[2]/div[2]/span[1]/text()').extract_first()
            watches = response.xpath('//*[@id="article_details"]/div[2]/div[2]/span[2]/text()').extract_first()
            comments = response.xpath('//*[@id="article_details"]/div[2]/div[2]/span[3]/text()').extract()[1]
            # comments = response.xpath('//*[@id="article_details"]/div[2]/div[2]/span[3]/text()').extract[0]
            item = CsdnItem()
            item['title'] = title
            item['url'] = response.url
            item['postdate'] = postdate
            item['watches'] = watches
            item['comments'] = comments
            print(title + " | " + postdate  + " | " + watches  + " | " + comments)
            return item
    

    具体的思路就是,通过start_urls指定的URL。抓到页面后提取出里面的博客页码对应的链接(每一页里面都会有很多篇具体的文章)。对每一个页进行抓取,然后再对每一篇博客进行具体的解析。

    这里start_urls下只能看到5个页面(实际上是4个,CSDN的当前页没有链接,这一点没做处理,其实直接处理也是很方便的,受益于yield嘛,哈哈)。

    思路很清晰,但是要理解request和response的工作流程还是有点绕的。这里也简单描述下。
    scrapy 通过start_urls创建request对象,同时callback方法(默认是parse)会被作为一个参数传给Request构造方法,这样,底层完成Request后,将返回的response作为一个结果集传给callback方法,这样的异步处理,不仅方便而且不会阻塞,可谓是有很多好处。

    至此,爬虫已经编写完毕了。

    E:\Code\Python\envs\scrapylearn\codes\csdn\csdn>scrapy list
    csdn
    
    

    运行爬虫

    现在代码也已经编写完毕了。直接运行爬虫就好。运行爬虫有很多种方式。我们可以通过指定py爬虫文件的方式,或者爬虫名称的方式来运行刚才编写完毕的爬虫。

    # 需要进入到spider目录哈
    scrapy runspider csdn_spider.py
    
    scrapy crawl csdn # 会输出爬虫整个生命流程的所有输出,便于调试
    scrapy crawl csdn --nolog # 只打印爬虫内部的输出信息,不会有调试信息输出,看起来更加简洁。
    scrapy crawl --nolog csdn -o csdn.article.json # 将爬虫信息重定向输出到文件中
    

    这里我就以第二个命令作为示例吧。

    E:\Code\Python\envs\scrapylearn\codes\csdn\csdn>scrapy crawl --nolog csdn -o csdn.article.json
    类Flask实现前后端交互之代码聊天室 - CSDN博客 | 2017年06月01日 09:18:25 | 8308人阅读 | (4)
    冒泡排序核心教程 - CSDN博客 | 2015年09月26日 18:59:48 | 6886人阅读 | (0)
    选择排序 - CSDN博客 | 2015年09月26日 19:15:03 | 6545人阅读 | (0)
    Nodejs之静态资源处理 - CSDN博客 | 2017年06月04日 18:52:35 | 10003人阅读 | (0)
    Nodejs 实用工具集笔记 - CSDN博客 | 2017年06月03日 21:33:16 | 6841人阅读 | (0)
    Tkinter小结 界面+快捷键设置 - CSDN博客 | 2017年04月21日 17:41:03 | 7975人阅读 | (1)
    CSDN 博客备份工具 - CSDN博客 | 2017年04月29日 10:59:48 | 9393人阅读 | (15)
    Nginx 从零搭建 - CSDN博客 | 2017年05月04日 16:04:27 | 6086人阅读 | (0)
    pymongo 存取 - CSDN博客 | 2017年04月22日 14:23:23 | 10709人阅读 | (3)
    给自己看的Redis - CSDN博客 | 2017年05月09日 17:02:47 | 5828人阅读 | (1)
    Java 程序员 面试前必备知识 - CSDN博客 | 2017年04月18日 10:40:24 | 12288人阅读 | (12)
    语音聊天 - CSDN博客 | 2017年05月11日 16:17:14 | 8561人阅读 | (5)
    我的MongoDB坎坷之路 - CSDN博客 | 2016年12月06日 17:31:20 | 11056人阅读 | (7)
    处理音频--pyaudio - CSDN博客 | 2017年05月10日 20:05:15 | 10822人阅读 | (1)
    QQ空间 代码秒赞 - CSDN博客 | 2016年12月13日 15:42:00 | 8680人阅读 | (4)
    解决服务器上部署PHP程序异常 - CSDN博客 | 2016年12月13日 19:02:22 | 6749人阅读 | (0)
    抓取网易云音乐歌曲热门评论生成词云 - CSDN博客 | 2017年04月26日 17:34:09 | 26285人阅读 | (25)
    实时体重检测 - CSDN博客 | 2016年12月11日 15:19:43 | 7807人阅读 | (8)
    PHP 数据库连接池实现 - CSDN博客 | 2016年12月24日 12:52:02 | 18269人阅读 | (7)
    扫码登陆 之我见 - CSDN博客 | 2016年12月16日 13:53:12 | 10203人阅读 | (4)
    PHP 反射技术 - CSDN博客 | 2016年12月24日 15:12:10 | 6821人阅读 | (0)
    在线 PHP运行工具、数据库可控 - CSDN博客 | 2016年12月25日 14:41:58 | 8409人阅读 | (2)
    数据库模块模块 小扳手 - CSDN博客 | 2017年01月21日 23:14:41 | 5756人阅读 | (1)
    用微信 远程遥控 服务器 - CSDN博客 | 2017年01月08日 19:31:04 | 8596人阅读 | (5)
    网站访客 简易日志记录 - CSDN博客 | 2016年12月30日 19:52:46 | 8931人阅读 | (4)
    在线 Python运行工具 - CSDN博客 | 2016年12月26日 10:32:02 | 9654人阅读 | (2)
    代理IP 有效性检测 - CSDN博客 | 2017年01月07日 12:17:52 | 22830人阅读 | (1)
    PHP 伪静态 - CSDN博客 | 2017年01月28日 18:17:33 | 5484人阅读 | (0)
    php 处理 非法访问 - CSDN博客 | 2017年01月29日 21:50:23 | 6286人阅读 | (0)
    php拓展 包管理工具 - CSDN博客 | 2017年01月24日 14:33:21 | 6685人阅读 | (0)
    后台站点文件扫描 - CSDN博客 | 2017年02月03日 21:08:05 | 6746人阅读 | (0)
    PFSI 开源啦,欢迎您来贡献您的代码 - CSDN博客 | 2017年02月06日 15:51:58 | 7343人阅读 | (2)
    Apache 常识小札 - CSDN博客 | 2017年01月30日 21:58:07 | 5930人阅读 | (2)
    Markdown转HTML之Node篇 - CSDN博客 | 2017年06月06日 21:55:28 | 7984人阅读 | (0)
    easyui Basic CRUD Application 试水 - CSDN博客 | 2017年02月02日 16:46:54 | 6311人阅读 | (1)
    Nodejs-cli 填坑记 - CSDN博客 | 2017年06月12日 15:26:31 | 7579人阅读 | (3)
    命令行进度条实现 - CSDN博客 | 2017年06月19日 20:40:21 | 7007人阅读 | (0)
    打包发布自己的nodejs包 - CSDN博客 | 2017年06月13日 22:37:18 | 10486人阅读 | (2)
    技能雷达图 - CSDN博客 | 2017年06月22日 14:04:49 | 7563人阅读 | (9)
    ajax跨域问题解决方案 - CSDN博客 | 2017年06月20日 17:05:15 | 8014人阅读 | (1)
    一个不成熟的模板引擎思路 - CSDN博客 | 2017年06月13日 16:38:45 | 6521人阅读 | (1)
    Web访问控制 - CSDN博客 | 2017年07月13日 16:14:30 | 7380人阅读 | (9)
    tmux安装与使用 - CSDN博客 | 2017年08月03日 14:53:54 | 6568人阅读 | (1)
    在线考试实时拍照系统 - CSDN博客 | 2017年07月16日 23:00:59 | 8048人阅读 | (1)
    MySQL笔记之多表 - CSDN博客 | 2017年07月05日 15:04:04 | 6062人阅读 | (0)
    图片上传预览原理及实现 - CSDN博客 | 2017年07月10日 19:38:56 | 8972人阅读 | (3)
    Python自定义大小截屏 - CSDN博客 | 2017年07月24日 22:43:12 | 8182人阅读 | (9)
    图解VIM常用操作 - CSDN博客 | 2017年08月26日 14:01:12 | 7021人阅读 | (14)
    在偷懒的路上越走越远 - CSDN博客 | 2017年08月19日 12:15:16 | 5485人阅读 | (4)
    Nginx-一个IP配置多个站点 - CSDN博客 | 2017年09月03日 12:10:48 | 9190人阅读 | (3)
    ctags,cscope,nerdtree,tmux 笔记 - CSDN博客 | 2017年09月16日 16:37:20 | 8111人阅读 | (5)
    谈谈反爬虫“政策与对策” - CSDN博客 | 2017年10月07日 09:48:05 | 5473人阅读 | (10)
    我与阿里云的故事 - CSDN博客 | 2017年02月07日 21:07:56 | 6762人阅读 | (10)
    DWR3.0  服务器推送及解惑 - CSDN博客 | 2017年02月17日 10:42:59 | 7681人阅读 | (13)
    我的worktools集合们 - CSDN博客 | 2017年08月27日 13:03:24 | 5443人阅读 | (0)
    你这个requests啊 - CSDN博客 | 2017年09月21日 23:40:40 | 20902人阅读 | (2)
    网页全截图实现 - CSDN博客 | 2017年02月28日 20:48:31 | 6766人阅读 | (2)
    《提问的艺术》读后感 - CSDN博客 | 2017年02月25日 15:02:50 | 7055人阅读 | (1)
    重新认识 Sublime Text 3 - CSDN博客 | 2017年02月24日 17:45:38 | 6661人阅读 | (0)
    几个面试常考的问题 - CSDN博客 | 2017年03月05日 11:48:44 | 7180人阅读 | (1)
    懒人翻译 - CSDN博客 | 2017年03月17日 17:11:44 | 6570人阅读 | (3)
    SSH 搭建点滴 - CSDN博客 | 2017年03月15日 20:34:55 | 6577人阅读 | (5)
    认真对待 Python3 收邮件 - CSDN博客 | 2017年03月27日 12:01:34 | 12563人阅读 | (13)
    CI之旅 - CSDN博客 | 2017年03月30日 16:51:47 | 6024人阅读 | (0)
    Python 模拟登录知乎 - CSDN博客 | 2017年04月07日 17:03:51 | 11109人阅读 | (47)
    记 dotamax 面试第一题 - CSDN博客 | 2017年04月13日 19:17:00 | 6295人阅读 | (0)
    Python 实现一个全面的单链表 - CSDN博客 | 2017年04月05日 19:28:50 | 8121人阅读 | (2)
    Python 实现二叉树相关操作 - CSDN博客 | 2017年04月06日 20:58:12 | 6712人阅读 | (0)
    半自动化生成README.md文件 - CSDN博客 | 2017年04月14日 20:32:20 | 6355人阅读 | (0)
    2017 携程 笔试编程题 1 - CSDN博客 | 2017年04月11日 22:05:40 | 6828人阅读 | (2)
    Java String 真的是不可变的吗 - CSDN博客 | 2017年03月08日 15:52:44 | 7111人阅读 | (0)
    当模拟登陆遇到验证码 - CSDN博客 | 2017年04月09日 21:56:29 | 8348人阅读 | (2)
    “社交网络”分析 - CSDN博客 | 2017年05月18日 15:27:12 | 7940人阅读 | (6)
    关于站内搜索的那些事儿 - CSDN博客 | 2017年05月12日 13:10:37 | 8519人阅读 | (9)
    读《卓越程序员密码》有感 - CSDN博客 | 2017年05月21日 13:51:34 | 5734人阅读 | (1)
    知乎用户分布研究 - CSDN博客 | 2017年05月22日 15:36:45 | 7792人阅读 | (6)
    爬取微博用户数据 - CSDN博客 | 2017年05月21日 20:34:06 | 6584人阅读 | (1)
    Flask中的ORM使用 - CSDN博客 | 2017年05月24日 14:05:26 | 11903人阅读 | (1)
    Django应用部署 - CSDN博客 | 2017年05月30日 11:43:30 | 6290人阅读 | (0)
    装饰器实现路由控制 - CSDN博客 | 2017年05月30日 19:51:16 | 6125人阅读 | (0)
    
    

    至此,整个爬虫已经全部调试通过。至于xpath和css这些Selector,我个人建议还是看官方文档来得实惠。而且讲的也更加的清晰。

    Scrapyd爬虫部署服务

    windows 下部署命令不识别的问题

    下面进入第二个阶段,部署我们刚才已经完成的爬虫项目。安装好了scrapyd和scrapd-client后,我们可能会遇到scrapyd-deploy不是windows下的命令的问题。这是由于环境变量找不到导致的。
    解决办法也很简单。在python的安装目录下创建俩同名的bat批处理文件即可。

    [图片上传失败...(image-ccfd56-1520953147514)]

    开启scrapyd服务

    这样就可以正常使用部署爬虫的命令了。在部署爬虫之前,先开启scrapyd的服务。具体的命令如下:

    developer@aliyun~#scrapyd
    2018-03-13T21:54:45+0800 [-] Loading d:\software\python3\lib\site-packages\scrapyd\txapp.py...
    2018-03-13T21:54:46+0800 [-] Scrapyd web console available at http://127.0.0.1:6800/
    2018-03-13T21:54:46+0800 [-] Loaded.
    2018-03-13T21:54:46+0800 [twisted.application.app.AppLogger#info] twistd 17.9.0 (d:\software\python3\python.exe 3.6.0) starting up.
    2018-03-13T21:54:46+0800 [twisted.application.app.AppLogger#info] reactor class: twisted.internet.selectreactor.SelectReactor.
    2018-03-13T21:54:46+0800 [-] Site starting on 6800
    2018-03-13T21:54:46+0800 [twisted.web.server.Site#info] Starting factory <twisted.web.server.Site object at 0x0000019D2BDFC320>
    2018-03-13T21:54:46+0800 [Launcher] Scrapyd 1.2.0 started: max_proc=16, runner='scrapyd.runner'
    

    部署爬虫

    服务已经开启,这个时候要记得打开scrapy.cfg中的deploy的url参数。否则scrapy爬虫部署可能就失败了。

    [deploy:csdndeploy]
    url = http://localhost:6800/
    project = tutorial
    

    注意[deploy:csdndeploy] 的格式,意思是target为csdndeploy的部署配置。有其他的部署可以通过冒号后面的target名称进行单独设置。

    然后具体的部署命令是:

    E:\Code\Python\envs\scrapylearn\codes\csdn\csdn>scrapyd-deploy csdndeploy -p csdn
    Packing version 1520952421
    Deploying to project "csdn" in http://localhost:6800/addversion.json
    Server response (200):
    {"node_name": "DESKTOP-5U5QNB2", "status": "ok", "project": "csdn", "version": "1520952421", "spiders": 1}
    

    按照输出信息的提示,我们只需要访问http://localhost:6800/addversion.json 资源就可以看到具体的部署信息了。

    作业控制

    scrapyd的官方文档也是很详细,我们可以通过对schedule.json,cancle.json等资源来实现以HTTP服务的方式控制爬虫。具体的文档为http://scrapyd.readthedocs.io/en/latest/api.html

    比如下面的开启爬虫:

    $ curl http://localhost:6800/schedule.json -d project=csdn -d spider=csdn
    

    然后的下面的结果就说明已经成功开启了一个爬虫。

    biao@DESKTOP-5U5QNB2 MINGW64 /e/Code/Python/envs/scrapylearn/codes/csdn
    $ curl http://localhost:6800/schedule.json -d project=csdn -d spider=csdn
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   118  100    94  100    24     31      7  0:00:03  0:00:03 --:--:--    31{"node_name": "DESKTOP-5U5QNB2", "status": "ok", "jobid": "4b39330c26ce11e8834a74d02bba7257"}
    
    

    然后就可以看到具体的爬虫运行信息了。http://localhost:6800/jobs
    我这里的结果如下:
    [图片上传失败...(image-ae0004-1520953147514)]

    点击“Log”超链接,就可以看到爬虫的具体的输出信息了。
    [图片上传失败...(image-7ee05-1520953147514)]

    其他HTTP操作类似,就不再过多的赘述了。参考官方文档即可。

    总结

    上一篇文章写了制作一个离线的作业控制系统,而今天这里用到的scrapyd就是一个底层使用了twisted的集成了的IPC服务套件(注意即使是同一个spider,两次run也要放到不同的JOBDIR,具体可以参考文档),很方便。然而自己去实现的话,对这块的内容也会理解的更深刻。

    相关文章

      网友评论

          本文标题:Scrapy爬虫以及Scrapyd爬虫部署

          本文链接:https://www.haomeiwen.com/subject/dufxqftx.html