Scrapy:运行爬虫程序的方式
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关键字的使用了):
P.S.又写了一篇,感觉自己棒棒哒!幸亏吃了那个小蛋糕!~今天的笔记本电量消耗好快啊(5个半小时),剩余36%了!而且没带充电器!~
Scrapy:运行爬虫程序的方式的更多相关文章
- Scrapy框架-爬虫程序相关属性和方法汇总
一.爬虫项目类相关属性 name:爬虫任务的名称 allowed_domains:允许访问的网站 start_urls: 如果没有指定url,就从该列表中读取url来生成第一个请求 custom_se ...
- Scrapy:创建爬虫程序的方式
Windows 10家庭中文版,Python 3.6.4,Scrapy 1.5.0, 在Scrapy中,建立爬虫程序或项目的方式有两种(在孤读过Scrapy的大部分文档后): 1.继承官方Spider ...
- Python中四种运行其他程序的方式
原文地址:http://blog.csdn.net/jerry_1126/article/details/46584179 在Python中,可以方便地使用os模块来运行其他脚本或者程序,这样就可以在 ...
- 编程语言类别;运行Python程序的方式;变量和常量;Python程序的垃圾回收机制;
目录 编程语言分类 运行Python程序的两种方式 1.交互式 变量与常量 1.变量 2.常量 3.小整数池 垃圾回收机制 编程语言分类 编程语言分为: 1.机器语言:直接用二进制的0和1和计算机(C ...
- Python黑科技 | Python中四种运行其他程序的方式
在Python中,可以方便地使用os模块来运行其他脚本或者程序,这样就可以在脚本中直接使用其他脚本或程序提供的功能,而不必再次编写实现该功能的代码.为了更好地控制运行的进程,可以使用win32proc ...
- linux下在root用户登陆状态下,以指定用户运行脚本程序实现方式
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAABKCAIAAACASdeXAAAEoUlEQVR4nO2dy7WlIBBFTYIoSIIkmD ...
- 使用Scrapy编写爬虫程序中遇到的问题及解决方案记录
1.创建与域名不一致的Request时,请求会报错 解决方法:创建时Request时加上参数dont_filter=True 2.当遇到爬取失败(对方反爬检测或网络问题等)时,重试,做法为在解析res ...
- Scrapy实战:使用IDE工具运行爬虫
一般我们运行爬虫程序都是使用命令行,比如:scrapy crwal sobook.不过这多少有些不方便,可以使用下面的方法使用IDE的方式运行爬虫 我这边使用的是pycharm软件,在pycharm里 ...
- 路由器逆向分析------在QEMU MIPS虚拟机上运行MIPS程序(ssh方式)
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/69652258 在QEMU MIPS虚拟机上运行MIPS程序--SSH方式 有关在u ...
随机推荐
- BZOJ 2668: [cqoi2012]交换棋子
2668: [cqoi2012]交换棋子 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1112 Solved: 409[Submit][Status ...
- 浅谈Tarjan算法及思想
在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连 ...
- Min Cost Climbing Stairs - LeetCode
目录 题目链接 注意点 解法 小结 题目链接 Min Cost Climbing Stairs - LeetCode 注意点 注意边界条件 解法 解法一:这道题也是一道dp题.dp[i]表示爬到第i层 ...
- 【uoj33】 UR #2—树上GCD
http://uoj.ac/problem/33 (题目链接) 题意 给出一棵${n}$个节点的有根树,${f_{u,v}=gcd(dis(u,lca(u,v)),dis(v,lca(u,v)))}$ ...
- Paxos Made Simple【翻译】
Paxos一致性算法——分布式系统中的经典算法,论文本身也有一段有趣的故事.一致性问题是分布式系统的根本问题之一,在论文中,作者一步步的加强最初一致性问题(2.1节提出的问题)的约束条件,最终导出了一 ...
- 前端学习 -- 内联框架iframe
内联框架iframe 可以向一个页面中引入其他的外部页面 内联框架中的内容不会被搜索引擎所检索,所以开发中尽量不要使用内联框架 <iframe></iframe> 属性: sr ...
- 退出Android程序时清除所有activity的实现方法
思路: 1. 自定义ActivityList管理类,添加删除维护该list; 2.Activity Stack 类似上面: 3.singleTask定义一个Activity为该启动模式,然后当返回时, ...
- Java入门:JDK与Eclipse之类的集成开发工具的关系
JDK是Java Development Kit,也就是说Java开发所需的工具包.有了这个东西,一切Java开发理论上都不是问题了.当然,根据你下载的版本不同,可能擅长的领域不同.通常大家都是用JD ...
- 转:CocoaPods pod install/pod update更新慢的问题
最近使用CocoaPods来添加第三方类库,无论是执行pod install还是pod update都卡在了Analyzing dependencies不动 原因在于当执行以上两个命令的时候会升级Co ...
- CSS3 渐变,rgba与hsla
radial-gradient:径向渐变 ellipse:椭圆形渐变默认,circle:圆形渐变 定义渐变大小,指定终点位置: farthest-corner:默认,指定径向渐变的半径长度为:从圆心到 ...