Scrapy 简明教程

Scrapy - Quick Guide

Scrapy - Overview

Scrapy 是一个使用 Python 编写的高速、开放源代码 Web 爬取框架,它用于借助基于 XPath 的选择器从网页提取数据。

Scrapy 最初于 2008 年 6 月 26 日发布,并获得 BSD 许可,并在 2015 年 6 月发布了 1.0 里程碑版本。

Why Use Scrapy?

  1. 构建和扩展大型爬取项目更为轻松。

  2. 它具有一个内置机制,称为选择器,用于从网站中提取数据。

  3. 它以异步方式处理请求,且速度很快。

  4. 它使用 Auto-throttling mechanism 自动调整爬取速度。

  5. Ensures developer accessibility.

Features of Scrapy

  1. Scrapy 是一个开源且免费的 web 爬取框架。

  2. Scrapy 生成以 JSON、CSV 和 XML 等格式进行馈送导出的数据。

  3. Scrapy 内置了通过 XPath 或 CSS 表达式从来源中选择和提取数据的支持。

  4. 基于爬虫的 Scrapy 允许自动从网页中提取数据。

Advantages

  1. Scrapy 可轻松扩展、并且快速而强大。

  2. 它是一个跨平台应用程序框架(Windows、Linux、Mac OS 和 BSD)。

  3. Scrapy 请求已安排并且已异步处理。

  4. Scrapy 带有一个内置的服务,称为 Scrapyd ,该服务允许使用 JSON web 服务上传项目和控制爬取。

  5. 有可能爬取任何网站,即使该网站没有用于原始数据访问的 API。

Disadvantages

  1. Scrapy 仅适用于 Python 2.7。

  2. 安装对于不同的操作系统来说是不同的。

Scrapy - Environment

在本章中,我们将讨论如何安装和设置 Scrapy。Scrapy 必须与 Python 一起安装。

可以通过 pip 安装 Scrapy。要安装,运行以下命令 −

pip install Scrapy

Windows

Note - 在 Windows 操作系统上不支持 Python 3。

Step 1 - 从 Python 安装 Python 2.7

通过将以下路径添加到 PATH 来设置环境变量 −

C:\Python27\;C:\Python27\Scripts\;

你可以使用以下命令来检查 Python 版本 −

python --version

Step 2 - 安装 OpenSSL

在你的环境变量中添加 C:\OpenSSL-Win32\bin。

Note - OpenSSL 预装在除 Windows 以外的所有操作系统中。

Step 3 - 安装 Visual C++ 2008 再发行包。

Step 4 - 安装 pywin32

Step 5 - 为早于 2.7.9 的 Python 安装 pip

你可以使用下面的命令检查 pip 版本 -

pip --version

Step 6 - 要安装 scrapy,运行以下命令 -

pip install Scrapy

Anaconda

如果你计算机上已安装了 anacondaminiconda ,运行下面的命令使用 conda 安装 Scrapy -

conda install -c scrapinghub scrapy

Scrapinghub 公司支持 Linux、Windows 和 OS X 的官方 conda 包。

Note - 如果你在使用 pip 安装时遇到问题,建议通过上面的命令安装 Scrapy。

Ubuntu 9.10 or Above

最新版的 Python 已预先安装在 Ubuntu 操作系统上。使用由 Scrapinghub 提供的 Ubuntu 包 aptgettable。要使用这些包 -

Step 1 - 你需要将用于对 Scrapy 包进行签名的 GPG 密钥导入 APT 密钥环 -

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 627220E7

Step 2 - 接下来,使用下面的命令创建 /etc/apt/sources.list.d/scrapy.list 文件 -

echo 'deb http://archive.scrapy.org/ubuntu scrapy main' | sudo tee
/etc/apt/sources.list.d/scrapy.list

Step 3 - 更新包列表并安装 scrapy -

sudo apt-get update && sudo apt-get install scrapy

Archlinux

你可以使用下面的命令从 AUR Scrapy 包安装 Scrapy -

yaourt -S scrapy

Mac OS X

使用下面的命令安装 Xcode 命令行工具 -

xcode-select --install

安装一个新的更新版本而不是使用系统 Python,该版本不会与系统中的其他部分发生冲突。

Step 1 - 安装 homebrew

Step 2 - 设置环境 PATH 变量,以指定 homebrew 包应在系统包之前使用 -

echo "export PATH = /usr/local/bin:/usr/local/sbin:$PATH" >> ~/.bashrc

Step 3 - 要确保已经完成更改,使用以下命令重新加载 .bashrc -

source ~/.bashrc

Step 4 - 接下来,使用下面的命令安装 Python -

brew install python

Step 5 - 使用下面的命令安装 Scrapy -

pip install Scrapy

Scrapy - Command Line Tools

Description

Scrapy 命令行工具用于控制 Scrapy,通常称为 'Scrapy tool' 。它包括针对各个对象的一组参数和选项的命令。

Configuration Settings

Scrapy 会在 scrapy.cfg 文件中查找配置设定。以下是几个位置 −

  1. 系统中的 C:\scrapy(项目文件夹)\scrapy.cfg

  2. 全局设定的 ~/.config/scrapy.cfg($XDG_CONFIG_HOME)和 ~/.scrapy.cfg($HOME)

  3. 您可以在项目根目录内找到 scrapy.cfg。

Scrapy 还可以使用以下环境变量进行配置 −

  1. SCRAPY_SETTINGS_MODULE

  2. SCRAPY_PROJECT

  3. SCRAPY_PYTHON_SHELL

Default Structure Scrapy Project

以下结构展示了 Scrapy 项目的默认文件结构。

scrapy.cfg                - Deploy the configuration file
project_name/             - Name of the project
   _init_.py
   items.py               - It is project's items file
   pipelines.py           - It is project's pipelines file
   settings.py            - It is project's settings file
   spiders                - It is the spiders directory
      _init_.py
      spider_name.py
      . . .

scrapy.cfg 文件是项目根目录,包括项目名称和项目设定。例如 −

[settings]
default = [name of the project].settings

[deploy]
#url = http://localhost:6800/
project = [name of the project]

Using Scrapy Tool

Scrapy 工具提供了一些使用方法和可用命令,如下所示 −

Scrapy X.Y  - no active project
Usage:
   scrapy  [options] [arguments]
Available commands:
   crawl      It puts spider (handle the URL) to work for crawling data
   fetch      It fetches the response from the given URL

Creating a Project

您可以使用以下命令在 Scrapy 中创建项目 −

scrapy startproject project_name

这会创建名为 project_name 的项目目录。然后,使用以下命令转到新创建的项目 −

cd  project_name

Controlling Projects

您可以使用 Scrapy 工具控制项目和管理它们,还可以使用以下命令创建新的爬虫 −

scrapy genspider mydomain mydomain.com

crawl 等命令必须在 Scrapy 项目内使用。您将在下一部分中了解哪些命令必须在 Scrapy 项目内运行。

Scrapy 包含一些内置命令,可用于您的项目。要查看可用命令的列表,请使用以下命令 −

scrapy -h

当您运行以下命令时,Scrapy 将显示可用命令的列表,如下所示 −

  1. fetch − 使用 Scrapy 下载器获取 URL。

  2. runspider − 用于在不创建项目的情况下运行独立的爬虫。

  3. settings − 指定项目设定值。

  4. shell − 是用于给定 URL 的交互式抓取模块。

  5. startproject − 它创建一个新的 Scrapy 项目。

  6. version − 它显示 Scrapy 版本。

  7. view − 它使用 Scrapy 下载器获取 URL,并在浏览器中显示内容。

你可以获得一些与项目相关的命令,如下所示−

  1. crawl − 它用于使用爬虫抓取数据。

  2. check − 它检查抓取命令返回的项目。

  3. list − 它显示项目中现有的可用爬虫列表。

  4. edit − 您可以使用编辑器编辑爬虫。

  5. parse − 它使用爬虫解析给定的 URL。

  6. bench − 它用于运行快速基准测试(基准值指出 Scrapy 每分钟可以爬取多少页面)。

Custom Project Commands

您可以使用 COMMANDS_MODULE 在 Scrapy 项目中设置自定义项目命令。它在设置中包含一个默认的空字符串。您可以添加以下自定义命令−

COMMANDS_MODULE = 'mycmd.commands'

可以使用 setup.py 文件中 scrapy.commands 部分添加 Scrapy 命令,如下所示−

from setuptools import setup, find_packages

setup(name = 'scrapy-module_demo',
   entry_points = {
      'scrapy.commands': [
         'cmd_demo = my_module.commands:CmdDemo',
      ],
   },
)

上面的代码在 setup.py 文件中添加了 cmd_demo 命令。

Scrapy - Spiders

Description

Spider 是一个类,负责定义如何通过网站跟踪链接并从页面中提取信息。

Scrapy 的默认爬虫如下 −

scrapy.Spider

它是一个爬虫,每个其他爬虫都必须从中继承。它具有以下类 −

class scrapy.spiders.Spider

下表显示了 scrapy.Spider 类的字段 −

Sr.No

Field & Description

1

name 它是爬虫的名称。

2

allowed_domains 它是爬虫抓取的域的列表。

3

start_urls 它是 URL 的列表,它们将成为以后抓取的根源,爬虫将从中开始抓取。

4

custom_settings 这些是设置,在运行爬虫时,将从项目范围配置中覆盖。

5

crawler 它是一个属性,链接到 spider 实例所绑定的 Crawler 对象。

6

settings 这些是用于运行爬虫的设置。

7

logger 它是一个 Python 日志记录器,用于发送日志消息。

8

from_crawler(crawler,*args, kwargs)*它是一个类方法,用于创建爬虫。参数是 − *crawler − 爬虫实例将与其绑定的爬取器。 args(list) − 这些参数传递给 init () 方法。 kwargs(dict) − 这些关键字参数传递给 init () 方法。

9

start_requests() 如果未指定特定的 URL 并且针对爬取打开了蜘蛛,则 Scrapy 会调用 start_requests() 方法。

10

make_requests_from_url(url) 这是一个用于将 url 转换为请求的方法。

11

parse(response) 此方法处理响应并返回废弃数据,并遵循更多 URL。

12

log(message[,level,component]) 这是一个通过 Spider 记录器发送日志消息的方法。

13

closed(reason) 此方法在 Spider 关闭时调用。

Spider Arguments

Spider 参数用于指定开始 URL,并使用 crawl 命令与 -a 选项一起传递,如下所示 −

scrapy crawl first_scrapy -a group = accessories

以下代码演示了 Spider 如何接收参数 −

import scrapy

class FirstSpider(scrapy.Spider):
   name = "first"

   def __init__(self, group = None, *args, **kwargs):
      super(FirstSpider, self).__init__(*args, **kwargs)
      self.start_urls = ["http://www.example.com/group/%s" % group]

Generic Spiders

你可以使用通用 Spider 对你的 Spider 进行子类化。它们的目的是根据特定规则遵循网站上的所有链接,以便从所有页面中提取数据。

对于以下 Spider 中使用的示例,让我们假设我们有一个包含以下字段的项目 −

import scrapy
from scrapy.item import Item, Field

class First_scrapyItem(scrapy.Item):
   product_title = Field()
   product_link = Field()
   product_description = Field()

CrawlSpider

CrawlSpider 定义了一组要遵循的规则,以便遵循链接并提取多个页面。它具有以下类 −

class scrapy.spiders.CrawlSpider

下面是 CrawlSpider 类的属性 −

rules

这是一个规则对象的列表,它定义了爬虫如何遵循链接。

下表显示了 CrawlSpider 类的规则 −

Sr.No

Rule & Description

1

LinkExtractor 它指定了 Spider 如何遵循链接并提取数据。

2

callback 它应该在每个页面被废弃之后调用。

3

follow 它指定是否继续遵循链接。

parse_start_url(response)

它可以通过允许解析初始响应来返回项目或请求对象。

Note − 确保在编写规则时,将 parse 函数重命名为除 parse 之外的其他名称,因为 parse 函数由 CrawlSpider 用于实现其逻辑。

让我们看一看以下示例,其中 Spider 开始爬取 demoexample.com 的主页,收集所有页面、链接,并使用 parse_items 方法进行解析 −

import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor

class DemoSpider(CrawlSpider):
   name = "demo"
   allowed_domains = ["www.demoexample.com"]
   start_urls = ["http://www.demoexample.com"]

   rules = (
      Rule(LinkExtractor(allow =(), restrict_xpaths = ("//div[@class = 'next']",)),
         callback = "parse_item", follow = True),
   )

   def parse_item(self, response):
      item = DemoItem()
      item["product_title"] = response.xpath("a/text()").extract()
      item["product_link"] = response.xpath("a/@href").extract()
      item["product_description"] = response.xpath("div[@class = 'desc']/text()").extract()
      return items

