Windows 10家庭中文版,Python 3.6.4,Scrapy 1.5.0,

在创建了爬虫程序后,就可以运行爬虫程序了。Scrapy中介绍了几种运行爬虫程序的方式,列举如下:

-命令行工具之scrapy runspider(全局命令)

-命令行工具之scrapy crawl(项目级命令)

-scrapy.crawler.CrawlerProcess

-scrapy.crawler.CrawlerRunner

注意,当系统中同时存在Python 2、Python 3时,孤的电脑直接执行scrapy命令使用的是Python 2,此时,需要在scrapy命令前添加“python3 -m”才可以使用Python 3,因此,请使用virtualenv建立虚拟环境运行scrapy等各种程序。

方式一:scrapy runspider命令(全局)

语法:scrapy runspider <spider_file.py>

还有一些配置项,可以使用scrapy runspider -h查看。

示例程序:文件名为baidu_com.py

 # -*- coding: utf-8 -*-
import scrapy class BaiduComSpider(scrapy.Spider):
name = 'baidu.com'
allowed_domains = ['www.baidu.com']
start_urls = ['https://www.baidu.com/'] def parse(self, response):
yield {
'title': response.xpath('//title/text()').extract_first()
}

parse函数使用response.xpath获取网页<title>的文本:

方式二:scrapy crawl(项目级)

crawl是项目级命令,因此只能在某个Scrapy项目中使用。那么,首先创建项目test070401:

使用tree命令查看创建的项目的结构:

刚刚创建的Scrapy项目的spiders目录中只有__init__.py文件,那么,将之前创建的baidu_com.py拷贝到此文件中:

现在,可以在项目test070401中使用crawl命令执行爬虫程序了。且慢,先看看crawl的语法:

scrapy crawl <spider>

注意,是<spider>而不是runspider命令的<spider_file.py>,准确的说<spider>是一个 爬虫程序的名称——爬虫类里面的name属性(必须required,且在项目中具有唯一性unique)。

baidu_com.py里面的爬虫类的名称是什么呢?baidu.com

疑问:一个爬虫文件里面是否可以建立多个爬虫类呢?

那么,执行下面的命令即可运行baidu_com.py里面的爬虫程序了:

scrapy crawl baidu.com

{

很尴尬,第一次执行居然失败了,没找到!

严重怀疑是拷贝的问题,拷贝过来后 还需要做一些配置吧?配置在……settings.py里面看看!

参考其它在项目里面建立的爬虫程序,发现settings.py中没有其配置;spiders包下面的__init__.py文件呢?也没发现其配置!

噩耗!怎么办?应该是可以执行的啊!

晕~字母拼写错误:baidu.com 拼写成 badu.com!严重警告一次!

}

重新执行正确的命令:仍然没有获取到需要的数据,因为,robots协议的存在,程序被拒绝了!

警示:所以,抓取数据不一定会成功,因为还会被网站拒绝!但是,开发爬虫程序时,必须要遵循相应的道德(规范)!

更多思考:

可是,为何之前使用runspider抓取数据成功了呢?

再次使用runspider命令执行baidu_com.py:结果, 成功!

为何如此 区别对待呢?

检查两者启动时的scrapy.crawler发现了不同:其中的crawl命令里面包含ROBOTSTXT_OBEY为True,表明其遵守站点的robots.txt协议!

那么,测试中的站点的robots.txt是怎样的呢?它几乎拒绝了所有的爬虫程序——Disallow!当然,baidu.com本来就是爬虫了,怎么会允许其它爬虫爬取它呢?爬虫爬取爬虫,好奇怪!

当然,Scrapy项目是否遵守robots.txt协议,是可以在settings.py中配置的,请参考官文Settings

疑问:runspider、crawl命令是否可以执行多个爬虫程序呢?请测试!

------分割线------

学习Scrapy之初一直有一个困惑,爬虫程序只能使用命令行来执行吗?不能写程序来执行吗?当然可以!

直到看了官文 Common Practices,此文中还介绍了一点关于分布式爬取(Distributed crawls)的内容,但本篇博客不涉及。

方式三:CrawlerProcess

使用CrawlerProcess执行上面的baidu_com.py中的爬虫类,程序runcp.py如下:

 import scrapy
from scrapy.crawler import CrawlerProcess
from baidu_com import BaiduComSpider # 创建一个CrawlerProcess对象
process = CrawlerProcess() # 括号中可以添加参数 process.crawl(BaiduComSpider)
process.start()

执行程序runcp.py:成功,抓取到了需要的数据。

孤是在virtualenv中执行,所以,直接输入runrc.py就可以运行程序,否则,请使用python -m runrc.py

注意,上面的程序是在Scrapy项目外执行的,如果是在项目内执行,

-可以使用get_project_settings()函数获取项目的一个Settings实例作为CrawlerProcess的参数;

-传递给crawl(...)函数的可以是项目内爬虫程序的name属性的值;

疑问,在项目内执行时,是否可以 混合使用项目内外的爬虫程序执行呢?既使用项目内的,也可以通过导入使用项目外的。

