如何评价scrapinghub这个云黑爬虫能查到什么平台平台?

Scrapyd部署爬虫项目
API 文档:
1、新建虚拟环境(方便管理),并在虚拟环境中安装scrapy项目需要使用到的包。
创建虚拟环境:
python3 -m venv scrapySpider
查找:which python
激活虚拟环境: 
source scrapySpider/bin/activate
删除虚拟环境: rm -rf venv
2、安装scrapyd模块,scrapyd模块是专门用于部署scrapy项目的,可以部署和管理scrapy项目。
pip install scrapyd
3、输入scrapyd启动scrapyd服务、浏览器输入127.0.0.1:6800 即可查看。
远程连接需要修改
所以这个时候就要改一下scrapyd配置*\Lib\site-packages\scrapyd中的default_scrapyd.conf:
将bind_address = 127.0.0.1改为bind_address = 0.0.0.0
4、如果连接成功先关闭服务,可以看到此时虚拟环境中多出了一个dbs文件夹,是用来存放爬虫项目的数据文件。
5、安装scrapyd-client模块。
Scrapyd-Client:GitHub:
scrapyd-client模块是专门打包scrapy爬虫项目到scrapyd服务中的,
进入虚拟环境,执行命令pip install scrapyd-client,
安装完成后,在虚拟环境的scripts中会出现scrapyd-deploy无后缀文件,这个scrapyd-deploy无后缀文件是启动文件。
6、进入虚拟环境,进入到你的爬虫项目中,进入带有scrapy.cfg文件的目录,执行scrapyd-deploy,测试scrapyd-deploy是否可以运行,如果出现以下则正常
7、打开爬虫项目中的scrapy.cfg文件,这个文件就是给scrapyd-deploy使用的,将url这行代码解掉注释,并且设置你的部署名称。
8、再次执行scrapyd-deploy -l 启动服务,可以看到设置的名称.
9、开始打包前,执行一个命令:scrapy list
,这个命令执行成功说明可以打包了,如果没执行成功说明还有工作没完成。
10、执行打包命令: scrapyd-deploy 部署名称 -p 项目名称
如:scrapyd-deploy bk -p baike
不用管,多提交几次,直到你的egg文件夹中有项目即可
11、部署scrapy
curl http://localhost:6800/schedule.json
-d project=项目名称 -d spider=爬虫名称
curl http://localhost:6800/schedule.json
-d project=baike -d spider=mybaike
可以去网页中127.0.0.1::6800查看爬虫运行状态
12、停止爬虫
curl http://localhost:6800/cancel.json
-d project=项目名称 -d job=运行ID
13、删除scrapy项目
注意:一般删除scrapy项目,需要先执行命令停止项目下已在远行的爬虫
curl http://localhost:6800/delproject.json -d project=scrapy项目名称
14、查看有多少个scrapy项目在api中
curl http:
15、查看指定的scrapy项目中有多少个爬虫
curl http://localhost:6800/listspiders.json?project=项目名称
16、如果我们想用 Python 程序来控制一下呢?我们还要用 requests 库一次次地请求这些 API ?这就太麻烦了吧,所以为了解决这个需求,Scrapyd-API 又出现了,
有了它我们可以只用简单的 Python 代码就可以实现 Scrapy 项目的监控和运行:
from scrapyd_api import ScrapydAPI
scrapyd = ScrapydAPI('http://localhost:6800')
scrapyd.list_jobs('project_name')
返回结果:
'pending': [
'running': [
'id': u'14a65...b27ce',
'spider': u'spider_name',
'start_time': u' 22:45:31.975358'
'finished': [
'id': '34c23...b21ba',
'spider': 'spider_name',
'start_time': ' 22:45:31.975358',
'end_time': ' 14:01:18.209680'
分布式爬虫管理框架Gerapy
是不是方便多了?
可是?真的达到最方便了吗?肯定没有!如果这一切的一切,从 Scrapy 的部署、启动到监控、日志查看,我们只需要鼠标键盘点几下就可以完成,那岂不是美滋滋?更或者说,连 Scrapy 代码都可以帮你自动生成,那岂不是爽爆了?
有需求就有动力,没错,Gerapy 就是为此而生的,GitHub:。
本节我们就来简单了解一下 Gerapy 分布式爬虫管理框架的使用方法。
Gerapy 是一款分布式爬虫管理框架,支持 Python 3,基于 Scrapy、Scrapyd、Scrapyd-Client、Scrapy-Redis、Scrapyd-API、Scrapy-Splash、Jinjia2、Django、Vue.js 开发,Gerapy 可以帮助我们:
更方便地控制爬虫运行
更直观地查看爬虫状态
更实时地查看爬取结果
更简单地实现项目部署
更统一地实现主机管理
更轻松地编写爬虫代码
安装非常简单,只需要运行 pip3 命令即可:
pip3 install gerapy
安装完成之后我们就可以使用 gerapy 命令了,输入 gerapy 便可以获取它的基本使用方法:
gerapy init [--folder=&]
gerapy migrate
gerapy createsuperuser
gerapy runserver [&]
gerapy makemigrations
如果出现上述结果,就证明 Gerapy 安装成功了。
接下来我们来开始使用 Gerapy,首先利用如下命令进行一下初始化,在任意路径下均可执行如下命令:
gerapy init
执行完毕之后,本地便会生成一个名字为 gerapy 的文件夹,接着进入该文件夹,可以看到有一个 projects 文件夹,我们后面会用到。
紧接着执行数据库初始化命令:
gerapy migrate
这样它就会在 gerapy 目录下生成一个 SQLite 数据库,同时建立数据库表。
接着我们只需要再运行命令启动服务就好了:
gerapy runserver
gerapy runserver
0.0.0.0:8000 【如果你是在本地,执行 gerapy runserver即可,如果你是在远程上,你就要改成前面这样来执行】
这样我们就可以看到 Gerapy 已经在 8000 端口上运行了。
全部的操作流程截图如下:
接下来我们在浏览器中打开 ,就可以看到 Gerapy 的主界面了:
这里显示了主机、项目的状态,当然由于我们没有添加主机,所以所有的数目都是 0。
如果我们可以正常访问这个页面,那就证明 Gerapy 初始化都成功了。
接下来我们可以点击左侧 Clients 选项卡,即主机管理页面,添加我们的 Scrapyd 远程服务,IP,端口为scrapyd端口,点击右上角的创建按钮即可添加我们需要管理的 Scrapyd 服务:
需要添加 IP、端口,以及名称,点击创建即可完成添加,点击返回即可看到当前添加的 Scrapyd 服务列表,样例如下所示:
这样我们可以在状态一栏看到各个 Scrapyd 服务是否可用,同时可以一目了然当前所有 Scrapyd 服务列表,另外我们还可以自由地进行编辑和删除。
如果你没有修改配置,应该这里会打不开,clients那里配置的时候,也应该会显示为error,就像这样:
所以这个时候就要改一下scrapyd配置*\Lib\site-packages\scrapyd中的default_scrapyd.conf:
将bind_address = 127.0.0.1改为bind_address = 0.0.0.0
Gerapy 的核心功能当然是项目管理,在这里我们可以自由地配置、编辑、部署我们的 Scrapy 项目,点击左侧的 Projects ,即项目管理选项,我们可以看到如下空白的页面:
假设现在我们有一个 Scrapy 项目,如果我们想要进行管理和部署,还记得初始化过程中提到的 projects 文件夹吗?这时我们只需要将项目拖动到刚才 gerapy 运行目录的 projects 文件夹下,例如我这里写好了一个 Scrapy 项目,名字叫做 baike,这时把它拖动到 projects 文件夹下:
这时刷新页面,我们便可以看到 Gerapy 检测到了这个项目,同时它是不可配置、没有打包的:
这时我们可以点击部署按钮进行打包和部署,在右下角我们可以输入打包时的描述信息,类似于 Git 的 commit 信息,然后点击打包按钮,即可发现 Gerapy 会提示打包成功,同时在左侧显示打包的结果和打包名称:
打包成功之后,我们便可以进行部署了,我们可以选择需要部署的主机,点击后方的部署按钮进行部署,同时也可以批量选择主机进行部署,示例如下:
可以发现此方法相比 Scrapyd-Client 的命令行式部署,简直不能方便更多。
部署完毕之后就可以回到主机管理页面进行任务调度了,任选一台主机,点击调度按钮即可进入任务管理页面,此页面可以查看当前 Scrapyd 服务的所有项目、所有爬虫及运行状态:
我们可以通过点击新任务、停止等按钮来实现任务的启动和停止等操作,同时也可以通过展开任务条目查看日志详情:
另外我们还可以随时点击停止按钮来取消 Scrapy 任务的运行。
这样我们就可以在此页面方便地管理每个 Scrapyd 服务上的 每个 Scrapy 项目的运行了。
同时 Gerapy 还支持项目编辑功能,有了它我们不再需要 IDE 即可完成项目的编写,我们点击项目的编辑按钮即可进入到编辑页面,如图所示:
这样即使 Gerapy 部署在远程的服务器上,我们不方便用 IDE 打开,也不喜欢用 Vim 等编辑软件,我们可以借助于本功能方便地完成代码的编写。
上述的项目主要针对的是我们已经写好的 Scrapy 项目,我们可以借助于 Gerapy 方便地完成编辑、部署、控制、监测等功能,而且这些项目的一些逻辑、配置都是已经写死在代码里面的,如果要修改的话,需要直接修改代码,即这些项目都是不可配置的。
在 Scrapy 中,其实提供了一个可配置化的爬虫 CrawlSpider,它可以利用一些规则来完成爬取规则和解析规则的配置,这样可配置化程度就非常高,这样我们只需要维护爬取规则、提取逻辑就可以了。如果要新增一个爬虫,我们只需要写好对应的规则即可,这类爬虫就叫做可配置化爬虫。
Gerapy 可以做到:我们写好爬虫规则,它帮我们自动生成 Scrapy 项目代码。
我们可以点击项目页面的右上角的创建按钮,增加一个可配置化爬虫,接着我们便可以在此处添加提取实体、爬取规则、抽取规则了,例如这里的解析器,我们可以配置解析成为哪个实体,每个字段使用怎样的解析方式,如 XPath 或 CSS 解析器、直接获取属性、直接添加值等多重方式,另外还可以指定处理器进行数据清洗,或直接指定正则表达式进行解析等等,通过这些流程我们可以做到任何字段的解析。
再比如爬取规则,我们可以指定从哪个链接开始爬取,允许爬取的域名是什么,该链接提取哪些跟进的链接,用什么解析方法来处理等等配置。通过这些配置,我们可以完成爬取规则的设置。
最后点击生成按钮即可完成代码的生成。
生成的代码示例结果其结构和 Scrapy 代码是完全一致的。
生成代码之后,我们只需要像上述流程一样,把项目进行部署、启动就好了,不需要我们写任何一行代码,即可完成爬虫的编写、部署、控制、监测。
以上便是 Gerapy 分布式爬虫管理框架的基本用法,如需了解更多,可以访问其
GitHub:。
Scrapyd部署项目爬虫
1. 新建虚拟环境(方便管理), 在虚拟环境中安装scrapy项目需要使用到的包.mkvirualenv --python=C:\python27\scripts\python.exe scrapyS...
阿里云服务器部署scrapy爬虫和apache2.4+php7.0+mysql5.7的配置
一.注册阿里云服务器
我购买的是云服务器ECS,一核CPU,2GB内存,ubuntu16.0.4 64位系统,学生价9.9一个月,注册过程我不多说,网上很多。但是有一点要注意,因为我用的是apache...
使用Scrapyd部署爬虫
为什么要用Scrapyd?
Scrapyd是scrapinghub官方提供的爬虫管理、部署、监控的方案之一,另一个是Scrapy Cloud。
官方对它的定义是
Scrapy Doc
Scrapyd部署爬虫项目
Scrapyd部署爬虫项目
1、新建虚拟环境(方便管理),在虚拟环境中安装scrapy项目需要使用到的包
mkvirtualenv--python=C:\python27\scripts\pytho...
ubuntu下scrapyd部署爬虫项目
Scrapyd是一个部署和运行Scrapy爬虫的应用程序。它使你能够通过JSON API部署(上传)工程,并且控制工程中的爬虫。scrapyd部署爬虫的优势:
1、方便监控爬虫的实时运行状态,也可以通...
Scrapy爬虫以及Scrapyd爬虫部署
Scrapy爬虫框架
Scrapyd爬虫部署服务
windows 下部署命令不识别的问题
开启scrapyd服务
centos系统下通过scrapyd部署python的scrapy
介绍续接上篇:Python网络爬虫使用总结,本篇记录下我学习用scrapyd部署scrapy程序的过程。感谢万能的互联网,感谢自己对python的这份喜爱。...
Scrapy笔记(9)- 部署
本篇主要介绍两种部署爬虫的方案。如果仅仅在开发调试的时候在本地部署跑起来是很容易的,不过要是生产环境,爬虫任务量大,并且持续时间长,那么还是建议使用专业的部署方法。主要是两种方案:
利用scrapyd管理scrapy的多个爬虫
说明:环境准备基于 Ubuntu16.04
sudo pip install scrapyd
sudo pip install scrapyd-client
二、验证命令...
scrapy-redis(七):部署scrapy
一般我们写好scrapy爬虫,如果需要启动的话,需要进入scrapy项目的根目录,然后运行以下命令:scrapy crawl {spidername}这样我们就可以在终端查看到爬虫信息了。但爬虫运行状...
没有更多推荐了,《Learning Scrapy》(中文版)第5章 快速构建爬虫 - 简书
《Learning Scrapy》(中文版)第5章 快速构建爬虫
第5章 快速构建爬虫
第3章中,我们学习了如何从网页提取信息并存储到Items中。大多数情况都可以用这一章的知识处理。本章,我们要进一步学习抓取流程UR2IM中两个R,Request和Response。
一个具有登录功能的爬虫
你常常需要从具有登录机制的网站抓取数据。多数时候,网站要你提供用户名和密码才能登录。我们的例子,你可以在或找到。用用户名“user”、密码“pass”登录之后,你会进入一个有三条房产链接的网页。现在的问题是,如何用Scrapy登录?
让我们使用谷歌Chrome浏览器的开发者工具搞清楚登录的机制。首先,选择Network标签(1)。然后,填入用户名和密码,点击Login(2)。如果用户名和密码是正确的,你会进入下一页。如果是错误的,会看到一个错误页。
一旦你点击了Login,在开发者工具的Network标签栏中,你就会看到一个发往的请求Request Method: POST。
提示:上一章的GET请求,通常用来获取静止数据,例如简单的网页和图片。POST请求通常用来获取的数据,取决于我们发给服务器的数据,例如这个例子中的用户名和密码。
点击这个POST请求,你就可以看到发给服务器的数据,其中包括表单信息,表单信息中有你刚才输入的用户名和密码。所有数据都以文本的形式发给服务器。Chrome开发者工具将它们整理好并展示出来。服务器的响应是302 FOUND(5),然后将我们重定向到新页面:/dynamic/gated。只有登录成功时才会出现此页面。如果没有正确输入用户名和密码就前往,服务器会发现你作弊,并将你重定向到错误页面:。服务器怎么知道你和密码呢?如果你点击左侧的gated(6),你会发现在RequestHeaders(7)下有一个Cookie(8)。
提示:HTTP cookie是通常是一些服务器发送到浏览器的短文本或数字片段。反过来,在每一个后续请求中,浏览器把它发送回服务器,以确定你、用户和期限。这让你可以执行复杂的需要服务器端状态信息的操作,如你购物车中的商品或你的用户名和密码。
总结一下,单单一个操作,如登录,可能涉及多个服务器往返操作,包括POST请求和HTTP重定向。Scrapy处理大多数这些操作是自动的,我们需要编写的代码很简单。
我们将第3章名为easy的爬虫重命名为login,并修改里面名字的属性,如下:
class LoginSpider(CrawlSpider):
name = 'login'
提示:本章的代码github的ch05目录中。这个例子位于ch05/properties。
我们要在上面模拟一个POST请求登录。我们用Scrapy中的类FormRequest来做。这个类和第3章中的Request很像,但有一个额外的formdata,用来传递参数。要使用这个类,首先必须要引入:
from scrapy.http import FormRequest
我们然后将start_URL替换为start_requests()方法。这么做是因为在本例中,比起URL,我们要做一些自定义的工作。更具体地,用下面的函数,我们创建并返回一个FormRequest:
# Start with a login request
def start_requests(self):
FormRequest(
"http://web:9312/dynamic/login",
formdata={"user": "user", "pass": "pass"}
就是这样。CrawlSpider的默认parse()方法,即LoginSpider的基本类,负责处理响应,并如第3章中使用Rules和LinkExtractors。其余的代码很少,因为Scrapy负责了cookies,当我们登录时,Scrapy将cookies传递给后续请求,与浏览器的方式相同。还是用scrapy crawl运行:
$ scrapy crawl login
INFO: Scrapy 1.0.3 started (bot: properties)
DEBUG: Redirecting (302) to &GET .../gated& from &POST .../login &
DEBUG: Crawled (200) &GET .../data.php&
DEBUG: Crawled (200) &GET .../property_000001.html& (referer: .../data.
DEBUG: Scraped from &200 .../property_000001.html&
{'address': [u'Plaistow, London'],
'date': [datetime.datetime(, 12, 7, 27, 120119)],
'description': [u'features'],
'image_URL': [u'http://web:9312/images/i02.jpg'],
INFO: Closing spider (finished)
INFO: Dumping Scrapy stats:
'downloader/request_method_count/GET': 4,
'downloader/request_method_count/POST': 1,
'item_scraped_count': 3,
我们注意到登录跳转从dynamic/login到dynamic/gated,然后就可以像之前一样抓取项目。在统计中,我们看到一个POST请求和四个GET请求;一个是dynamic/gated首页,三个是房产网页。
提示:在本例中,我们不保护房产页,而是是这些网页的链接。代码在相反的情况下也是相同的。
如果我们使用了错误的用户名和密码,我们将重定向到一个没有URL的页面,进程并将在这里结束,如下所示:
$ scrapy crawl login
INFO: Scrapy 1.0.3 started (bot: properties)
DEBUG: Redirecting (302) to &GET .../dynamic/error & from &POST .../
dynamic/login&
DEBUG: Crawled (200) &GET .../dynamic/error&
INFO: Spider closed (closespider_itemcount)
这是一个简单的登录示例,演示了基本的登录机制。大多数网站可能有更复杂的机制,但Scrapy也处理的很好。例如一些网站在执行POST请求时,需要通过从表单页面到登录页面传递某种形式的变量以确定cookies的启用,让你使用大量用户名和密码暴力破解时变得困难。
例如,如果你访问,你会看到一个和之前一样的网页,但如果你使用Chrome开发者工具,你会发现这个页面的表单有一个叫做nonce的隐藏字段。当你提交表单时,你必须既要提供正确的用户名密码,还要提交正确的浏览器发给你的nonce值。因为这个值是随机且只能使用一次,你很难猜到。这意味着,如果要成功登陆,必须要进行两次请求。你必须访问表单、登录页,然后传递数值。和以前一样,Scrapy有内建的功能可以解决这个问题。
我们创建一个和之前相似的NonceLoginSpider爬虫。现在,在start_requests()中,我们要向表单页返回一个简单的Request,并通过设定callback为名字是parse_welcome()的方法手动处理响应。在parse_welcome()中,我们使用FormRequest对象中的from_response()方法创建FormRequest,并将原始表单中的字段和值导入FormRequest。FormRequest.from_response()可以模拟提交表单。
提示:花时间看from_response()的文档是十分值得的。他有许多有用的功能如formname和formnumber,它可以帮助你当页面有多个表单时,选择特定的表单。
它最大的功能是,一字不差地包含了表单中所有的隐藏字段。我们只需使用formdata参数,填入user和pass字段,并返回FormRequest。代码如下:
# Start on the welcome page
def start_requests(self):
"http://web:9312/dynamic/nonce",
callback=self.parse_welcome)
# Post welcome page's first form with the given user/pass
def parse_welcome(self, response):
return FormRequest.from_response(
formdata={"user": "user", "pass": "pass"}
像之前一样运行爬虫:
$ scrapy crawl noncelogin
INFO: Scrapy 1.0.3 started (bot: properties)
DEBUG: Crawled (200) &GET .../dynamic/nonce&
DEBUG: Redirecting (302) to &GET .../dynamic/gated & from &POST .../
dynamic/login-nonce&
DEBUG: Crawled (200) &GET .../dynamic/gated&
INFO: Dumping Scrapy stats:
'downloader/request_method_count/GET': 5,
'downloader/request_method_count/POST': 1,
'item_scraped_count': 3,
我们看到第一个GET请求先到/dynamic/nonce,然后POST,重定向到/dynamic/nonce-login之后,之后像之前一样,访问了/dynamic/gated。登录过程结束。这个例子的登录含有两步。只要有足够的耐心,无论多少步的登录过程,都可以完成。
使用JSON APIs和AJAX页面的爬虫
有时,你会发现网页的HTML找不到数据。例如,在页面上右键点击检查元素(1,2),你就可以在DOM树种看到所有HTML元素。或者,如果你使用scrapy shell或在Chrome中右键点击查看网页源代码(3,4),你会看到这个网页的HTML代码不包含任何和值有关的信息。数据都是从何而来呢?
和以前一样,在开发者工具中打开Network标签(5)查看发生了什么。左侧列表中,可以看到所有的请求。在这个简单的页面中,只有三个请求:static/我们已经检查过了,jquery.min.js是一个流行的JavaScript框架,api.json看起来不同。如果我们点击它(6),然后在右侧点击Preview标签(7),我们可以看到它包含我们要找的信息。事实上,包含IDs和名字(8),如下所示:
"title": "better set unique family well"
"title": "better portered mile"
这是一个很简单的JSON API例子。更复杂的APIs可能要求你登录,使用POST请求,或返回某种数据结结构。任何时候,JSON都是最容易解析的格式,因为不需要XPath表达式就可以提取信息。
Python提供了一个强大的JSON解析库。当我们import json时,我们可以使用json.loads(response.body)解析JSON,并转换成等价的Python对象,语句、列表和字典。
复制第3章中的manual.py文件。这是最好的方法,因为我们要根据JSON对象中的IDs手动创建URL和Request。将这个文件重命名为api.py,重命名类为ApiSpider、名字是api。新的start_URL变成:
start_URL = (
'http://web:9312/properties/api.json',
如果你要做POST请求或更复杂的操作,你可以使用start_requests()方法和前面几章介绍的方法。这里,Scrapy会打开这个URL并使用Response作为参数调用parse()方法。我们可以import json,使用下面的代码解析JSON:
def parse(self, response):
base_url = "http://web:9312/properties/"
js = json.loads(response.body)
for item in js:
id = item["id"]
url = base_url + "property_%06d.html" % id
yield Request(url, callback=self.parse_item)
这段代码使用了json.loads(response.body)将响应JSON对象转换为Python列表,然后重复这个过程。对于列表中的每个项,我们设置一个URL,它包含:base_url,property_%06d和.html.base_url,.html.base_url前面定义过的URL前缀。%06d是一个非常有用的Python词,可以让我们结合多个Python变量形成一个新的字符串。在本例中,用id变量替换%06d。id被当做数字(%d的意思就是当做数字进行处理),并扩展成6个字符,位数不够时前面添加0。如果id的值是5,%06d会被替换为000005;id是34322时,%06d会被替换为034322替换。最后的结果是可用的URL。和第3章中的yield一样,我们用URL做一个新的Request请求。运行爬虫:
$ scrapy crawl api
INFO: Scrapy 1.0.3 started (bot: properties)
DEBUG: Crawled (200) &GET ...properties/api.json&
DEBUG: Crawled (200) &GET .../property_000029.html&
INFO: Closing spider (finished)
INFO: Dumping Scrapy stats:
'downloader/request_count': 31, ...
'item_scraped_count': 30,
最后一共有31次请求,每个项目一次,api.json一次。
在响应间传递参数
许多时候,你想把JSON APIs中的信息存储到Item中。为了演示,在我们的例子中,对于一个项,JSON API在返回它的名字时,在前面加上“better”。例如,如果一个项的名字时“Covent Garden”,API会返回“Better Covent Garden”。我们要在Items中保存这些含有“bette”的名字。如何将数据从parse()传递到parse_item()中呢?
我们要做的就是在parse()方法产生的Request中进行设置。然后,我们可以从parse_item()的的Response中取回。Request有一个名为meta的字典,在Response中可以直接访问。对于我们的例子,给字典设一个title值以存储从JSON对象的返回值:
title = item["title"]
yield Request(url, meta={"title": title},callback=self.parse_item)
在parse_item()中,我们可以使用这个值,而不用XPath表达式:
l.add_value('title', response.meta['title'],
MapCompose(unicode.strip, unicode.title))
你会注意到,我们从调用add_xpath()切换到add_value(),因为对于这个字段不需要使用XPath。我们现在运行爬虫,就可以在PropertyItems中看到api.json中的标题了。
一个加速30倍的项目爬虫
当你学习使用一个框架时,这个框架越复杂,你用它做任何事都会很复杂。可能你觉得Scrapy也是这样。当你就要为XPath和其他方法变得抓狂时,不妨停下来思考一下:我现在抓取网页的方法是最简单的吗?
如果你可以从索引页中提取相同的信息,就可以避免抓取每一个列表页,这样就可以节省大量的工作。
提示:许多网站的索引页提供的项目数量是不同的。例如,一个网站可以通过调整一个参数,例如&show=50,给每个索引页面设置10、 50或100个列表项。如果是这样的话,将其设置为可用的最大值。
例如,对于我们的例子,我们需要的所有信息都存在于索引页中,包括标题、描述、价格和图片。这意味着我们抓取单个索引页,提取30个条目和下一个索引页的链接。通过抓取100个索引页,我们得到3000个项,但只有100个请求而不是3000个。
在真实的Gumtree网站上,索引页的描述比列表页的完整描述要短。这是可行的,或者是更推荐的。
提示:许多情况下,您不得不在数据质量与请求数量间进行折衷。很多网站都限制请求数量(后面章节详解),所以减少请求可能解决另一个棘手的问题。
在我们的例子中,如果我们查看一个索引页的HTML,我们会发现,每个列表页有自己的节点,itemtype=""。节点有每个项的全部信息,如下所示:
让我们在Scrapy shell中加载索引首页,并用XPath处理:
$ scrapy shell http://web:9312/properties/index_00000.html
While within the Scrapy shell, let's try to select everything with the Product tag:
&&& p=response.xpath('//*[@itemtype="http://schema.org/Product"]')
&&& len(p)
[&Selector xpath='//*[@itemtype="http://schema.org/Product"]' data=u'&li
class="listing-maxi" itemscopeitemt'...]
我们得到了一个包含30个Selector对象的表,每个都指向一个列表。Selector对象和Response对象很像,我们可以用XPath表达式从它们指向的对象中提取信息。不同的是,表达式为有相关性的XPath表达式。相关性XPath表达式与我们之前见过的很像,不同之处是它们前面有一个点“.”。然我们看看如何用.//*[@itemprop="name"][1]/text()提取标题的:
&&& selector = p[3]
&&& selector
&Selector xpath='//*[@itemtype="http://schema.org/Product"]' ... '&
&&& selector.xpath('.//*[@itemprop="name"][1]/text()').extract()
[u'l fun broadband clean people brompton european']
我们可以在Selector对象表中用for循环提取一个索引页的所有30个项目信息。还是从第3章中的maunal.py文件开始,重命名为fast.py。重复使用大部分代码,修改parse()和parse_item()方法。更新的方法如下所示:
def parse(self, response):
# Get the next index URL and yield Requests
next_sel = response.xpath('//*[contains(@class,"next")]//@href')
for url in next_sel.extract():
yield Request(urlparse.urljoin(response.url, url))
# Iterate through products and create PropertiesItems
selectors = response.xpath(
'//*[@itemtype="http://schema.org/Product"]')
for selector in selectors:
yield self.parse_item(selector, response)
第一部分中用于产生下一条索引请求的代码没有变动。不同的地方是第二部分,我们重复使用选择器调用parse_item()方法,而不是用yield创建请求。这和原先使用的源代码很像:
def parse_item(self, selector, response):
# Create the loader using the selector
l = ItemLoader(item=PropertiesItem(), selector=selector)
# Load fields using XPath expressions
l.add_xpath('title', './/*[@itemprop="name"][1]/text()',
MapCompose(unicode.strip, unicode.title))
l.add_xpath('price', './/*[@itemprop="price"][1]/text()',
MapCompose(lambda i: i.replace(',', ''), float),
re='[,.0-9]+')
l.add_xpath('description',
'.//*[@itemprop="description"][1]/text()',
MapCompose(unicode.strip), Join())
l.add_xpath('address',
'.//*[@itemtype="http://schema.org/Place"]'
'[1]/*/text()',
MapCompose(unicode.strip))
make_url = lambda i: urlparse.urljoin(response.url, i)
l.add_xpath('image_URL', './/*[@itemprop="image"][1]/@src',
MapCompose(make_url))
# Housekeeping fields
l.add_xpath('url', './/*[@itemprop="url"][1]/@href',
MapCompose(make_url))
l.add_value('project', self.settings.get('BOT_NAME'))
l.add_value('spider', self.name)
l.add_value('server', socket.gethostname())
l.add_value('date', datetime.datetime.now())
return l.load_item()
我们做出的变动是:
ItemLoader现在使用selector作为源,不使用Response。这么做可以让ItemLoader更便捷,可以让我们从特定的区域而不是整个页面抓取信息。
通过在前面添加“.”使XPath表达式变为相关XPath。
提示:碰巧的是,在我们的例子中,XPath表达式在索引页和介绍页中是相同的。不同的时候,你需要按照索引页修改XPath表达式。
在response.url给我们列表页的URL之前,我们必须自己编辑Item的URL。然后,它才能返回我们抓取网页的URL。我们必须用.//*[@itemprop="url"][1]/@href提取URL,然后将它用MapCompose转化为URL绝对路径。
这些小小大量的工作的改动可以节省大量的工作。现在,用以下命令运行爬虫:
$ scrapy crawl fast -s CLOSESPIDER_PAGECOUNT=3
INFO: Dumping Scrapy stats:
'downloader/request_count': 3, ...
'item_scraped_count': 90,...
就像之前说的,我们用三个请求,就抓取了90个项目。不从索引开始的话,就要用93个请求。
如果你想用scrapy parse来调试,你需要如下设置spider参数:
$ scrapy parse --spider=fast http://web:9312/properties/index_00000.html
&&& STATUS DEPTH LEVEL 1 &&&
# Scraped Items
--------------------------------------------
[{'address': [u'Angel, London'],
... 30 items...
# Requests
---------------------------------------------------
[&GET http://web:9312/properties/index_00001.html&]
正如所料,parse()返回了30个Items和下一个索引页的请求。你还可以继续试验scrapy parse,例如,设置—depth=2。
可以抓取Excel文件的爬虫
大多数时候,你每抓取一个网站就使用一个爬虫,但如果要从多个网站抓取时,不同之处就是使用不同的XPath表达式。为每一个网站配置一个爬虫工作太大。能不能只使用一个爬虫呢?答案是可以。
新建一个项目抓取不同的东西。当前我们是在ch05的properties目录,向上一级:
/root/book/ch05/properties
/root/book/ch05
新建一个项目,命名为generic,再创建一个名为fromcsv的爬虫:
$ scrapy startproject generic
$ cd generic
$ scrapy genspider fromcsv example.com
新建一个.csv文件,它是我们抓取的目标。我们可以用Excel表建这个文件。如下表所示,填入URL和XPath表达式,在爬虫的目录中(有scrapy.cfg的文件夹)保存为todo.csv。保存格式是csv:
一切正常的话,就可以在终端看见这个文件:
$ cat todo.csv
url,name,price
a.html,"//*[@id=""itemTitle""]/text()","//*[@id=""prcIsum""]/text()"
b.html,//h1/text(),//span/strong/text()
c.html,"//*[@id=""product-desc""]/span/text()"
Python中有csv文件的内建库。只需import csv,就可以用后面的代码一行一行以dict的形式读取这个csv文件。在当前目录打开Python命令行,然后输入:
/root/book/ch05/generic2
&&& import csv
&&& with open("todo.csv", "rU") as f:
reader = csv.DictReader(f)
for line in reader:
print line
文件的第一行会被自动作为header,从而导出dict的键名。对于下面的每一行,我们得到一个包含数据的dict。用for循环执行每一行。前面代码的结果如下:
{'url': ' http://a.html', 'price': '//*[@id="prcIsum"]/text()', 'name': '//*[@id="itemTitle"]/text()'}
{'url': ' http://b.html', 'price': '//span/strong/text()', 'name': '//h1/text()'}
{'url': ' http://c.html', 'price': '', 'name': '//*[@id="product-desc"]/span/text()'}
很好。现在编辑generic/spiders/fromcsv.py爬虫。我们使用.csv文件中的URL,并且不希望遇到域名限制的情况。因此第一件事是移除start_URL和allowed_domains。然后再读.csv文件。
因为从文件中读取的URL是我们事先不了解的,所以使用一个start_requests()方法。对于每一行,我们都会创建Request。我们还要从request,meta的csv存储字段名和XPath,以便在我们的parse()函数中使用。然后,我们使用Item和ItemLoader填充Item的字段。下面是所有代码:
import csv
import scrapy
from scrapy.http import Request
from scrapy.loader import ItemLoader
from scrapy.item import Item, Field
class FromcsvSpider(scrapy.Spider):
name = "fromcsv"
def start_requests(self):
with open("todo.csv", "rU") as f:
reader = csv.DictReader(f)
for line in reader:
request = Request(line.pop('url'))
request.meta['fields'] = line
yield request
def parse(self, response):
item = Item()
l = ItemLoader(item=item, response=response)
for name, xpath in response.meta['fields'].iteritems():
item.fields[name] = Field()
l.add_xpath(name, xpath)
return l.load_item()
运行爬虫,输出文件保存为csv:
$ scrapy crawl fromcsv -o out.csv
INFO: Scrapy 0.0.3 started (bot: generic)
DEBUG: Scraped from &200 a.html&
{'name': [u'My item'], 'price': [u'128']}
DEBUG: Scraped from &200 b.html&
{'name': [u'Getting interesting'], 'price': [u'300']}
DEBUG: Scraped from &200 c.html&
{'name': [u'Buy this now']}
INFO: Spider closed (finished)
$ cat out.csv
price,name
128,My item
300,Getting interesting
,Buy this now
有几点要注意。项目中没有定义一个整个项目的Items,我们必须手动向ItemLoader提供一个:
item = Item()
l = ItemLoader(item=item, response=response)
我们还用Item的fields成员变量添加了动态字段。添加一个新的动态字段,并用ItemLoader填充,使用下面的方法:
item.fields[name] = Field()
l.add_xpath(name, xpath)
最后让代码再漂亮些。硬编码todo.csv不是很好。Scrapy提供了一种便捷的向爬虫传递参数的方法。如果我们使用-a参数,例如,-a variable=value,就创建了一个爬虫项,可以用self.variable取回。为了检查变量(没有的话,提供一个默认变量),我们使用Python的getattr()方法:getattr(self, 'variable', 'default')。总之,原来的with open…替换为:
with open(getattr(self, "file", "todo.csv"), "rU") as f:
现在,todo.csv是默认文件,除非使用参数-a,用一个源文件覆盖它。如果还有一个文件,another_todo.csv,我们可以运行:
$ scrapy crawl fromcsv -a file=another_todo.csv -o out.csv
在本章中,我们进一步学习了Scrapy爬虫。我们使用FormRequest进行登录,用请求/响应中的meta传递变量,使用了相关的XPath表达式和Selectors,使用.csv文件作为数据源等等。
接下来在第6章学习在Scrapinghub云部署爬虫,在第7章学习关于Scrapy的设置。
第5章 快速构建爬虫
&& 最近在看的书:
《图解数据结构·使用Python》
《数据科学家访谈录》
《利用Apache Flink进行流处理》
《Twisted网络编程精要》
&& 欢迎指出译稿和其它文章中的错误
(又忙起来了。。。)
&& 所有文章仅供个人学习不涉及商业利益
序言第1章 Scrapy介绍第2章 理解HTML和XPath第3章 爬虫基础第4章 从Scrapy到移动应用第5章 快速构建爬虫第6章 Scrapinghub部署第7章 配置和管理第8章 Scrapy编程第9章 使用Pipeline第10章 理解Scrapy的性能第11章(...
序言第1章 Scrapy介绍第2章 理解HTML和XPath第3章 爬虫基础 第4章 从Scrapy到移动应用第5章 快速构建爬虫第6章 Scrapinghub部署第7章 配置和管理第8章 Scrapy编程第9章 使用Pipeline第10章 理解Scrapy的性能第11章...
序言第1章 Scrapy介绍第2章 理解HTML和XPath第3章 爬虫基础 第4章 从Scrapy到移动应用第5章 快速构建爬虫第6章 Scrapinghub部署第7章 配置和管理第8章 Scrapy编程第9章 使用Pipeline第10章 理解Scrapy的性能第11章...
序言第1章 Scrapy介绍第2章 理解HTML和XPath第3章 爬虫基础 第4章 从Scrapy到移动应用第5章 快速构建爬虫第6章 Scrapinghub部署第7章 配置和管理第8章 Scrapy编程第9章 使用Pipeline第10章 理解Scrapy的性能第11章...
序言第1章 Scrapy介绍第2章 理解HTML和XPath第3章 爬虫基础 第4章 从Scrapy到移动应用第5章 快速构建爬虫第6章 Scrapinghub部署第7章 配置和管理第8章 Scrapy编程第9章 使用Pipeline第10章 理解Scrapy的性能第11章...
风声渐起,你在哪里。 你,黄胖子,会卖萌,会耍酷,你有一颗热情的心,可你不存在。 但我认识你之后,我与你之间产生了深深的羁绊。我发现我们难以分开。你成为了我的光之信仰。 你精神让我感动,20年的风雨成长让你坚毅,勇敢。你也成为我的榜样。 主题曲里的歌词成了我的座右铭:拿出勇...
好险,在地铁门关上的那一刹那,我还是跑进来了,只留下在原地气得跺脚的站务人员。我一直都想坐地铁体验一把,可就是没有机会。但我就是倔脾气,越不让我上,我就越要上,今晚终于让我逮着机会了。真是的,至于这么拦着我吗?我又不会干出什么坏事。 不过这会坐地铁的人还真是少啊,我进的正好...
给你提供一份完美的简历!高工资好待遇的工作!优秀毕业论文!这些大学老师都能帮你,最近太多关于老师的负面新闻,嗯,我来点正能量吧。 这篇文章就是在老师办公室有感而发,敲出来的,纯属个人干货。大家可能都觉得只有学霸才能抱得了老师大腿。并!不!是!这!样! 说起自己的大学老师,可...
我能想到最幸福的事,就是陪你讲故事、睡午觉。 早上醒来明明决定今天一定要出去走走逛逛,送你去爷爷奶奶家,逛了两三个小时就无比想你,又返回爷爷家接你回来。 你长大了,能交流沟通了,我就特别愿意哪都带上你,虽然你调皮捣蛋,会惹我生气,可我很爱你,舍不得离开你。
我是一家客栈的伙计。我会给每一位客人上一壶酒。 这是一家充满神秘的客栈,客栈名字很奇特,叫重楼。老板告诉我说是取"绝顶之上,更有重楼"之意。但我总觉得是在隐喻人心犹如鬼魅,永不餍足。 比店名更加神秘的是它的未知,它处在虚无缥缈的地方,只有在烟雨天气才会出现,只有漫无目的四处...

我要回帖

更多关于 黑爬虫能查到什么平台 的文章

 

随机推荐