XMLFeedSpider

它是从 XML feed 进行抓取并迭代节点的爬虫的基础类。它有以下类:

class scrapy.spiders.XMLFeedSpider

下表显示用于设置迭代器和标签名的类属性:

Sr.No

Attribute & Description

1

iterator 它定义了要使用的迭代器。它可以是 iternodes、html 或 xml。默认值为 iternodes。

2

itertag 它是一个用于迭代的节点名称字符串。

3

namespaces 它由 (prefix, uri) 元组列表定义,该列表使用 register_namespace() 方法自动注册命名空间。

4

adapt_response(response) 当来自爬虫中间件的响应到达时,它接收响应并修改响应正文,在爬虫开始解析它之前。

5

parse_node(response,selector) 当调用每个与提供标签名称匹配的节点时,它接收响应和一个选择器。 Note -如果你不重写该方法,你的爬虫将不起作用。

6

process_results(response,results) 返回爬虫返回的结果和响应列表。

CSVFeedSpider

它遍历每行,接收 CSV 文件作为响应,并调用 parse_row() 方法。它有以下类:

class scrapy.spiders.CSVFeedSpider

下表显示了关于 CSV 文件的设置选项:

Sr.No

Option & Description

1

delimiter 它是一个包含逗号(“,”)分隔符的字符串,用于每个字段。

2