疑问:

是否可以执行多个爬虫程序呢?按理说 可以;(实际上也是可以的,官文有介绍)

是否可以定时执行爬虫程序呢?按理说 可以;(本文未介绍)

关于第一个“执行多个”的问题,在官文 Common Practices中有介绍,示例如下(仍然是在Scrapy项目外):

 import scrapy
from scrapy.crawler import CrawlerProcess
from baidu_com import BaiduComSpider
from msn_com import MsnComSpider # 创建一个CrawlerProcess对象
process = CrawlerProcess() # 括号中可以添加参数 process.crawl(BaiduComSpider)
process.crawl(MsnComSpider)
process.start()

执行结果:不过,注意日志显示的抓取顺序和代码中相反。

方式四:CrawlerRunner

官文对CrawlerRunner有更详细的介绍,还涉及到Twisted模块中的Reactor、Deferred等,而孤对Twisted模块的用法还不熟悉,只是昨天看了Deferred的参考文档。

但是,本文的目的是使用CrawlerRunner来编写脚本运行爬虫程序,那么,关于Twisted可以稍候详细了解,需要精通

本节包括下面的程序(均为Scrapy项目外):

-运行单个爬虫程序

-运行多个爬虫程序

-使用inlineCallbacks的方式运行爬虫程序(多个)

运行单个爬虫程序

 from twisted.internet import reactor
import scrapy
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging
from baidu_com import BaiduComSpider # 必须执行下面的,否则命令行中没有数据输出,555,
configure_logging({'LOG_FORMAT': '%(levelname)s: %(message)s'}) # 创建一个CrawlerRunner对象
runner = CrawlerRunner() d = runner.crawl(BaiduComSpider) # 返回一个Twisted中的Deferred对象
d.addBoth(lambda _: reactor.stop()) # addBoth参考Derrerred的文档
reactor.run()

执行结果:获取数据成功,,不过,第一次执行什么也没有输出到命令行中,因为没有执行configure_logging,为何这样?

运行多个爬虫程序

 from twisted.internet import reactor
import scrapy
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging
from baidu_com import BaiduComSpider
from techmeme_com import TechmemeComSpider configure_logging() # 创建一个CrawlerRunner对象
runner = CrawlerRunner() runner.crawl(BaiduComSpider)
runner.crawl(TechmemeComSpider)
d = runner.join() # 在多线程编程中见到过此函数,这里是?
d.addBoth(lambda _: reactor.stop()) # addBoth参考Derrerred的文档
reactor.run()

执行结果:获取数据成功,不过,techmeme.com的抓取结果 没有“一瞬间”显示出来,而是延迟了2~3秒。

注意,其获取网页的顺序和程序中添加的一致,当然,也可能是因为延迟问题。

使用inlineCallbacks的方式运行爬虫程序(多个)

需要懂Twisted的Dererred才能理解的!孤目前懂了10%吧?程序如下:

 from twisted.internet import reactor, defer

 from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging from baidu_com import BaiduComSpider
from techmeme_com import TechmemeComSpider configure_logging() # 创建一个CrawlerRunner对象
runner = CrawlerRunner() # 关键点来了!
@defer.inlineCallbacks
def crawl():
yield runner.crawl(BaiduComSpider)
yield runner.crawl(TechmemeComSpider)
reactor.stop() # 调用crawl()
crawl() reactor.run()

执行结果:执行成功(就不展示截图了,和前面一个程序的结果一样)!

总结

通过本文,孤对运行爬虫程序的方式有了更全面的了解了,读者您呢?

不过会有些不足,那就是对Twisted的reactor、Deferred不了解,并且自己对Python的装饰器使用没有达到精通级别,所以,看到装饰器会有些发怵!

本文没有 定时执行爬虫程序 的方法,因为水平不足,不过,既然都能在程序执行了,那么,离完成 定时执行爬虫程序 的目标还远吗?

没有写 分布式爬虫 的问题,孤自己懂了再写呗!

在看Twisted的文档时会遇到很多“新东西”,这就是困难了,心中对自己的期望应该是——读一遍就可以了,自己很聪明,可是呢?自己不过是个不如想象中聪明的普通人,一遍,是远远不够的,要很多遍!同时结合多练习,这也是孤最近学习东西时发现的一个问题——把自己的学习能力“想象”的太厉害了,而当显示出现差距时,自己就会感觉挫折,产生负面情绪。不过,现在认识到这一点了,能更好地理解自己了,所以,不会觉得学不会,只是觉得一遍学不会而已,不会再对自己这个人产生怀疑。

对了,下面是Twisted的一些链接(学习Twisted还需要懂的异步、同步、阻塞、非阻塞IO,更别说Python的装饰器、协程等基础知识和最新的async/awati关键字的使用了):

Twisted官网

Introduction to Deferred

Deferred Reference

Reactor Overview

P.S.又写了一篇,感觉自己棒棒哒!幸亏吃了那个小蛋糕!~今天的笔记本电量消耗好快啊(5个半小时),剩余36%了!而且没带充电器!~

Scrapy:运行爬虫程序的方式的更多相关文章

  1. Scrapy框架-爬虫程序相关属性和方法汇总

    一.爬虫项目类相关属性 name:爬虫任务的名称 allowed_domains:允许访问的网站 start_urls: 如果没有指定url,就从该列表中读取url来生成第一个请求 custom_se ...

  2. Scrapy:创建爬虫程序的方式

    Windows 10家庭中文版,Python 3.6.4,Scrapy 1.5.0, 在Scrapy中,建立爬虫程序或项目的方式有两种(在孤读过Scrapy的大部分文档后): 1.继承官方Spider ...

  3. Python中四种运行其他程序的方式

    原文地址:http://blog.csdn.net/jerry_1126/article/details/46584179 在Python中,可以方便地使用os模块来运行其他脚本或者程序,这样就可以在 ...

  4. 编程语言类别;运行Python程序的方式;变量和常量;Python程序的垃圾回收机制;

    目录 编程语言分类 运行Python程序的两种方式 1.交互式 变量与常量 1.变量 2.常量 3.小整数池 垃圾回收机制 编程语言分类 编程语言分为: 1.机器语言:直接用二进制的0和1和计算机(C ...

  5. Python黑科技 | Python中四种运行其他程序的方式

    在Python中,可以方便地使用os模块来运行其他脚本或者程序,这样就可以在脚本中直接使用其他脚本或程序提供的功能,而不必再次编写实现该功能的代码.为了更好地控制运行的进程,可以使用win32proc ...

  6. linux下在root用户登陆状态下,以指定用户运行脚本程序实现方式

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAABKCAIAAACASdeXAAAEoUlEQVR4nO2dy7WlIBBFTYIoSIIkmD ...

  7. 使用Scrapy编写爬虫程序中遇到的问题及解决方案记录

    1.创建与域名不一致的Request时,请求会报错 解决方法:创建时Request时加上参数dont_filter=True 2.当遇到爬取失败(对方反爬检测或网络问题等)时,重试,做法为在解析res ...

  8. Scrapy实战:使用IDE工具运行爬虫

    一般我们运行爬虫程序都是使用命令行,比如:scrapy crwal sobook.不过这多少有些不方便,可以使用下面的方法使用IDE的方式运行爬虫 我这边使用的是pycharm软件,在pycharm里 ...

  9. 路由器逆向分析------在QEMU MIPS虚拟机上运行MIPS程序(ssh方式)

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/69652258 在QEMU MIPS虚拟机上运行MIPS程序--SSH方式 有关在u ...

随机推荐

  1. Linux中的防火墙----iptables

    防火墙,它是一种位于内部网络与外部网络之间的网络安全系统.一项信息安全的防护系统,依照特定的规则,允许或是限制传输的数据通过. 防火墙根据主要的功能可分为网络层防火墙.应用层防火墙.数据库防火墙. 网 ...

  2. python之冒泡排序

    重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.def Bubble_Sort(lists): ...

  3. Linux中cd test和cd /test以及类似命令的区别

    一.加“/”的区别 今天重拾Linux的学习!按照书上,在tmp下,创建文件夹,命令如下: mkdir -p /test1/test2 结果使用下面两行命令结果不同,就对是否加“/”有了疑问,就去百度 ...

  4. Linux及安全实践四——ELF文件格式分析

    Linux及安全实践四——ELF文件格式分析 一.ELF文件格式概述 1. ELF:是一种对象文件的格式,用于定义不同类型的对象文件中都放了什么东西.以及都以什么样的格式去放这些东西. 二.分析一个E ...

  5. keepalived使用nc命令检测udp端口

    keepalived支持的健康检测方式有:HTTP_GET|SSL_GET.TCP_CHECK.SMTP_CHECK.MISC_CHECK. 由于keepalived自身并不支持udp检测,有TCP_ ...

  6. java类加载详解

    1,类的加载过程: JVM将类加载过程分为三个步骤:装载(load),链接(link)和初始化(initialize),其中链接又分为三个步骤: 验证(varification),准备(Prepara ...

  7. PyCharm引入自定义类报错

    This inspection detects names that should resolve but don't. Due to dynamic dispatch and duck typing ...

  8. python 调用aiohttp

    1. aiohttp安装   pip3 install aiohttp 1.1. 基本请求用法 async with aiohttp.get('https://github.com') as r: a ...

  9. html中一些莫名的空格

    我们日常用编辑器编辑代码的时候,为了让代码的可读性更高,通常会有换行,空格或者tab键(bootstrap的规则中非常不建议这样做,不过为了方便,我还是比较习惯这样来缩进)的操作. 而这些也就造成了一 ...

  10. Java并发编程原理与实战二十:线程安全性问题简单总结

    一.出现线程安全性问题的条件 •在多线程的环境下 •必须有共享资源 •对共享资源进行非原子性操作   二.解决线程安全性问题的途径 •synchronized (偏向锁,轻量级锁,重量级锁) •vol ...