quotechar 它是一个包含引号(“"”)的字符串,用于每个字段。

3

headers 它是一个包含字段可以从中提取的语句的列表。

4

parse_row(response,row) 它接收响应和每一行以及头部的键。

CSVFeedSpider Example

from scrapy.spiders import CSVFeedSpider
from demoproject.items import DemoItem

class DemoSpider(CSVFeedSpider):
   name = "demo"
   allowed_domains = ["www.demoexample.com"]
   start_urls = ["http://www.demoexample.com/feed.csv"]
   delimiter = ";"
   quotechar = "'"
   headers = ["product_title", "product_link", "product_description"]

   def parse_row(self, response, row):
      self.logger.info("This is row: %r", row)
      item = DemoItem()
      item["product_title"] = row["product_title"]
      item["product_link"] = row["product_link"]
      item["product_description"] = row["product_description"]
      return item

SitemapSpider

SitemapSpider 在 Sitemaps 的帮助下,通过从 robots.txt 定位 URL 来爬取网站。它具有以下类:

class scrapy.spiders.SitemapSpider

下表显示了 SitemapSpider 的字段:

Sr.No

Field & Description

1

sitemap_urls 要抓取指向网站地图的 URL 列表。

2

sitemap_rules 元组 (regex, callback)的列表,其中 regex 是正则表达式,而 callback 用于处理匹配正则表达式的 URL。

3

sitemap_follow 要遵循的网站地图正则表达式列表。

4

sitemap_alternate_links 指定要为单一网址遵循的备用链接。

SitemapSpider Example

以下 SitemapSpider 处理所有 URL −

from scrapy.spiders import SitemapSpider

class DemoSpider(SitemapSpider):
   urls = ["http://www.demoexample.com/sitemap.xml"]

   def parse(self, response):
      # You can scrap items here

以下 SitemapSpider 使用回调处理一些 URL −

from scrapy.spiders import SitemapSpider

class DemoSpider(SitemapSpider):
   urls = ["http://www.demoexample.com/sitemap.xml"]

   rules = [
      ("/item/", "parse_item"),
      ("/group/", "parse_group"),
   ]

   def parse_item(self, response):
      # you can scrap item here

   def parse_group(self, response):
      # you can scrap group here

以下代码显示 robots.txt 中网址为 /sitemap_company 的 sitemap。

from scrapy.spiders import SitemapSpider

class DemoSpider(SitemapSpider):
   urls = ["http://www.demoexample.com/robots.txt"]
   rules = [
      ("/company/", "parse_company"),
   ]
   sitemap_follow = ["/sitemap_company"]

   def parse_company(self, response):
      # you can scrap company here

您甚至可以将 SitemapSpider 与其他 URL 结合使用,如下面的命令所示。

from scrapy.spiders import SitemapSpider

class DemoSpider(SitemapSpider):
   urls = ["http://www.demoexample.com/robots.txt"]
   rules = [
      ("/company/", "parse_company"),
   ]

   other_urls = ["http://www.demoexample.com/contact-us"]
   def start_requests(self):
      requests = list(super(DemoSpider, self).start_requests())
      requests += [scrapy.Request(x, self.parse_other) for x in self.other_urls]
      return requests

   def parse_company(self, response):
      # you can scrap company here...

   def parse_other(self, response):
      # you can scrap other here...

Scrapy - Selectors

Description

当您抓取网页时,您需要通过使用名为 selectors 的机制提取 HTML 源的特定部分,通过使用 XPath 或 CSS 表达式实现。选择器建立在 lxml 库之上,该库处理 Python 语言中的 XML 和 HTML。

使用以下代码片段定义选择器的不同概念 −

<html>
   <head>
      <title>My Website</title>
   </head>

   <body>
      <span>Hello world!!!</span>
      <div class = 'links'>
         <a href = 'one.html'>Link 1<img src = 'image1.jpg'/></a>
         <a href = 'two.html'>Link 2<img src = 'image2.jpg'/></a>
         <a href = 'three.html'>Link 3<img src = 'image3.jpg'/></a>
      </div>
   </body>
</html>

Constructing Selectors

您可以通过传递 textTextResponse 对象来构建选择器类实例。基于提供的输入类型,选择器选择以下规则 −

from scrapy.selector import Selector
from scrapy.http import HtmlResponse

使用上述代码,您可以从文本中构建为 −

Selector(text = body).xpath('//span/text()').extract()

它会显示结果为 −

[u'Hello world!!!']

您可以从响应中构建为 −

response = HtmlResponse(url = 'http://mysite.com', body = body)
Selector(response = response).xpath('//span/text()').extract()

它会显示结果为 −

[u'Hello world!!!']

Using Selectors

使用上述简单代码片段,您可以构建 XPath 来选择标题标签中定义的文本,如下所示 −

>>response.selector.xpath('//title/text()')

现在,您可以使用 .extract() 方法提取文本数据,如下所示 −

>>response.xpath('//title/text()').extract()

它会产生结果为 −

[u'My Website']

您可以显示所有元素的名称,如下所示 −

>>response.xpath('//div[@class = "links"]/a/text()').extract()

它会显示元素为 −

Link 1
Link 2
Link 3

如果您想要提取第一个元素,那么使用 .extract_first() 方法,如下所示 −

>>response.xpath('//div[@class = "links"]/a/text()').extract_first()

它会显示元素为 −

Link 1

Nesting Selectors

使用上述代码,您可以嵌套选择器,以使用 .xpath() 方法显示页面链接和图片源,如下所示 −

links = response.xpath('//a[contains(@href, "image")]')

for index, link in enumerate(links):
   args = (index, link.xpath('@href').extract(), link.xpath('img/@src').extract())
   print 'The link %d pointing to url %s and image %s' % args

它会显示结果为 −

Link 1 pointing to url [u'one.html'] and image [u'image1.jpg']
Link 2 pointing to url [u'two.html'] and image [u'image2.jpg']
Link 3 pointing to url [u'three.html'] and image [u'image3.jpg']

Selectors Using Regular Expressions

Scrapy 允许使用正则表达式提取数据,它使用 .re() 方法。从以上的 HTML 代码中,我们将提取图片名称,如下所示:

>>response.xpath('//a[contains(@href, "image")]/text()').re(r'Name:\s*(.*)')

上面的行显示图片名称如下:

[u'Link 1',
u'Link 2',
u'Link 3']

Using Relative XPaths

当您使用 XPaths(它始于 / )时,嵌套选择器和 XPath 与文档的绝对路径相关,而不是选择器的相对路径。

如果您想提取 <p> 元素,首先获取所有 div 元素:

>>mydiv = response.xpath('//div')

接下来,您可以通过在 XPath 前加上一个点来提取里面的所有 'p' 元素,如下面的 .//p 所示:

>>for p in mydiv.xpath('.//p').extract()

Using EXSLT Extensions

EXSLT 是一个社区,它为 XSLT(可扩展样式表语言转换)发布扩展,它将 XML 文档转换为 XHTML 文档。您可以使用 XPath 表达式中注册的命名空间中的 EXSLT 扩展,如下表所示:

Sr.No

Prefix & Usage

Namespace

1

re regular expressions

http://exslt.org/regexp/index.html

2

set set manipulation

http://exslt.org/set/index.html

您可以在上一部分检查使用正则表达式提取数据的简单代码格式。

在将 XPath 与 Scrapy 选择器一起使用时,有一些 XPath 技巧很有用。有关详细信息,请单击此 link

Scrapy - Items

Description

Scrapy 进程可用于从诸如使用爬虫的网页等来源提取数据。Scrapy 使用 Item 类生成输出,其对象用于收集抓取的数据。

Declaring Items

你可以使用类定义语法以及如下所示的字段对象来声明项目 -

import scrapy
class MyProducts(scrapy.Item):
   productName = Field()
   productLink = Field()
   imageURL = Field()
   price = Field()
   size = Field()

Item Fields

项目字段用于显示每个字段的元数据。由于字段对象上的值没有限制,可访问的元数据键不会包含元数据的任何参考列表。字段对象用于指定所有字段元数据,你可以根据项目中的要求指定任何其他字段键。可以使用 Item.fields 属性访问字段对象。

Working with Items

在你使用项目时可以定义一些常见的函数。有关详细信息,请点击此处的 link

Extending Items

可以通过声明原始项目的子类来扩展项目。例如 -

class MyProductDetails(Product):
   original_rate = scrapy.Field(serializer = str)
   discount_rate = scrapy.Field()

你可以使用现有的字段元数据通过添加更多值或更改现有值来扩展字段元数据,如下面的代码所示 -

class MyProductPackage(Product):
   name = scrapy.Field(Product.fields['name'], serializer = serializer_demo)

Item Objects

可以使用以下类指定项目对象,该类从给定的参数中提供新的已初始化项目 -

class scrapy.item.Item([arg])

Item 提供构造函数的副本,并提供一个由项目中的字段给出的额外属性。

Field Objects

可以使用以下类指定字段对象,其中 Field 类不会发出额外的进程或属性 -

class scrapy.item.Field([arg])

Scrapy - Item Loaders

Description

项目加载器提供了一种便捷的方法来填充从网站抓取的项目。

Declaring Item Loaders

项目加载器的声明类似于项目。

例如 -

from scrapy.loader import ItemLoader
from scrapy.loader.processors import TakeFirst, MapCompose, Join

class DemoLoader(ItemLoader):
   default_output_processor = TakeFirst()
   title_in = MapCompose(unicode.title)
   title_out = Join()
   size_in = MapCompose(unicode.strip)
   # you can continue scraping here

在上面的代码中,您可以看到使用 _in 后缀声明输入处理器,并使用 _out 后缀声明输出处理器。

ItemLoader.default_input_processorItemLoader.default_output_processor 属性用于声明默认输入/输出处理器。

Using Item Loaders to Populate Items

要使用项目加载器,首先使用类字典对象实例化或没有类字典对象实例化项目,该项目使用 ItemLoader.default_item_class 属性中指定的项目类。

  1. 您可以使用选择器将值收集到项目加载器中。

  2. 您可以在相同项目的字段中添加更多值,此时项目加载器将使用合适的处理器来添加这些值。

以下代码展示使用项目加载器填充项目的的过程:

from scrapy.loader import ItemLoader
from demoproject.items import Demo

def parse(self, response):
   l = ItemLoader(item = Product(), response = response)
   l.add_xpath("title", "//div[@class = 'product_title']")
   l.add_xpath("title", "//div[@class = 'product_name']")
   l.add_xpath("desc", "//div[@class = 'desc']")
   l.add_css("size", "div#size]")
   l.add_value("last_updated", "yesterday")
   return l.load_item()

如上所示,有两个不同的 XPath,由 add_xpath() 方法抽取 title 域:

1. //div[@class = "product_title"]
2. //div[@class = "product_name"]

此后,类似的请求用于 desc 域。通过 add_css() 方法抽取大小数据,然后通过 add_value() 方法使用值“昨天”填充 last_updated

一旦收集到所有数据,调用 ItemLoader.load_item() 方法,它将返回填充了通过 add_xpath()add_css()add_value() 方法抽取的数据的项目。

Input and Output Processors

项目加载器的每个域都包含一个输入处理器和一个输出处理器。

  1. 在抽取数据时,输入处理器对数据进行处理,其结果存储在 ItemLoader 中。

  2. 接下来,在收集完数据后,调用 ItemLoader.load_item() 方法以获取填充项目的对象。

  3. 最后,可以将输出处理器的结果分配给项目。

以下代码展示如何调用特定域的输入和输出处理器:

l = ItemLoader(Product(), some_selector)
l.add_xpath("title", xpath1) # [1]
l.add_xpath("title", xpath2) # [2]
l.add_css("title", css)      # [3]
l.add_value("title", "demo") # [4]
return l.load_item()         # [5]

Line 1 - 从 xpath1 抽取标题数据并传递通过输入处理器,然后收集其结果并存储在 ItemLoader 中。

Line 2 - 同样,从 xpath2 抽取标题并传递通过相同的输入处理器,然后将其结果添加到为 [1] 收集的数据中。

Line 3 - 从 css 选择器抽取标题并传递通过相同的输入处理器,然后将结果添加到为 [1] 和 [2] 收集的数据中。

Line 4 - 接下来,分配值“demo”并传递通过输入处理器。

Line 5 - 最后,从所有域内部收集数据并传递至输出处理器,最后的值分配给项目。

Declaring Input and Output Processors

输入和输出处理器在项目加载器的定义中声明。除此外,它们还可以 Item Field 元数据中指定。

例如 -

import scrapy
from scrapy.loader.processors import Join, MapCompose, TakeFirst
from w3lib.html import remove_tags

def filter_size(value):
   if value.isdigit():
      return value

class Item(scrapy.Item):
   name = scrapy.Field(
      input_processor = MapCompose(remove_tags),
      output_processor = Join(),
   )
   size = scrapy.Field(
      input_processor = MapCompose(remove_tags, filter_price),
      output_processor = TakeFirst(),
   )

>>> from scrapy.loader import ItemLoader
>>> il = ItemLoader(item = Product())
>>> il.add_value('title', [u'Hello', u'<strong>world</strong>'])
>>> il.add_value('size', [u'<span>100 kg</span>'])
>>> il.load_item()

其显示的输出为:

{'title': u'Hello world', 'size': u'100 kg'}

Item Loader Context

项目加载器上下文是 input 和 output 处理器共享的任意键值 dict。

例如,假设您具有函数 parse_length:

def parse_length(text, loader_context):
   unit = loader_context.get('unit', 'cm')

   # You can write parsing code of length here
   return parsed_length

通过接收 loader_context 参数,Item Loader 会知道可以接收 Item Loader 上下文。有几种方法可以更改 Item Loader 上下文的 value −

  1. 修改当前的活动 Item Loader 上下文 −

loader = ItemLoader (product)
loader.context ["unit"] = "mm"
  1. 在 Item Loader 实例化时 −

loader = ItemLoader(product, unit = "mm")
  1. 在 Item Loader 声名为输入/输出处理器时会实例化 Item Loader 上下文 −

class ProductLoader(ItemLoader):
   length_out = MapCompose(parse_length, unit = "mm")

ItemLoader Objects

它是一个对象,返回一个 Item Loader,以填充给定的项目。它有以下类 −

class scrapy.loader.ItemLoader([item, selector, response, ]**kwargs)

下表显示 ItemLoader 对象的参数 −

Sr.No

Parameter & Description

1

item 它是通过调用 add_xpath()、add_css() 或 add_value() 填充的项目。

2

selector 用于从网站提取数据。

3

response 用于通过 default_selector_class 构建选择器。

下表显示 ItemLoader 对象的方法 −

Sr.No

Method & Description

Example

1

get_value(value, *processors, **kwargs) 通过给定的处理器和关键字参数,值由 get_value() 方法处理。

>>> from scrapy.loader.processors import TakeFirst>>> loader.get_value(u’title: demoweb', TakeFirst(),unicode.upper, re = 'title: (.+)')'DEMOWEB`

2

add_value(field_name, value, *processors, **kwargs) 它处理值并将其添加到字段,其中在通过字段输入处理器传递之前,它首先通过 get_value 进行处理,提供处理器和关键字参数。

loader.add_value('title', u’DVD')loader.add_value('colors', [u’black', u’white'])loader.add_value('length', u'80')loader.add_value('price', u'2500')

3

replace_value(field_name, value, *processors, **kwargs) 它用一个新值替换收集的数据。

loader.replace_value('title', u’DVD')loader.replace_value('colors', [u’black',u’white'])loader.replace_value('length', u'80')loader.replace_value('price', u'2500')

4

get_xpath(xpath, *processors, **kwargs) 通过接收 XPath,通过提供处理器和关键字参数,用于提取 unicode 字符串。

= HTML 代码:<div class = "item-name">DVD</div>loader.get_xpath("//div[@class =[id="_html_code_div_id_lengththe_length_is"]= HTML 代码:<div id = "length">the length is45cm</div>loader.get_xpath("//div[@id = 'length']", TakeFirst(),re = "the length is (.*)")

5

add_xpath(field_name, xpath, *processors, **kwargs) 它接收要提取 unicode 字符串的字段的 XPath。

= HTML 代码:<div class = "item-name">DVD</div> loader.add_xpath('name', '//div [id="_html_code_div_id_lengththe_length_is"] = HTML 代码:<div id = "length">the length is 45cm</div> loader.add_xpath('length', '//div[@id = "length"]', re = 'the length is (.*)')

6

replace_xpath(field_name, xpath, *processors, **kwargs) 它使用 XPath 从网站中替换收集的数据。

= HTML 代码:<div class = "item-name">DVD</div> loader.replace_xpath('name', ' [id="_html_code_div_id_lengththe_length_is"] = HTML 代码:<div id = "length">the length is 45cm</div> loader.replace_xpath('length', '

7

get_css(css, *processors, **kwargs) 它接收用于提取 Unicode 字符串的 CSS 选择器。

loader.get_css("div.item-name") loader.get_css("div#length", TakeFirst(), re = "the length is (.*)")

8

add_css(field_name, css, *processors, **kwargs) It is similar to add_value() method with one difference that it adds CSS selector to the field.

loader.add_css('name', 'div.item-name') loader.add_css('length', 'div#length', re = 'the length is (.*)')

9

replace_css(field_name, css, *processors, **kwargs) It replaces the extracted data using CSS selector.

loader.replace_css('name', 'div.item-name') loader.replace_css('length', 'div#length', re = 'the length is (.*)')

10

load_item() When the data is collected, this method fills the item with collected data and returns it.

def parse(self, response): l = ItemLoader(item = Product(), response = response) l.add_xpath('title', '// div[@class = "product_title"]') loader.load_item()

11

nested_xpath(xpath) It is used to create nested loaders with an XPath selector.

loader = ItemLoader(item = Item()) loader.add_xpath('social', ' a[@class="social"]/@href') loader.add_xpath('email', ' a[@class="email"]/@href')

12

nested_css(css) 它用于使用 CSS 选择器创建嵌套加载器。

loader = ItemLoader(item = Item()) loader.add_css('social', 'a[@class="social"]/@href') loader.add_css('email', 'a[@class="email"]/@href')

下表显示了 ItemLoader 对象的属性:

Sr.No

Attribute & Description

1

item Item Loader 执行解析的对象。

2

context Item Loader 当前的活动上下文。

3

default_item_class 如果在构造函数中没有给出,它用于表示该项。

4

default_input_processor 未指定输入处理器的字段是唯一使用 default_input_processors 的字段。

5

default_output_processor 未指定输出处理器的字段是唯一使用 default_output_processors 的字段。

6

default_selector_class 这是用于构建选择器的类,如果在构造函数中未给出该类。

7

selector 这是一个可以用于从网站中提取数据的对象。

Nested Loaders

它用于在解析文档子部分中的值时创建嵌套加载器。如果你不创建嵌套加载器,你需要为要提取的每个值指定完整的 XPath 或 CSS。

例如,假设数据正在从头文件中提取 −

<header>
   <a class = "social" href = "http://facebook.com/whatever">facebook</a>
   <a class = "social" href = "http://twitter.com/whatever">twitter</a>
   <a class = "email" href = "mailto:someone@example.com">send mail</a>
</header>

接下来,你可以通过向头文件中添加相关值来用头选择器创建嵌套加载器 −

loader = ItemLoader(item = Item())
header_loader = loader.nested_xpath('//header')
header_loader.add_xpath('social', 'a[@class = "social"]/@href')
header_loader.add_xpath('email', 'a[@class = "email"]/@href')
loader.load_item()

Reusing and extending Item Loaders

项目加载器旨在减轻在项目获取更多爬虫时出现的维护问题。

例如,假设某个网站的产品名称包含三个破折号(例如 --DVD---)。如果你不希望它出现在最终产品名称中,你可以通过重复使用默认的产品项目加载器来移除那些破折号,如下面的代码所示 −

from scrapy.loader.processors import MapCompose
from demoproject.ItemLoaders import DemoLoader

def strip_dashes(x):
   return x.strip('-')

class SiteSpecificLoader(DemoLoader):
   title_in = MapCompose(strip_dashes, DemoLoader.title_in)

Available Built-in Processors

以下是常用的内置处理器 −

class scrapy.loader.processors.Identity

它返回原始值而不做任何更改。例如 −

>>> from scrapy.loader.processors import Identity
>>> proc = Identity()
>>> proc(['a', 'b', 'c'])
['a', 'b', 'c']

class scrapy.loader.processors.TakeFirst

它从接收值列表中返回第一个非空/非空值。例如 −

>>> from scrapy.loader.processors import TakeFirst
>>> proc = TakeFirst()
>>> proc(['', 'a', 'b', 'c'])
'a'

class scrapy.loader.processors.Join(separator = u' ')

它返回连接到分隔符的值。默认分隔符是 u' ',它相当于函数 u' '.join 。例如 −

>>> from scrapy.loader.processors import Join
>>> proc = Join()
>>> proc(['a', 'b', 'c'])
u'a b c'
>>> proc = Join('<br>')
>>> proc(['a', 'b', 'c'])
u'a<br>b<br>c'

class scrapy.loader.processors.Compose(*functions, **default_loader_context)

它由一个处理器定义,其中它的每个输入值都传递到第一个函数,该函数的结果传递到第二个函数,依此类推,直到最后函数返回最终值作为输出。

例如 -

>>> from scrapy.loader.processors import Compose
>>> proc = Compose(lambda v: v[0], str.upper)
>>> proc(['python', 'scrapy'])
'PYTHON'

class scrapy.loader.processors.MapCompose(*functions, **default_loader_context)

这是一个处理器,输入值会在其中进行迭代,第一个函数会应用到每个元素。接下来,这些函数调用的结果连接在一起,形成可迭代的新项,然后应用到第二个函数,依此类推,知道最后一个函数。

例如 -

>>> def filter_scrapy(x):
   return None if x == 'scrapy' else x

>>> from scrapy.loader.processors import MapCompose
>>> proc = MapCompose(filter_scrapy, unicode.upper)
>>> proc([u'hi', u'everyone', u'im', u'pythonscrapy'])
[u'HI, u'IM', u'PYTHONSCRAPY']

class scrapy.loader.processors.SelectJmes(json_path)

这个类使用提供的 json 路径查询值并返回输出。

例如 -

>>> from scrapy.loader.processors import SelectJmes, Compose, MapCompose
>>> proc = SelectJmes("hello")
>>> proc({'hello': 'scrapy'})
'scrapy'
>>> proc({'hello': {'scrapy': 'world'}})
{'scrapy': 'world'}

以下是通过导入 json 查询值的代码 −

>>> import json
>>> proc_single_json_str = Compose(json.loads, SelectJmes("hello"))
>>> proc_single_json_str('{"hello": "scrapy"}')
u'scrapy'
>>> proc_json_list = Compose(json.loads, MapCompose(SelectJmes('hello')))
>>> proc_json_list('[{"hello":"scrapy"}, {"world":"env"}]')
[u'scrapy']

Scrapy - Shell

Description

Scrapy shell 可用于使用无错误的代码来抓取数据,而无需使用爬虫。Scrapy shell 的主要目的是测试已提取的代码、XPath 或 CSS 表达式。它还有助于指定您要从中抓取数据的网页。

Configuring the Shell

可以通过安装 IPython (用于交互式计算)控制台来配置 shell,这是一个功能强大的交互式 shell,它提供了自动完成、着色输出等功能。

如果您在 Unix 平台上工作,那么最好安装 IPython。如果 IPython 不可访问,您还可以使用 bpython

您可以通过设置名为 SCRAPY_PYTHON_SHELL 的环境变量或按如下方式定义 scrapy.cfg 文件来配置 shell:

[settings]
shell = bpython

Launching the Shell

可以使用以下命令启动 Scrapy shell:

scrapy shell <url>

url 指定要抓取数据的 URL。

Using the Shell

shell 提供一些附加快捷方式和 Scrapy 对象,如下表所述:

Available Shortcuts

shell 在项目中提供了以下可用快捷方式:

Sr.No

Shortcut & Description

1

shelp() 它通过帮助选项提供了可用的对象和快捷方式。

2

fetch(request_or_url) 它收集来自请求或网址的响应,并且关联的对象会被恰当地更新。

3

view(response) 您可以在浏览器的本地浏览器中查看给定请求的响应以进行观察,并且为了正确地显示外部链接,它会追加一个基础标记到响应体。

Available Scrapy Objects

Shell 在 project 中提供了以下可用的 Scrapy 对象 −

Sr.No

Object & Description

1

crawler 它指定了当前的爬虫对象。

2

spider 如果没有当前网址的爬虫,那么它将通过定义新的爬虫来处理网址或爬虫对象。

3

request 它指定了最后一个收集页面的请求对象。

4

response 它指定了最后一个收集页面的响应对象。

5

settings 它提供了当前的 Scrapy 设置。

Example of Shell Session

让我们尝试爬取 scrapy.org 网站,然后按照说明开始从 reddit.com 爬取数据。

在继续之前,首先我们将按照以下命令启动 shell −

scrapy shell 'http://scrapy.org' --nolog

Scrapy 将在使用以上网址时显示可用的对象 −

[s] Available Scrapy objects:
[s]   crawler    <scrapy.crawler.Crawler object at 0x1e16b50>
[s]   item       {}
[s]   request    <GET http://scrapy.org >
[s]   response   <200 http://scrapy.org >
[s]   settings   <scrapy.settings.Settings object at 0x2bfd650>
[s]   spider     <Spider 'default' at 0x20c6f50>
[s] Useful shortcuts:
[s]   shelp()           Provides available objects and shortcuts with help option
[s]   fetch(req_or_url) Collects the response from the request or URL and associated
objects will get update
[s]   view(response)    View the response for the given request

接下来,开始使用对象,如下所示 −

>> response.xpath('//title/text()').extract_first()
u'Scrapy | A Fast and Powerful Scraping and Web Crawling Framework'
>> fetch("http://reddit.com")
[s] Available Scrapy objects:
[s]   crawler
[s]   item       {}
[s]   request
[s]   response   <200 https://www.reddit.com/>
[s]   settings
[s]   spider
[s] Useful shortcuts:
[s]   shelp()           Shell help (print this help)
[s]   fetch(req_or_url) Fetch request (or URL) and update local objects
[s]   view(response)    View response in a browser
>> response.xpath('//title/text()').extract()
[u'reddit: the front page of the internet']
>> request = request.replace(method="POST")
>> fetch(request)
[s] Available Scrapy objects:
[s]   crawler
...

Invoking the Shell from Spiders to Inspect Responses

只有当您希望获取该响应时,您才能检查从爬虫处理的响应。

例如 −

import scrapy

class SpiderDemo(scrapy.Spider):
   name = "spiderdemo"
   start_urls = [
      "http://mysite.com",
      "http://mysite1.org",
      "http://mysite2.net",
   ]

   def parse(self, response):
      # You can inspect one specific response
      if ".net" in response.url:
         from scrapy.shell import inspect_response
         inspect_response(response, self)

如以上代码所示,您可以在爬虫中调用 shell 来使用以下函数检查响应 −

scrapy.shell.inspect_response

现在运行爬虫,您将得到以下屏幕 −

2016-02-08 18:15:20-0400 [scrapy] DEBUG: Crawled (200)  (referer: None)
2016-02-08 18:15:20-0400 [scrapy] DEBUG: Crawled (200)  (referer: None)
2016-02-08 18:15:20-0400 [scrapy] DEBUG: Crawled (200)  (referer: None)
[s] Available Scrapy objects:
[s]   crawler
...
>> response.url
'http://mysite2.org'

您可以通过以下代码检查提取的代码是否有效 −

>> response.xpath('//div[@class = "val"]')

它会以下形式显示输出

[]

以上行仅显示了一个空白输出。现在您可以调用 shell 来检查响应,如下所示 −

>> view(response)

它会显示以下响应

True

Scrapy - Item Pipeline

Description

Item Pipeline 是一种对收集到的项目进行处理的方法。当一个项目被发送到项目管道时,它会被一个爬虫程序抓取出来,然后使用几个按顺序执行的组件进行处理。

每当接收到一个项目时,就会决定采取以下两种操作之一 −

  1. Keep processing the item.

  2. Drop it from pipeline.

  3. Stop processing the item.

项目管道通常用于以下目的 −

  1. 将抓取到的项目存储在数据库中。

  2. 如果接收到的项目是一个重复的项目,那它会将重复的项目删除。

  3. 它将检查该项目是否带有目标字段。

  4. Clearing HTML data.

Syntax

您可以使用以下方法编写项目管道 −

process_item(self, item, spider)

上述方法包含以下参数 −

  1. Item (Item 对象或字典)- 它指定要抓取的 Item。

  2. spider (spider 对象)- 发送该 Item 的 spider。

你也可以使用下表中给出的各种方法-

Sr.No

Method & Description

Parameters

1

open_spider(self, spider) 当 spider 被打开时选择它。

spider(spider 对象)- 它指被打开的 spider。

2

close_spider(self, spider) 当 spider 被关闭时选择它。

spider (spider 对象)- 它指被关闭的 spider。

3

from_crawler(cls, crawler) 借助 crawler, 该管道可以访问 Scrapy 的核心组件,如信号和设定。

crawler (Crawler 对象)- 它指使用此管道的 crawler。

Example

以下是用于不同概念的 Item 管道的范例。

Dropping Items with No Tag

在以下代码中,管道平衡了那些不包含增值税(excludes_vat 属性)的 Item 的(price)属性并忽略不带价签的 Item.-

from Scrapy.exceptions import DropItem
class PricePipeline(object):
   vat = 2.25

   def process_item(self, item, spider):
      if item['price']:
         if item['excludes_vat']:
            item['price'] = item['price'] * self.vat
            return item
         else:
            raise DropItem("Missing price in %s" % item)

Writing Items to a JSON File

以下代码将把所有 spider 抓取的所有 Item 存储到单个 items.jl 文件中,其中包含每个以 JSON 格式序列化的行里的一个 Item。 JsonWriterPipeline 类在代码中用于展示如何编写 Item 管道-

import json

class JsonWriterPipeline(object):
   def __init__(self):
      self.file = open('items.jl', 'wb')

   def process_item(self, item, spider):
      line = json.dumps(dict(item)) + "\n"
      self.file.write(line)
      return item

Writing Items to MongoDB

你可以在 Scrapy 设置中指定 MongoDB 地址和数据库名称,并且 MongoDB 集合可以以 Item 类命名。以下代码描述了如何正确使用 from_crawler() 方法来收集资源-

import pymongo

class MongoPipeline(object):
   collection_name = 'Scrapy_list'

   def __init__(self, mongo_uri, mongo_db):
      self.mongo_uri = mongo_uri
      self.mongo_db = mongo_db

   @classmethod
   def from_crawler(cls, crawler):
      return cls(
         mongo_uri = crawler.settings.get('MONGO_URI'),
         mongo_db = crawler.settings.get('MONGO_DB', 'lists')
      )

   def open_spider(self, spider):
      self.client = pymongo.MongoClient(self.mongo_uri)
      self.db = self.client[self.mongo_db]

   def close_spider(self, spider):
      self.client.close()

   def process_item(self, item, spider):
      self.db[self.collection_name].insert(dict(item))
      return item

Duplicating Filters

过滤器会检查重复的 Item, 并且会删除已经处理的 Item。在以下代码中,我们为我们的 Item 已经使用一个唯一的 id, 但是 spider 返回了多个带有相同 id 的 Item -

from scrapy.exceptions import DropItem

class DuplicatesPipeline(object):
   def __init__(self):
      self.ids_seen = set()

   def process_item(self, item, spider):
      if item['id'] in self.ids_seen:
         raise DropItem("Repeated items found: %s" % item)
      else:
         self.ids_seen.add(item['id'])
         return item

Activating an Item Pipeline

你可以通过将它的类添加到 ITEM_PIPELINES 设置中来激活一个 Item Pipeline 组件,如下面的代码所示。你可以按照它们运行的顺序给类分配整数值(顺序可以从低值到高值),并且其值在 0 到 1000 范围内。

ITEM_PIPELINES = {
   'myproject.pipelines.PricePipeline': 100,
   'myproject.pipelines.JsonWriterPipeline': 600,
}

Scrapy - Feed exports

Description

数据提要导出是一种存储从网站抓取数据的技术,即生成 "export file"

Serialization Formats

通过使用多种序列化格式和存储后端,数据提要导出可使用项目导出器并根据抓取的项目生成提要。

下表展示受支持的格式:

Sr.No

Format & Description

1

JSON FEED_FORMAT 为 jsonExporter 使用的是 scrapy.exporters.JsonItemExporter 类

2

JSON lines FEED_FROMAT 为 jsonlinesExporter 使用的是 scrapy.exporters.JsonLinesItemExporter 类

3

CSV FEED_FORMAT 为 CSVExporter 使用的是 scrapy.exporters.CsvItemExporter 类

4

XML FEED_FORMAT 为 xmlExporter 使用的是 scrapy.exporters.XmlItemExporter 类

通过使用 FEED_EXPORTERS 设置,受支持的格式还可以得到扩展 −

Sr.No

Format & Description

1

Pickle FEED_FORMAT 为 pickelExporter 使用的是 scrapy.exporters.PickleItemExporter 类

2

Marshal FEED_FORMAT 为 marshalExporter 使用的是 scrapy.exporters.MarshalItemExporter 类

Storage Backends

存储后端定义了在何处存储使用 URI 的数据提要。

下表展示了受支持的存储后端 −

Sr.No

Storage Backend & Description

1

Local filesystem URI 方案为 file,它用于存储数据提要。

2

FTP URI 方案为 ftp,它用于存储数据提要。

3

S3 URI 方案为 S3,数据提要存储在 Amazon S3 上。需要 botocoreboto 外部库。

4

Standard output URI 方案为 stdout 数据提要存储在标准输出。

Storage URI Parameters

以下是存储 URL 的参数,在创建数据提要时替换它 −

  1. %(time)s:此参数替换为时间戳。

  2. %(name)s:此参数替换为爬虫名称。

Settings

下表显示了用于配置 Feed 导出的设置:

Sr.No

Setting & Description

1

FEED_URI 这是用于启用 Feed 导出的导出 Feed 的 URI。

2

FEED_FORMAT 这是用于 Feed 的序列化格式。

3

FEED_EXPORT_FIELDS 用于定义需要导出的字段。

4

FEED_STORE_EMPTY 它定义是否导出没有项目的 Feed。

5

FEED_STORAGES 它是一个具有其他 Feed 存储后端的字典。

6

FEED_STORAGES_BASE 它是一个具有内置 Feed 存储后端的字典。

7

FEED_EXPORTERS 它是一个具有其他 Feed 导出的字典。

8

FEED_EXPORTERS_BASE 它是一个具有内置 Feed 导出的字典。

Scrapy - Requests and Responses

Description

Scrapy 可使用 RequestResponse 对象抓取网站。请求对象经过系统,使用蜘蛛执行请求并在返回响应对象时返回到请求。

Request Objects

请求对象是一个生成响应的 HTTP 请求。它具有以下类:

class scrapy.http.Request(url[, callback, method = 'GET', headers, body, cookies, meta,
   encoding = 'utf-8', priority = 0, dont_filter = False, errback])

下表显示请求对象的各个参数:

Sr.No

Parameter & Description

1

url 是一个指定 URL 请求的字符串。

2

callback 是一个可调用函数,该函数将请求的响应用作第一个参数。

3

method 是一个指定 HTTP 方法请求的字符串。

4

headers 是一个具有请求头部的词典。

5

body 是一个具有请求正文的字符串或 unicode。

6

cookies 是一个包含请求 cookie 的列表。

7

meta 是一个包含请求元数据值的词典。

8

encoding 是一个包含用于对 URL 编码的 utf-8 编码的字符串。

9

priority 是一个整型,其中调度程序使用优先级来定义处理请求的顺序。

10

dont_filter 是一个布尔值,指定调度程序不得过滤该请求。

11

errback 是一个可调用函数,在处理请求时引发异常时调用。

Passing Additional Data to Callback Functions

请求的回调函数在以其第一个参数下载响应时调用。

例如 -

def parse_page1(self, response):
   return scrapy.Request("http://www.something.com/some_page.html",
      callback = self.parse_page2)

def parse_page2(self, response):
   self.logger.info("%s page visited", response.url)

如果您想要将参数传递给可调用函数并在第二个回调中接收这些参数,则可以使用 Request.meta 属性,如下例所示:

def parse_page1(self, response):
   item = DemoItem()
   item['foremost_link'] = response.url
   request = scrapy.Request("http://www.something.com/some_page.html",
      callback = self.parse_page2)
   request.meta['item'] = item
   return request

def parse_page2(self, response):
   item = response.meta['item']
   item['other_link'] = response.url
   return item

Using errbacks to Catch Exceptions in Request Processing

当在处理请求时引发异常时,调用 errback 函数。

以下示例演示了这一点−

import scrapy

from scrapy.spidermiddlewares.httperror import HttpError
from twisted.internet.error import DNSLookupError
from twisted.internet.error import TimeoutError, TCPTimedOutError

class DemoSpider(scrapy.Spider):
   name = "demo"
   start_urls = [
      "http://www.httpbin.org/",              # HTTP 200 expected
      "http://www.httpbin.org/status/404",    # Webpage not found
      "http://www.httpbin.org/status/500",    # Internal server error
      "http://www.httpbin.org:12345/",        # timeout expected
      "http://www.httphttpbinbin.org/",       # DNS error expected
   ]

   def start_requests(self):
      for u in self.start_urls:
         yield scrapy.Request(u, callback = self.parse_httpbin,
         errback = self.errback_httpbin,
         dont_filter=True)

   def parse_httpbin(self, response):
      self.logger.info('Recieved response from {}'.format(response.url))
      # ...

   def errback_httpbin(self, failure):
      # logs failures
      self.logger.error(repr(failure))

      if failure.check(HttpError):
         response = failure.value.response
         self.logger.error("HttpError occurred on %s", response.url)

      elif failure.check(DNSLookupError):
         request = failure.request
         self.logger.error("DNSLookupError occurred on %s", request.url)

      elif failure.check(TimeoutError, TCPTimedOutError):
         request = failure.request
         self.logger.error("TimeoutError occurred on %s", request.url)

Request.meta Special Keys

request.meta 特殊键是 Scrapy 识别的特殊 meta 键列表。

下表显示 Request.meta 的一些键:

Sr.No

Key & Description

1

dont_redirect 当设置为 true 时,这是一个关键,不依据响应的状态重新定向请求。

2

dont_retry 当设置为 true 时,这是一个关键,不会重试失败的请求,并且会被中间件忽略。

3

handle_httpstatus_list 这是一个定义每个请求基础允许哪些响应代码的关键。

4

handle_httpstatus_all 这是一个关键,用于通过将其设置为 true 来允许任何请求响应代码。

5

dont_merge_cookies 这是一个关键,用于通过将其设置为 true 来避免与现有 cookie 合并。

6

cookiejar 这是一个关键,用于为每个蜘蛛保持多个 cookie 会话。

7

dont_cache 这是一个关键,用于避免在每个策略上缓存 HTTP 请求和响应。

8

redirect_urls 这是一个关键,包含请求通过的 URL。

9

bindaddress 这是可用于执行请求的传出 IP 地址的 IP。

10

dont_obey_robotstxt 当设置为 true 时,这是一个关键,即使启用了 ROBOTSTXT_OBEY,也不会过滤 robots.txt 排除标准禁止的请求。

11

download_timeout 它用于为每个蜘蛛设置超时(以秒为单位),下载器将在超时之前等待此超时。

12

download_maxsize 它用于为每个蜘蛛设置最大大小(以字节为单位),这是下载器将下载的大小。

13

可以针对 Request 对象设置代理,以将 HTTP 代理设置为用于请求。

Request Subclasses

你可以通过对 request 类进行子类化来实现自己的自定义功能。内置请求子类如下 −

FormRequest Objects

FormRequest 类通过扩展基本请求来处理 HTML 表单。它具有以下类 −

class scrapy.http.FormRequest(url[,formdata, callback, method = 'GET', headers, body,
   cookies, meta, encoding = 'utf-8', priority = 0, dont_filter = False, errback])

以下是参数 −

formdata − 这是一个具有 HTML 表单数据的字典,该字典被分配给请求正文。

Note − 其余参数与 request 类相同,并在 Request Objects 部分中进行了说明。

除了请求方法之外, FormRequest 对象还支持以下类方法 −

classmethod from_response(response[, formname = None, formnumber = 0, formdata = None,
   formxpath = None, formcss = None, clickdata = None, dont_click = False, ...])

下表显示了上面类的参数 -

Sr.No

Parameter & Description

1

response 这是一个用于使用 HTML 表单响应预先填充表单字段的对象。

2

formname 如果指定,这是一个将使用名称属性的表单的字符串。

3

formnumber 当响应中有多个表单时,这是一个要使用的表单的整数。

4

formdata 这是一个用于覆盖的表单数据字段的字典。

5

formxpath 当指定时,这是使用 xpath 匹配的表单。

6

formcss 当指定时,这是使用 css 选择器匹配的表单。

7

clickdata 这是一个用于观察已单击控件的属性字典。

8

dont_click 当设置为 true 时,表单中的数据将被提交且不会单击任何元素。

Examples

以下是部分请求用例 -

Using FormRequest to send data via HTTP POST

下面的代码演示了在蜘蛛中重复 HTML 表单 POST 时,如何返回 FormRequest 对象 -

return [FormRequest(url = "http://www.something.com/post/action",
   formdata = {'firstname': 'John', 'lastname': 'dave'},
   callback = self.after_post)]

Using FormRequest.from_response() to simulate a user login

通常,网站使用元素通过它们提供预先填充的表单字段。

当你希望这些字段在抓取时自动填充时,可以使用 FormRequest.form_response() 方法。

以下示例演示了这一点。

import scrapy
class DemoSpider(scrapy.Spider):
   name = 'demo'
   start_urls = ['http://www.something.com/users/login.php']
   def parse(self, response):
      return scrapy.FormRequest.from_response(
         response,
         formdata = {'username': 'admin', 'password': 'confidential'},
         callback = self.after_login
      )

   def after_login(self, response):
      if "authentication failed" in response.body:
         self.logger.error("Login failed")
         return
      # You can continue scraping here

Response Objects

这是一个表征 HTTP 响应的对象,它被输入到需要处理的爬虫中。它有以下类 -

class scrapy.http.Response(url[, status = 200, headers, body, flags])

下表显示了响应对象的参数 -

Sr.No

Parameter & Description

1

url 这是一个指定 URL 响应字符串。

2

status 这是一个包含 HTTP 状态响应的整数。

3

headers 这是包含响应头的字典。

4

body 这是一个包含响应体的字符串。

5

flags 这是一个包含响应标志的列表。

Response Subclasses

你可以通过对响应类进行子类化来实现你自定义的功能。内置的响应子类如下:

TextResponse objects

TextResponse 对象被用于二进制数据,例如图像、声音等,它有能力编码基本的响应类。它包含以下类:

class scrapy.http.TextResponse(url[, encoding[,status = 200, headers, body, flags]])

以下是参数 −

encoding − 这是一个用于对响应进行编码的字符串。

Note − 剩余的参数与响应类相同,在 Response Objects 部分中对其进行了说明。

下表显示了 TextResponse 对象在响应方法之外支持的属性:

Sr.No

Attribute & Description

1

text 这是一个响应体,可以多次访问 response.text。

2

encoding 这是一个包含用于响应的编码的字符串。

3

selector 这是一个在首次访问时实例化的属性,并且使用响应作为目标。

下表显示了 TextResponse 对象在响应方法之外支持的方法:

Sr.No

Method & Description

1

xpath (query) 这是一个指向 TextResponse.selector.xpath(query) 的捷径。

2

css (query) 这是一个指向 TextResponse.selector.css(query) 的捷径。

3

body_as_unicode() 这是一个响应体,可以作为一种方法进行访问,在其中可以多次访问 response.text。

HtmlResponse Objects

它是一个支持编码和自动发现的对象,通过查看 HTML 的 meta httpequiv 属性进行此操作。它的参数与响应类相同,在响应对象部分中对此进行了说明。它包含以下类:

class scrapy.http.HtmlResponse(url[,status = 200, headers, body, flags])

XmlResponse Objects

它是一个通过查看 XML 行支持编码和自动发现的对象。它的参数与响应类相同,在响应对象部分中对此进行了说明。它包含以下类:

class scrapy.http.XmlResponse(url[, status = 200, headers, body, flags])

Description

顾名思义,链接提取器是可以用于使用 scrapy.http.Response 对象从网页中提取链接的对象。在 Scrapy 中,有内建的提取器,例如 scrapy.linkextractors 导入 LinkExtractor 。您可以通过实现简单界面根据需要自定义您自己的链接提取器。

每个链接提取器都有一个称为 extract_links 的公共方法,它包括一个 Response 对象并返回一个 scrapy.link.Link 对象列表。您只能实例化链接提取器一次,并多次调用 extract_links 方法以使用不同的响应来提取链接。CrawlSpiderclass 使用链接提取器和一组规则,其主要目的是提取链接。

通常,链接提取器与 Scrapy 一起分组,并在 scrapy.linkextractors 模块中提供。默认情况下,链接提取器将是 LinkExtractor,其功能与 LxmlLinkExtractor 相同 −

from scrapy.linkextractors import LinkExtractor

LxmlLinkExtractor

class scrapy.linkextractors.lxmlhtml.LxmlLinkExtractor(allow = (), deny = (),
   allow_domains = (), deny_domains = (), deny_extensions = None, restrict_xpaths = (),
   restrict_css = (), tags = ('a', 'area'), attrs = ('href', ),
   canonicalize = True, unique = True, process_value = None)

LxmlLinkExtractor 是一个强烈推荐的链接提取器,因为它具有方便的过滤选项,并且与 lxml 的强大 HTMLParser 一起使用。

Sr.No

Parameter & Description

1

allow (正则表达式(或列表))它允许一个单个表达式或表达式组与要提取的 url 匹配。如果未提及,它将匹配所有链接。

2

deny (正则表达式(或列表))它阻止或排除与不应提取的 url 匹配的一个表达式或表达式组。如果未提及或留空,则不会消除不需要的链接。

3

allow_domains (str 或列表)它允许一个单个字符串或字符串列表与要从中提取链接的域名匹配。

4

deny_domains (str 或列表)它阻止或排除与不应从中提取链接的域名匹配的一个单个字符串或字符串列表。

5

deny_extensions (列表)在提取链接时,它会阻止带有扩展名的字符串列表。如果未设置,则默认设置为 IGNORED_EXTENSIONS,其中包含 scrapy.linkextractors 包中预定义的列表。

6

restrict_xpaths (str 或列表)它是 XPath 列表区域,从中提取链接的响应。如果给出,链接将仅从由 XPath 选定的文本中提取。

7

restrict_css (str 或列表)它的行为类似于 restrict_xpaths 参数,该参数将从响应中 CSS 选定的区域中提取链接。

8

tags (str 或列表)在提取链接时应考虑的单个标签或标签列表。默认情况下,它将为 (’a’, ’area’)。

9

attrs (列表)在提取链接时应考虑一个单个属性或属性列表。默认情况下,它将为 (’href’,)。

10

canonicalize (布尔值)使用 scrapy.utils.url.canonicalize_url 将提取的 url 转换成标准形式。默认情况下,它将为 True。

11

unique (布尔型)如果提取的链接重复,此布尔型将被使用。

12

process_value (可调用)这是一个接收从扫描标签和属性中获取的值的函数。获取的值可被更改并返回,否则将不会返回任何内容以拒绝链接。如果未被使用,则默认值为 lambda x: x。

Example

以下代码用来提取链接 −

<a href = "javascript:goToPage('../other/page.html'); return false">Link text</a>

以下代码函数可用于 process_value −

def process_value(val):
   m = re.search("javascript:goToPage\('(.*?)'", val)
   if m:
      return m.group(1)

Scrapy - Settings

Description

Scrapy 组件的行为可以通过 Scrapy 设置进行修改。如果你有多个 Scrapy 项目,设置还可以选择当前激活的 Scrapy 项目。

Designating the Settings

当你抓取网站时,你必须通知 Scrapy 你正在使用哪些设置。为此,应该使用环境变量 SCRAPY_SETTINGS_MODULE ,其值应为 Python 路径语法。

Populating the Settings

下表显示了一些可以填充设置的机制−

Sr.No

Mechanism & Description

1

Command line options 此处,传递的参数优先级最高,覆盖其他选项。 -s 用于覆盖一个或多个设置。scrapy crawl myspider -s LOG_FILE = scrapy.log

2

Settings per-spider 通过使用属性 custom_settings,Spider 可以具有自己的设置,从而覆盖 project 设置。class DemoSpider(scrapy.Spider): name = 'demo' custom_settings = { 'SOME_SETTING': 'some value', }

3

Project settings module 此处,您可以填充自定义设置,例如在 settings.py 文件中添加或修改设置。

4

Default settings per-command 每个 Scrapy 工具命令在 default_settings 属性中定义其自己的设置,以覆盖全局默认设置。

5

Default global settings 这些设置可在 scrapy.settings.default_settings 模块中找到。

Access Settings

它们可通过 self.settings 获得,并在初始化后设置在基础 Spider 中。

以下示例演示了这一点。

class DemoSpider(scrapy.Spider):
   name = 'demo'
   start_urls = ['http://example.com']
   def parse(self, response):
      print("Existing settings: %s" % self.settings.attributes.keys())

要在初始化 Spider 之前使用设置,您必须在 Spider 的 init () 方法中覆盖 from_crawler 方法。您可以通过传递给 from_crawler 方法的属性 scrapy.crawler.Crawler.settings 访问设置。

以下示例演示了这一点。

class MyExtension(object):
   def __init__(self, log_is_enabled = False):
      if log_is_enabled:
         print("Enabled log")
         @classmethod
   def from_crawler(cls, crawler):
      settings = crawler.settings
      return cls(settings.getbool('LOG_ENABLED'))

Rationale for Setting Names

设置名称被添加为它们配置的组件的前缀。例如,对于 robots.txt 扩展,设置名称可以是 ROBOTSTXT_ENABLED、 ROBOTSTXT_OBEY、ROBOTSTXT_CACHEDIR 等。

Built-in Settings Reference

下表显示了 Scrapy 的内置设置−

Sr.No

Setting & Description

1

AWS_ACCESS_KEY_ID 用于访问 Amazon Web 服务。默认值:无

2

AWS_SECRET_ACCESS_KEY 用于访问 Amazon Web 服务。默认值:无

3

BOT_NAME 可以用于构造 User-Agent 的 bot 名称。默认值:'scrapybot'

4

CONCURRENT_ITEMS Item Processor 中用于并行处理的现有项的最大数量。默认值:100

5

CONCURRENT_REQUESTS Scrapy 下载器执行的现有请求的最大数量。默认值:16

6

CONCURRENT_REQUESTS_PER_DOMAIN 同时对任何单个域执行的现有请求的最大数量。默认值:8

7

CONCURRENT_REQUESTS_PER_IP 同时对任何单个 IP 执行的现有请求的最大数量。默认值:0

8

DEFAULT_ITEM_CLASS 用于表示项的类。默认值:'scrapy.item.Item'

9

DEFAULT_REQUEST_HEADERS 用于 Scrapy 的 HTTP 请求的默认标头。默认值 −{ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9, / ;q=0.8', 'Accept-Language': 'en',}

10

DEPTH_LIMIT 蜘蛛爬取任何站点的最大深度。默认值: 0

11

DEPTH_PRIORITY 用于根据深度调整请求优先级的整数。默认值: 0

12

DEPTH_STATS 表示是否收集深度统计信息。默认值: True

13

DEPTH_STATS_VERBOSE 当启用此设置时,将为每个详细深度收集统计信息中的请求数量。默认值: False

14

DNSCACHE_ENABLED 用于在内存缓存中启用 DNS。默认值: True

15

DNSCACHE_SIZE 定义内存缓存中 DNS 的大小。默认值: 10000

16

DNS_TIMEOUT 用于设置处理查询的 DNS 超时。默认值: 60

17

DOWNLOADER 用于爬行过程的下载器。默认值: "scrapy.core.downloader.Downloader"

18

DOWNLOADER_MIDDLEWARES 保存下载器中间件及其顺序的字典。默认值: {}

19

DOWNLOADER_MIDDLEWARES_BASE 保存默认启用下载器中间件的字典。默认值 −{ "scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware": 100, }

20

DOWNLOADER_STATS 此设置用于启用下载器统计信息。默认值: True

21

DOWNLOAD_DELAY 定义下载器从站点下载页面之前的时间总数。默认值: 0

22

DOWNLOAD_HANDLERS 含下载处理程序的字典。默认值: {}

23

DOWNLOAD_HANDLERS_BASE 是包含默认启用的下载处理程序的字典。默认值 −{ "file": "scrapy.core.downloader.handlers.file.FileDownloadHandler", }

24

DOWNLOAD_TIMEOUT 是下载器在超时之前等待的总时间。默认值: 180

25

DOWNLOAD_MAXSIZE 是下载器要下载的响应的最大值。默认值: 1073741824 (1024MB)

26

DOWNLOAD_WARNSIZE 定义下载器发出警告的响应大小。默认值: 33554432 (32MB)

27

DUPEFILTER_CLASS 用于检测和筛选重复请求的类。默认值: "scrapy.dupefilters.RFPDupeFilter"

28

DUPEFILTER_DEBUG 将所有重复过滤器记录在这项设置为 true 时。默认值: False

29

EDITOR 它用于使用编辑命令编辑爬虫。默认值:取决于环境

30

EXTENSIONS 这是一个包含在项目中启用的扩展的字典。默认值:{}

31

EXTENSIONS_BASE 这是一个包含内置扩展的字典。默认值:{ 'scrapy.extensions.corestats.CoreStats': 0, }

32

FEED_TEMPDIR 这是一个目录,用于设置自定义文件夹,其中可以存储爬虫临时文件。

33

ITEM_PIPELINES 这是一个包含管道的字典。默认值:{}

34

LOG_ENABLED 它定义是否启用日志记录。默认值:True

35

LOG_ENCODING 它定义用于日志记录的编码类型。默认值:'utf-8'

36

LOG_FILE 这是用于日志记录输出的文件的名称。默认值:None

37

LOG_FORMAT 它是一个字符串,可用于设置日志消息格式。默认值:'%(asctime)s [%(name)s] %(levelname)s: %(message)s'

38

LOG_DATEFORMAT 这是一个字符串,可用于设置日期/时间格式。默认值:'%Y-%m-%d %H:%M:%S'

39

LOG_LEVEL 它定义最小日志级别。默认值:'DEBUG'

40

LOG_STDOUT 如果此设置设为 true,则所有进程输出将显示在日志中。默认值:False

41

MEMDEBUG_ENABLED 它定义是否启用内存调试。默认值:False

42

MEMDEBUG_NOTIFY 它定义在启用内存调试时发送到特定地址的内存报告。默认值:[]

43

MEMUSAGE_ENABLED 它定义当 Scrapy 进程超过内存限制时是否启用内存使用。默认值:False

44

MEMUSAGE_LIMIT_MB 它定义允许的最大内存限制(以兆字节为单位)。默认值:0

45

MEMUSAGE_CHECK_INTERVAL_SECONDS 它用于通过设置间隔长度检查当前的内存使用情况。默认值:60.0

46

MEMUSAGE_NOTIFY_MAIL 它用于在内存达到限制时通过电子邮件列表进行通知。默认值:False

47

MEMUSAGE_REPORT 它定义在关闭每个爬虫时是否发送内存使用情况报告。默认值:False

48

MEMUSAGE_WARNING_MB 在发出警告之前,它定义了允许的总内存。默认值:0

49

NEWSPIDER_MODULE 它是一个使用 genspider 命令创建新蜘蛛的模块。默认值:''

50

RANDOMIZE_DOWNLOAD_DELAY 它定义了 Scrapy 在从网站下载请求时等待的随机时间量。默认值:True

51

REACTOR_THREADPOOL_MAXSIZE 它定义了反应堆线程池的最大大小。默认值:10

52

REDIRECT_MAX_TIMES 它定义了请求可以被重定向的次数。默认值:20

53

REDIRECT_PRIORITY_ADJUST 设置此设置时,调整请求的重定向优先级。默认值:+2

54

RETRY_PRIORITY_ADJUST 设置此设置时,调整请求的重试优先级。默认值:-1

55

ROBOTSTXT_OBEY 当设置为 true 时,Scrapy 遵守 robots.txt 策略。默认值:False

56

SCHEDULER 它定义了用于爬网目的的调度程序。默认值:'scrapy.core.scheduler.Scheduler'

57

SPIDER_CONTRACTS 它是项目中的一个字典,其中包含要测试蜘蛛的蜘蛛合同。默认值:{}

58

SPIDER_CONTRACTS_BASE 它是一个包含 Scrapy 合同的字典,默认情况下在 Scrapy 中启用。默认值 −{ 'scrapy.contracts.default.UrlContract' : 1, 'scrapy.contracts.default.ReturnsContract': 2,}

59

SPIDER_LOADER_CLASS 它定义了一个实现 SpiderLoader API 以加载蜘蛛的类。默认值:'scrapy.spiderloader.SpiderLoader'

60

SPIDER_MIDDLEWARES 它是一个包含蜘蛛中间件的字典。默认值:{}

61

SPIDER_MIDDLEWARES_BASE 它是一个包含默认情况下在 Scrapy 中启用的蜘蛛中间件的字典。默认值 −{ 'scrapy.spidermiddlewares.httperror.HttpErrorMiddleware': 50,}

62

SPIDER_MODULES 它是一个包含 Scrapy 将查找的包含蜘蛛的模块的列表。默认值:[]

63

STATS_CLASS 它是一个实现统计收集器 API 以收集统计信息的类。默认值:'scrapy.statscollectors.MemoryStatsCollector'

64

STATS_DUMP 当此设置设置为 true 时,将统计信息转储到日志中。默认值:True

65

STATSMAILER_RCPTS 在蜘蛛完成抓取后,Scrapy 使用此设置发送统计信息。默认值:[]

66

TELNETCONSOLE_ENABLED 它定义了是否启用 telnet 控制台。默认值:True

67

TELNETCONSOLE_PORT 它为 telnet 控制台定义了一个端口。默认值:[6023, 6073]

68

TEMPLATES_DIR 它是一个包含模板的目录,这些模板可在创建新项目时使用。默认值:scrapy 模块内部的 templates 目录

69

URLLENGTH_LIMIT 它定义允许爬取 URL 的 URL 长度最大限制。默认值:2083

70

USER_AGENT 它定义在爬取网站时要使用的 user agent。默认值:"Scrapy/VERSION (+http://scrapy.org)"

有关其他 Scrapy 设置,请访问此 link

Scrapy - Exceptions

Description

不规则的事件称为异常。在 Scrapy 中,异常是由配置缺失、从项目管道删除项目等原因引发的。以下是 Scrapy 中提到的异常及其应用程序列表。

DropItem

项目管道利用此异常在任何阶段停止处理项目。它可以写成−

exception (scrapy.exceptions.DropItem)

CloseSpider

此异常用于停止使用回调请求的蜘蛛。它可以写成−

exception (scrapy.exceptions.CloseSpider)(reason = 'cancelled')

它包含一个名为原因 (str) 的参数,该参数指定关闭的原因。

例如,以下代码显示了此异常用法−

def parse_page(self, response):
   if 'Bandwidth exceeded' in response.body:
      raise CloseSpider('bandwidth_exceeded')

IgnoreRequest

此异常由调度程序或下载器中间件用于忽略请求。它可以写成−

exception (scrapy.exceptions.IgnoreRequest)

NotConfigured

它表示缺少配置的情况,并且应该在组件构造函数中引发。

exception (scrapy.exceptions.NotConfigured)

如果以下任何组件停用,都可能会引发此异常。

  1. Extensions

  2. Item pipelines

  3. Downloader middlewares

  4. Spider middlewares

NotSupported

如果某个特性或方法不受支持,将会引发此异常。可将其写为:

exception (scrapy.exceptions.NotSupported)

Scrapy - Create a Project

Description

要从网页中获取数据,首先需要创建你将存储代码的 Scrapy 项目。要创建新目录,运行以下命令:

scrapy startproject first_scrapy

上面的代码将创建一个名为 first_scrapy 的目录,它将包含以下结构:

first_scrapy/
scrapy.cfg            # deploy configuration file
first_scrapy/         # project's Python module, you'll import your code from here
__init__.py
items.py              # project items file
pipelines.py          # project pipelines file
settings.py           # project settings file
spiders/              # a directory where you'll later put your spiders
__init__.py

Scrapy - Define an Item

Description

项目是用于收集从网站获取的数据的容器。你必须通过定义你的项目来启动你的爬虫。要定义项目,编辑在目录 first_scrapy 下找到的 items.py 文件(自定义目录)。items.py 看起来如下:

import scrapy

class First_scrapyItem(scrapy.Item):
   # define the fields for your item here like:
      # name = scrapy.Field()

MyItem 类继承了包含一系列 Scrapy 已经为我们构建的预定义对象的 Item。例如,如果你想从站点中提取名称、URL 和描述,则需要为这三个属性中的每一个定义字段。

因此,让我们添加我们要收集的那些项目:

from scrapy.item import Item, Field

class First_scrapyItem(scrapy.Item):
   name = scrapy.Field()
   url = scrapy.Field()
   desc = scrapy.Field()

Scrapy - First Spider

Description

Spider 是一个类,它定义了从哪里提取数据的初始 URL,以及如何遵循分页链接以及如何提取和解析 items.py 中定义的字段。Scrapy 提供不同类型的蜘蛛,每种蜘蛛都给出了一个特定目的。

在 first_scrapy/spiders 目录下创建一个名为 "first_spider.py" 的文件,在那里我们可以告诉 Scrapy 如何找到我们正在寻找的确切数据。为此,你必须定义一些属性:

  1. name - 它定义了蜘蛛的唯一名称。

  2. allowed_domains - 它包含蜘蛛要爬取的基本 URL。

  3. start-urls − 蜘蛛开始爬行的 URL 列表。

  4. parse() − 它是用来提取和解析所爬取数据的函数。

以下代码演示了一个爬虫代码的样例 −

import scrapy

class firstSpider(scrapy.Spider):
   name = "first"
   allowed_domains = ["dmoz.org"]

   start_urls = [
      "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
      "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
   ]
   def parse(self, response):
      filename = response.url.split("/")[-2] + '.html'
      with open(filename, 'wb') as f:
         f.write(response.body)

Scrapy - Crawling

Description

要执行你的爬虫程序,在 first_scrapy 目录中运行以下命令 −

scrapy crawl first

其中, first 是创建爬虫程序时指定的爬虫程序名称。

爬虫程序爬取后,可以看到以下输出 −

2016-08-09 18:13:07-0400 [scrapy] INFO: Scrapy started (bot: tutorial)
2016-08-09 18:13:07-0400 [scrapy] INFO: Optional features available: ...
2016-08-09 18:13:07-0400 [scrapy] INFO: Overridden settings: {}
2016-08-09 18:13:07-0400 [scrapy] INFO: Enabled extensions: ...
2016-08-09 18:13:07-0400 [scrapy] INFO: Enabled downloader middlewares: ...
2016-08-09 18:13:07-0400 [scrapy] INFO: Enabled spider middlewares: ...
2016-08-09 18:13:07-0400 [scrapy] INFO: Enabled item pipelines: ...
2016-08-09 18:13:07-0400 [scrapy] INFO: Spider opened
2016-08-09 18:13:08-0400 [scrapy] DEBUG: Crawled (200)
<GET http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> (referer: None)
2016-08-09 18:13:09-0400 [scrapy] DEBUG: Crawled (200)
<GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> (referer: None)
2016-08-09 18:13:09-0400 [scrapy] INFO: Closing spider (finished)

正如你可以在输出中看到的,对于每个 URL 都有一个日志行,该日志行(引用:无)指出 URL 是开始 URL,并且它们没有引用。接下来,你应该看到在 first_scrapy 目录中创建了两个新文件,命名为 Books.html 和 Resources.html。

Scrapy - Extracting Items

Description

为了从网页中提取数据,Scrapy 使用了一种基于 XPathCSS 表达式的选择器技术。以下是 XPath 表达式的一些示例 −

  1. /html/head/title − 这将选择 HTML 文档的 <head> 元素内的 <title> 元素。

  2. /html/head/title/text() − 这将选择同一个 <title> 元素内的文本。

  3. //td − 这将选择所有来自 <td> 的元素。

  4. //div[@class = "slice"] − 这将选择所有来自 div 的元素,其中包含属性 class = "slice"

选择器有四个基本的方法,如下表所示 −

Sr.No

Method & Description

1

extract() 它返回一个 unicode 字符串和选择的数据。

2

re() 返回 unicode 字符串列表,当提供正则表达式作为参数时会提取它们。

3

xpath() 返回一个选择器列表,它表示由作为参数给出的 xpath 表达式选定的节点。

4

css() 返回选择器列表,它表示由作为参数给出的 CSS 表达式选定的节点。

Using Selectors in the Shell

要使用内置的 Scrapy 外壳演示选择器,你需要在你的系统中安装 IPython 。这里的重要事项是,在运行 Scrapy 时,URL 应该包含在引号内;否则带有“&”字符的 URL 将不起作用。你可以使用以下命令在项目的顶级目录中启动外壳 −

scrapy shell "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/"

一个外壳将如下所示 −

[ ... Scrapy log here ... ]

2014-01-23 17:11:42-0400 [scrapy] DEBUG: Crawled (200)
<GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>(referer: None)
[s] Available Scrapy objects:
[s]   crawler    <scrapy.crawler.Crawler object at 0x3636b50>
[s]   item       {}
[s]   request    <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
[s]   response   <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
[s]   settings   <scrapy.settings.Settings object at 0x3fadc50>
[s]   spider     <Spider 'default' at 0x3cebf50>
[s] Useful shortcuts:
[s]   shelp()           Shell help (print this help)
[s]   fetch(req_or_url) Fetch request (or URL) and update local objects
[s]   view(response)    View response in a browser

In [1]:

当外壳加载时,你可以分别使用 response.body 和 response.header 访问正文或标题。类似地,你可以使用 response.selector.xpath() 或 response.selector.css() 对响应运行查询。

例如 −

In [1]: response.xpath('//title')
Out[1]: [<Selector xpath = '//title' data = u'<title>My Book - Scrapy'>]

In [2]: response.xpath('//title').extract()
Out[2]: [u'<title>My Book - Scrapy: Index: Chapters</title>']

In [3]: response.xpath('//title/text()')
Out[3]: [<Selector xpath = '//title/text()' data = u'My Book - Scrapy: Index:'>]

In [4]: response.xpath('//title/text()').extract()
Out[4]: [u'My Book - Scrapy: Index: Chapters']

In [5]: response.xpath('//title/text()').re('(\w+):')
Out[5]: [u'Scrapy', u'Index', u'Chapters']

Extracting the Data

要从一个普通 HTML 站点中提取数据,我们必须检查该站点的源代码来获取 XPath。检查后,你会看到数据将位于 ul 标签中。选择 li 标签内的元素。

以下代码行显示了不同类型数据的提取 −

对于 li 标签中选择数据 −

response.xpath('//ul/li')

对于选择描述 −

response.xpath('//ul/li/text()').extract()

对于选择网站标题 −

response.xpath('//ul/li/a/text()').extract()

对于选择网站链接 −

response.xpath('//ul/li/a/@href').extract()

以下代码证明了上述提取器的使用 −

import scrapy

class MyprojectSpider(scrapy.Spider):
   name = "project"
   allowed_domains = ["dmoz.org"]

   start_urls = [
      "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
      "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
   ]
   def parse(self, response):
      for sel in response.xpath('//ul/li'):
         title = sel.xpath('a/text()').extract()
         link = sel.xpath('a/@href').extract()
         desc = sel.xpath('text()').extract()
         print title, link, desc

Scrapy - Using an Item

Description

Item 对象是 Python 的正规字典。我们可以使用以下语法来访问类的属性 −

>>> item = DmozItem()
>>> item['title'] = 'sample title'
>>> item['title']
'sample title'

将以上代码添加到以下示例 −

import scrapy

from tutorial.items import DmozItem

class MyprojectSpider(scrapy.Spider):
   name = "project"
   allowed_domains = ["dmoz.org"]

   start_urls = [
      "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
      "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
   ]
   def parse(self, response):
      for sel in response.xpath('//ul/li'):
         item = DmozItem()
         item['title'] = sel.xpath('a/text()').extract()
         item['link'] = sel.xpath('a/@href').extract()
         item['desc'] = sel.xpath('text()').extract()
         yield item

以上爬虫的输出将是 −

[scrapy] DEBUG: Scraped from <200
http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
   {'desc': [u' - By David Mertz; Addison Wesley. Book in progress, full text,
      ASCII format. Asks for feedback. [author website, Gnosis Software, Inc.\n],
   'link': [u'http://gnosis.cx/TPiP/'],
   'title': [u'Text Processing in Python']}
[scrapy] DEBUG: Scraped from <200
http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
   {'desc': [u' - By Sean McGrath; Prentice Hall PTR, 2000, ISBN 0130211192,
      has CD-ROM. Methods to build XML applications fast, Python tutorial, DOM and
      SAX, new Pyxie open source XML processing library. [Prentice Hall PTR]\n'],
   'link': [u'http://www.informit.com/store/product.aspx?isbn=0130211192'],
   'title': [u'XML Processing with Python']}

Description

在本章中,我们将学习如何提取我们感兴趣的页面的链接,跟踪它们并从该页面提取数据。为此,我们需要对我们的 previous code 作出如下更改:

import scrapy
from tutorial.items import DmozItem

class MyprojectSpider(scrapy.Spider):
   name = "project"
   allowed_domains = ["dmoz.org"]

   start_urls = [
      "http://www.dmoz.org/Computers/Programming/Languages/Python/",
   ]
   def parse(self, response):
      for href in response.css("ul.directory.dir-col > li > a::attr('href')"):
         url = response.urljoin(href.extract())
            yield scrapy.Request(url, callback = self.parse_dir_contents)

   def parse_dir_contents(self, response):
      for sel in response.xpath('//ul/li'):
         item = DmozItem()
         item['title'] = sel.xpath('a/text()').extract()
         item['link'] = sel.xpath('a/@href').extract()
         item['desc'] = sel.xpath('text()').extract()
         yield item

上面的代码包含以下方法-

  1. parse() - 它将提取我们感兴趣的链接。

  2. response.urljoin - parse() 方法将使用这种方法来构建一个新的 url 并提供一个新的请求,稍后会将其发送到 callback。

  3. parse_dir_contents() − 这项回叫实际将抓取所需信息。

在此处,Scrapy 使用回叫机制来跟踪链接。利用该机制,可以设计更大的爬虫并且可以跟踪所需的链接以从不同的页面中抓取所需信息。常规方法将是回叫方法,该方法将提取数据项,查找链接来跟踪到下一页,然后针对相同的回叫提供请求。

以下示例生成一个循环,该循环将跟踪链接到下一页。

def parse_articles_follow_next_page(self, response):
   for article in response.xpath("//article"):
      item = ArticleItem()

      ... extract article data here

      yield item

   next_page = response.css("ul.navigation > li.next-page > a::attr('href')")
   if next_page:
      url = response.urljoin(next_page[0].extract())
      yield scrapy.Request(url, self.parse_articles_follow_next_page)

Scrapy - Scraped Data

Description

存储抓取数据的最佳方法是使用 Feed 导出,这确保了使用多种序列化格式正确地存储数据。JSON、JSON 行、CSV、XML 是序列化格式中现有的格式。可以通过以下命令存储数据 −

scrapy crawl dmoz -o data.json

此命令将创建一个 data.json 文件,其中包含 JSON 格式的抓取数据。此方法适用于小量数据。如果必须处理大量数据,那么我们可以使用 Item Pipeline。就像 data.json 文件,在项目在 tutorial/pipelines.py 中创建时会设置保留文件。

Scrapy - Logging

Description

Logging 表示使用内置日志系统进行的事件跟踪,并定义用于实现应用程序和库的功能和类。日志记录是一种可随时使用的材料,它可以与记录设置中列出的 Scrapy 设置配合使用。

在运行命令时,Scrapy 会设置一些默认设置,并通过 scrapy.utils.log.configure_logging() 处理这些设置。

Log levels

在 Python 中,一个日志消息具有五种不同的严重程度级别。以下列表以升序列出了标准日志消息 -

  1. logging.DEBUG – 用于调试消息(严重程度最低)

  2. logging.INFO – 用于信息消息

  3. logging.WARNING – 用于警告消息

  4. logging.ERROR – 用于一般错误

  5. logging.CRITICAL − 用于严重错误(最高级别)

How to Log Messages

下面的代码显示使用 logging.info 级别记录消息。

import logging
logging.info("This is an information")

上述记录消息可以用 logging.log 作为参数,显示如下:

import logging
logging.log(logging.INFO, "This is an information")

现在,你还可以使用记录器用日志助手日志将消息包含起来以清楚地显示出日志消息,如下所示:

import logging
logger = logging.getLogger()
logger.info("This is an information")

可以有多个记录器,可以通过使用 logging.getLogger 函数获取其名称来访问它们,显示如下。

import logging
logger = logging.getLogger('mycustomlogger')
logger.info("This is an information")

对于任何模块,可以使用 name 变量来使用自定义记录器,它包含了模块路径,如下所示:

import logging
logger = logging.getLogger(__name__)
logger.info("This is an information")

Logging from Spiders

每个爬取器实例都拥有一个 logger ,并可以使用,如下所示:

import scrapy

class LogSpider(scrapy.Spider):
   name = 'logspider'
   start_urls = ['http://dmoz.com']
   def parse(self, response):
      self.logger.info('Parse function called on %s', response.url)

在上面的代码中,记录器是使用爬取器的名称创建的,但是你可以使用 Python 提供的任何自定义记录器,如下所示:

import logging
import scrapy

logger = logging.getLogger('customizedlogger')
class LogSpider(scrapy.Spider):
   name = 'logspider'
   start_urls = ['http://dmoz.com']

   def parse(self, response):
      logger.info('Parse function called on %s', response.url)

Logging Configuration

记录器无法自行显示它们发送的消息。因此,它们需要“处理器”来显示这些消息,而处理器会将这些消息重定向到各自的目的地,如文件、电子邮件和标准输出。

根据下列设置,Scrapy 会为记录器配置处理器。

Logging Settings

下列设置用于配置日志 −

  1. LOG_FILELOG_ENABLED 决定了日志消息的目标。

  2. 当你把 LOG_ENCODING 设置为 false 时,它将不会显示日志输出信息。

  3. LOG_LEVEL 将确定消息的严重程度顺序;严重程度较低的消息将被过滤掉。

  4. LOG_FORMATLOG_DATEFORMAT 用于为所有消息指定布局。

  5. 当你把 LOG_STDOUT 设置为 true,所有标准输出和错误信息的过程都会重定向到日志。

Command-line Options

可以通过传递命令行参数来覆盖 Scrapy 设置,如下表所示:

Sr.No

Command & Description

1

--logfile FILE Overrides LOG_FILE

2

--loglevel/-L LEVEL Overrides LOG_LEVEL

3

--nolog Sets LOG_ENABLED to False

scrapy.utils.log module

此函数可用于初始化 Scrapy 的默认日志记录。

scrapy.utils.log.configure_logging(settings = None, install_root_handler = True)

Sr.No

Parameter & Description

1

settings (dict, None) 它创建并配置根记录器的处理器。默认情况下,它是 None。

2

install_root_handler (bool) 它指定安装根日志处理程序。默认情况下,它为 True。

以上函数 −

  1. 通过 Python 标准日志记录路由警告和 Twisted 日志记录。

  2. 将 DEBUG 分配给 Scrapy 和 ERROR 级别分配给 Twisted 日志记录器。

  3. 如果 LOG_STDOUT 设置为 true,则将 stdout 路由到日志。

可以使用 settings 参数覆盖默认选项。当未指定设置时,则使用默认值。当 install_root_handler 设为 true 时,可以为根日志记录器创建处理程序。如果将其设为 false,则不会设置任何日志输出。在使用 Scrapy 命令时,configure_logging 将自动调用,并且在运行自定义脚本时可以显式运行。

若要手动配置日志记录输出,可以使用 logging.basicConfig() ,如下所示 −

import logging
from scrapy.utils.log import configure_logging

configure_logging(install_root_handler = False)
logging.basicConfig (
   filename = 'logging.txt',
   format = '%(levelname)s: %(your_message)s',
   level = logging.INFO
)

Scrapy - Stats Collection

Description

状态收集器是 Scrapy 提供的一个工具,用于收集以键/值形式表示的状态,并且是通过爬虫 API(爬虫提供对所有 Scrapy 核心组件的访问)进行访问的。状态收集器为每个爬虫提供一个状态表,状态收集器在爬虫打开时自动打开该表并在爬虫关闭时关闭该表。

Common Stats Collector Uses

以下代码使用 stats 属性访问该统计收集器。

class ExtensionThatAccessStats(object):
   def __init__(self, stats):
      self.stats = stats

   @classmethod
   def from_crawler(cls, crawler):
      return cls(crawler.stats)

下表显示了可以使用各种选项和统计收集器 -

Sr.No

Parameters

Description

1

stats.set_value('hostname', socket.gethostname())

用于设置统计值。

2

stats.inc_value('customized_count')

将增加统计值。

3

stats.max_value('max_items_scraped', value)

只有大于之前的值时才能设置统计值。

4

stats.min_value('min_free_memory_percent', value)

只有小于之前的值时才能设置统计值。

5

stats.get_value('customized_count')

获取统计值。

6

stats.get_stats() {'custom_count': 1, 'start_time':datetime.datetime(2009, 7, 14, 21, 47, 28, 977139)}

获取所有统计信息

Available Stats Collectors

Scrapy 提供不同类型的统计收集器,可以使用 STATS_CLASS 设置访问它。

MemoryStatsCollector

这是默认统计集合器,它维护用于抓取内容的每个蜘蛛的统计信息,而数据将存储在内存中。

class scrapy.statscollectors.MemoryStatsCollector

DummyStatsCollector

此统计集合器非常有效,不做任何事。可以使用 STATS_CLASS 设置对它进行设置,并用于禁用统计集合以提高性能。

class scrapy.statscollectors.DummyStatsCollector

Scrapy - Sending an E-mail

Description

Scrapy 可以使用其名为 Twisted non-blocking IO 的自有工具发送电子邮件,该工具远离爬虫程序的非阻塞 IO。你可以配置发送电子邮件的一些设置,并提供用于发送附件的简单 API。

共有两种实例化 MailSender 的方法,如下表所示 −

Sr.No

Parameters

Method

1

from scrapy.mail import MailSender mailer = MailSender()

通过使用标准构造函数。

2

mailer = MailSender.from_settings(settings)

通过使用 Scrapy 设置对象。

以下代码行发送不带附件的电子邮件 −

mailer.send(to = ["receiver@example.com"], subject = "subject data", body = "body data",
   cc = ["list@example.com"])

MailSender Class Reference

MailSender 类使用 Twisted non-blocking IO 从 Scrapy 发送电子邮件。

class scrapy.mail.MailSender(smtphost = None, mailfrom = None, smtpuser = None,
   smtppass = None, smtpport = None)

以下表格显示了 MailSender 类中使用的参数 −

Sr.No

Parameter & Description

1

smtphost (str) SMTP 主机用于发送电子邮件。如果没有,则会使用 MAIL_HOST 设置。

2

mailfrom (str) 收件人地址用于发送电子邮件。如果没有,则会使用 MAIL_FROM 设置。

3

smtpuser 它指定 SMTP 用户。如果没有使用,则会使用 MAIL_USER 设置,并且如果未提及,则没有 SMTP 验证。

4

smtppass (str) 它指定用于验证的 SMTP 密码。

5

smtpport (int) 它指定用于连接的 SMTP 端口。

6

smtptls (boolean) 它使用 SMTP STARTTLS 实现。

7

smtpssl (boolean) 它使用安全 SSL 连接进行管理。

参考中指定了 MailSender 类中具有以下两个方法。第一个方法,

classmethod from_settings(settings)

它通过使用 Scrapy 设置对象合并。它包含以下参数 −

settings (scrapy.settings.Settings object) − 它被视为电子邮件接收者。

另一种方法,

send(to, subject, body, cc = None, attachs = (), mimetype = 'text/plain', charset = None)

下表包含了上述方法的参数 −

Sr.No

Parameter & Description

1

to (list) 它指的是电子邮件接收者。

2

subject (str) 它指定电子邮件的主题。

3

cc (list) 它指的是接收者列表。

4

body (str) 此处指电子邮件正文数据。

5

attachs (iterable) 此处指电子邮件的附件、附件的 MIME 类型和附件的名称。

6

mimetype (str) 它表示电子邮件的 MIME 类型。

7

charset (str) 它指定了电子邮件内容使用的字符编码。

Mail Settings

通过以下设置确保无需编写任何代码,即可使用项目中的 MailSender 类配置电子邮件。

Sr.No

Settings & Description

Default Value

1

MAIL_FROM 此处指发送电子邮件的发件人电子邮件。

'scrapy@localhost'

2

MAIL_HOST 此处指用于发送电子邮件的 SMTP 主机。

'localhost'

3

MAIL_PORT 此处指定了用于发送电子邮件的 SMTP 端口。

25

4

MAIL_USER 此处指 SMTP 验证。如果此设置设为禁用,则不会进行任何验证。

None

5

MAIL_PASS 此处提供了用于 SMTP 验证的密码。

None

6

MAIL_TLS 此处提供了使用 SSL/TLS 将不安全的连接升级为安全连接的方法。

False

7

MAIL_SSL 它使用 SSL 加密连接实现连接。

False

Scrapy - Telnet Console

Description

Telnet 控制台是一个 Python 外壳,该外壳在 Scrapy 流程内部运行,用于检查和控制要运行的 Scrapy 流程。

Access Telnet Console

可以使用以下命令访问 telnet 控制台 −

telnet localhost 6023

基本上,telnet 控制台在 TELNETCONSOLE_PORT 中所述的 TCP 端口中列出。

Variables

下表中所述的某些默认变量用作快捷方式 −

Sr.No

Shortcut & Description

1

crawler 它引用 Scrapy 爬虫 (scrapy.crawler.Crawler) 对象。

2

engine 它引用 Crawler.engine 属性。

3

spider 它引用处于活动状态的爬虫。

4

slot 它引用引擎槽。

5

extensions 它引用扩展管理器 (Crawler.extensions) 属性。

6

stats 它引用状态收集器 (Crawler.stats) 属性。

7

setting 它引用 Scrapy 设置对象 (Crawler.settings) 属性。

8

est 它引用打印引擎状态报告。

9

prefs 它引用用于调试的内存。

10

p 它引用 pprint.pprint 函数的快捷方式。

11

hpy 它引用内存调试。

Examples

以下是使用 Telnet 控制台说明的一些示例。

Pause, Resume and Stop the Scrapy Engine

要暂停 Scrapy 引擎,请使用以下命令 -

telnet localhost 6023
>>> engine.pause()
>>>

要恢复 Scrapy 引擎,请使用以下命令 -

telnet localhost 6023
>>> engine.unpause()
>>>

要停止 Scrapy 引擎,请使用以下命令 -

telnet localhost 6023
>>> engine.stop()
Connection closed by foreign host.

View Engine Status

Telnet 控制台使用 est() 方法检查 Scrapy 引擎状态,如下面的代码中所示 -

telnet localhost 6023
>>> est()
Execution engine status

time()-engine.start_time                        : 8.62972998619
engine.has_capacity()                           : False
len(engine.downloader.active)                   : 16
engine.scraper.is_idle()                        : False
engine.spider.name                              : followall
engine.spider_is_idle(engine.spider)            : False
engine.slot.closing                             : False
len(engine.slot.inprogress)                     : 16
len(engine.slot.scheduler.dqs or [])            : 0
len(engine.slot.scheduler.mqs)                  : 92
len(engine.scraper.slot.queue)                  : 0
len(engine.scraper.slot.active)                 : 0
engine.scraper.slot.active_size                 : 0
engine.scraper.slot.itemproc_size               : 0
engine.scraper.slot.needs_backout()             : False

Telnet Console Signals

你可以使用 telnet 控制台信号在 telnet 本地命名空间添加、更新或删除变量。要执行此操作,你需要在处理程序中添加 telnet_vars 字典。

scrapy.extensions.telnet.update_telnet_vars(telnet_vars)

参数 -

telnet_vars (dict)

其中,dict 是一个包含 telnet 变量的字典。

Telnet Settings

下表显示控制 Telnet 控制台行为的设置 -

Sr.No

Settings & Description

Default Value

1

TELNETCONSOLE_PORT 这表示 telnet 控制台的端口范围。如果将其设置为 none,那么将动态分配端口。

[6023, 6073]

2

TELNETCONSOLE_HOST 这表示 telnet 控制台应侦听的接口。

'127.0.0.1'

Scrapy - Web Services

Description

一个正在运行的 Scrapy 网络爬虫可以通过 JSON-RPC 控制。它通过 JSONRPC_ENABLED 设置启用。此服务通过 JSON-RPC 2.0 协议提供对主爬虫对象的访问。用于访问爬虫程序对象的端点为 −

http://localhost:6080/crawler

下表包含显示 Web 服务行为的一些设置 −

Sr.No

Setting & Description

Default Value

1

JSONRPC_ENABLED 这指布尔值,它决定 Web 服务及其扩展名是否启用。

True

2

JSONRPC_LOGFILE 这指用于记录向 Web 服务发出的 HTTP 请求的文件。如果未设置,将使用标准 Scrapy 日志。

None

3

JSONRPC_PORT 这指 Web 服务的端口范围。如果设置为无,则将动态分配端口。

[6080, 7030]

4

JSONRPC_HOST 这指 Web 服务应监听的接口。

'127.0.0.1'