Scrapy - 快速指南



Scrapy - 概述

Scrapy 是一个用 Python 编写的快速、开源的网页爬取框架,用于利用基于 XPath 的选择器从网页中提取数据。

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

为什么要使用 Scrapy?

  • 构建和扩展大型爬取项目更容易。

  • 它有一个名为选择器的内置机制,用于从网站提取数据。

  • 它异步处理请求并且速度很快。

  • 它使用 自动限速机制 自动调整爬取速度。

  • 确保开发者可访问性。

Scrapy 的特性

  • Scrapy 是一个开源且免费使用的网页爬取框架。

  • Scrapy 生成以 JSON、CSV 和 XML 等格式的数据导出。

  • Scrapy 内置支持通过 XPath 或 CSS 表达式从源选择和提取数据。

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

优点

  • Scrapy 易于扩展,快速且强大。

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

  • Scrapy 请求被异步调度和处理。

  • Scrapy 带有一个名为 Scrapyd 的内置服务,允许使用 JSON Web 服务上传项目和控制爬虫。

  • 即使网站没有用于原始数据访问的 API,也可以抓取任何网站。

缺点

  • Scrapy 仅适用于 Python 2.7 及以上版本。

  • 不同操作系统的安装方式不同。

Scrapy - 环境

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

Scrapy 可以使用 pip 安装。要安装,请运行以下命令:

pip install Scrapy

Windows

注意 - Windows 操作系统不支持 Python 3。

步骤 1 - 从 Python 安装 Python 2.7

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

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

可以使用以下命令检查 Python 版本:

python --version

步骤 2 - 安装 OpenSSL

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

注意 - 除 Windows 外,所有操作系统都预装了 OpenSSL。

步骤 3 - 安装 Visual C++ 2008 可再发行组件。

步骤 4 - 安装 pywin32

步骤 5 - 为低于 2.7.9 的 Python 版本安装 pip

可以使用以下命令检查 pip 版本:

pip --version

步骤 6 - 要安装 scrapy,请运行以下命令:

pip install Scrapy

Anaconda

如果您的机器上安装了 anacondaminiconda,请运行以下命令使用 conda 安装 Scrapy:

conda install -c scrapinghub scrapy 

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

注意 - 如果您在通过 pip 安装时遇到问题,建议使用上述命令安装 Scrapy。

Ubuntu 9.10 或更高版本

Ubuntu 操作系统预装了最新版本的 Python。使用 Scrapinghub 提供的 Ubuntu 包 aptgettable。要使用这些包:

步骤 1 - 您需要将用于签署 Scrapy 包的 GPG 密钥导入到 APT 密钥环中:

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

步骤 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

步骤 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,而是安装一个新的更新版本,以免与系统其他部分冲突。

步骤 1 - 安装 homebrew

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

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

步骤 3 - 为了确保更改已完成,请使用以下命令重新加载 .bashrc

source ~/.bashrc 

步骤 4 - 接下来,使用以下命令安装 Python:

brew install python

步骤 5 - 使用以下命令安装 Scrapy:

pip install Scrapy

Scrapy - 命令行工具

描述

Scrapy 命令行工具用于控制 Scrapy,通常称为 'Scrapy 工具'。它包含用于各种对象的命令,以及一组参数和选项。

配置设置

Scrapy 将在 scrapy.cfg 文件中查找配置设置。以下是一些位置:

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

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

  • 您可以在项目的根目录中找到 scrapy.cfg。

Scrapy 也可以使用以下环境变量进行配置:

  • SCRAPY_SETTINGS_MODULE
  • SCRAPY_PROJECT
  • SCRAPY_PYTHON_SHELL

Scrapy 项目的默认结构

以下结构显示了 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 = https://127.0.0.1:6800/ 
project = [name of the project] 

使用 Scrapy 工具

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

创建项目

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

scrapy startproject project_name

这将创建名为 project_name 的项目目录。接下来,使用以下命令转到新创建的项目:

cd  project_name

控制项目

您可以使用 Scrapy 工具控制项目并对其进行管理,还可以使用以下命令创建新的爬虫:

scrapy genspider mydomain mydomain.com

诸如 crawl 等命令必须在 Scrapy 项目内部使用。在接下来的部分中,您将了解哪些命令必须在 Scrapy 项目内部运行。

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

scrapy -h

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

  • fetch - 它使用 Scrapy 下载器获取 URL。

  • runspider - 用于运行自包含的爬虫,无需创建项目。

  • settings - 它指定项目设置值。

  • shell - 它是给定 URL 的交互式抓取模块。

  • startproject - 创建一个新的 Scrapy 项目。

  • version - 显示 Scrapy 版本。

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

您还可以使用一些与项目相关的命令,如下所示:

  • crawl - 用于使用爬虫爬取数据。

  • check - 检查爬取命令返回的项目。

  • list - 显示项目中所有可用爬虫的列表。

  • edit - 您可以使用编辑器编辑爬虫。

  • parse - 使用爬虫解析给定的 URL。

  • bench - 用于运行快速基准测试(基准测试告诉 Scrapy 每分钟可以爬取多少个页面)。

自定义项目命令

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

COMMANDS_MODULE = 'mycmd.commands'

Scrapy 命令可以通过 setup.py 文件中的 scrapy.commands 部分添加,如下所示:

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 - 爬虫

描述

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

Scrapy 的默认爬虫如下:

scrapy.Spider

它是一个爬虫,所有其他爬虫都必须继承它。它具有以下类:

class scrapy.spiders.Spider

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

序号 字段 & 描述
1

name

它是您的爬虫的名称。

2

allowed_domains

它是爬虫爬取的域名的列表。

3

start_urls

它是 URL 列表,将成为后续爬取的根,爬虫将从此处开始爬取。

4

自定义设置

这些是在运行爬虫时,会覆盖项目全局配置的设置。

5

爬虫

它是一个属性,链接到爬虫实例绑定的 Crawler 对象。

6

设置

这些是运行爬虫的设置。

7

日志记录器

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

8

from_crawler(crawler,*args,**kwargs)

它是一个类方法,用于创建你的爬虫。参数如下:

  • crawler − 爬虫实例将绑定的爬虫。

  • args(列表) − 这些参数传递给 _init_() 方法。

  • kwargs(字典) − 这些关键字参数传递给 _init_() 方法。

9

start_requests()

当没有指定特定的 URL 且爬虫打开进行抓取时,Scrapy 会调用 start_requests() 方法。

10

make_requests_from_url(url)

它是一个用于将 URL 转换为请求的方法。

11

parse(response)

此方法处理响应并返回抓取的数据,以及更多 URL。

12

log(message[,level,component])

它是一个通过爬虫日志记录器发送日志消息的方法。

13

closed(reason)

当爬虫关闭时,会调用此方法。

爬虫参数

爬虫参数用于指定起始 URL,并使用 crawl 命令以及 -a 选项传递,如下所示:

scrapy crawl first_scrapy -a group = accessories

以下代码演示了爬虫如何接收参数:

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]

通用爬虫

您可以使用通用爬虫从其子类化您的爬虫。它们的目的是根据某些规则遵循网站上的所有链接,以从所有页面提取数据。

对于以下爬虫中使用的示例,让我们假设我们有一个具有以下字段的项目:

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 类的规则:

序号 规则 & 描述
1

LinkExtractor

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

2

callback

在每个页面被抓取后调用。

3

follow

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

parse_start_url(response)

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

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

让我们看下面的例子,其中爬虫从 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 提要抓取并迭代节点的爬虫的基类。它具有以下类:

class scrapy.spiders.XMLFeedSpider

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

序号 属性 & 描述
1

iterator

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

2

itertag

它是一个包含要迭代的节点名称的字符串。

3

namespaces

它由 (前缀,uri) 元组列表定义,这些元组使用 register_namespace() 方法自动注册命名空间。

4

adapt_response(response)

它接收响应并在响应体从爬虫中间件到达后立即修改它,在爬虫开始解析它之前。

5

parse_node(response,selector)

当为每个匹配提供的标签名称的节点调用时,它接收响应和选择器。

注意 − 如果您不覆盖此方法,您的爬虫将无法工作。

6

process_results(response,results)

它返回爬虫返回的结果和响应列表。

CSVFeedSpider

它迭代其每一行,接收 CSV 文件作为响应,并调用 parse_row() 方法。它具有以下类:

class scrapy.spiders.CSVFeedSpider

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

序号 选项 & 描述
1

delimiter

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

2

quotechar

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

3

headers

它是一个语句列表,从中可以提取字段。

4

parse_row(response,row)

它接收响应和每一行以及标题的键。

CSVFeedSpider 示例

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 通过从 robots.txt 中找到 URL 来帮助 网站地图 爬取网站。它具有以下类:

class scrapy.spiders.SitemapSpider

下表显示了 SitemapSpider 的字段:

序号 字段 & 描述
1

sitemap_urls

您要爬取的指向网站地图的 URL 列表。

2

sitemap_rules

它是一个 (正则表达式,回调) 元组列表,其中正则表达式是一个正则表达式,回调用于处理与正则表达式匹配的 URL。

3

sitemap_follow

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

4

sitemap_alternate_links

指定要为单个 URL 遵循的备用链接。

SitemapSpider 示例

以下 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 中的网站地图,其 url 包含 /sitemap_company

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 - 选择器

描述

当您抓取网页时,您需要使用称为选择器的机制来提取 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>

构造选择器

您可以通过传递文本TextResponse对象来构造选择器类实例。根据提供的输入类型,选择器选择以下规则:

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!!!']

使用选择器

使用上述简单的代码片段,您可以构建 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

嵌套选择器

使用上述代码,您可以嵌套选择器以使用.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']

使用正则表达式的选择器

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

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

以上代码行显示图像名称如下:

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

使用相对 XPath

当您使用以/开头的 XPath 时,嵌套选择器和 XPath 与文档的绝对路径相关,而不是选择器的相对路径。

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

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

接下来,您可以通过在 XPath 前添加点作为.//p来提取内部的所有'p'元素,如下所示:

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

使用 EXSLT 扩展

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

序号 前缀 & 用途 命名空间
1

re

正则表达式

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

2

set

集合操作

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

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

有一些 XPath 提示,在将 XPath 与 Scrapy 选择器一起使用时非常有用。有关更多信息,请点击此 链接

Scrapy - 项目

描述

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

声明项目

您可以使用类定义语法以及字段对象来声明项目,如下所示:

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

项目字段

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

使用项目

当您使用项目时,可以定义一些常见函数。有关更多信息,请点击此 链接

扩展项目

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

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)

项目对象

项目对象可以使用以下类来指定,该类根据给定的参数提供新的初始化项目:

class scrapy.item.Item([arg])

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

字段对象

字段对象可以使用以下类来指定,其中 Field 类不发出其他过程或属性:

class scrapy.item.Field([arg])

Scrapy - 项目加载器

描述

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

声明项目加载器

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

例如:

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属性用于声明默认输入/输出处理器。

使用 Item Loaders 填充 Item

要使用 Item Loader,首先需要使用类似字典的对象或不使用任何对象实例化它,其中 Item 使用在ItemLoader.default_item_class属性中指定的 Item 类。

  • 您可以使用选择器将值收集到 Item Loader 中。

  • 您可以在同一 Item 字段中添加更多值,Item Loader 将使用适当的处理器来添加这些值。

以下代码演示了如何使用 Item Loaders 填充 Item:

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 用于提取title字段,使用add_xpath()方法提取:

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

然后,对desc字段使用类似的请求。尺寸数据使用add_css()方法提取,last_updated使用add_value()方法填充值为“yesterday”。

收集完所有数据后,调用ItemLoader.load_item()方法,该方法返回使用add_xpath()add_css()add_value()方法提取数据填充的 Item。

输入和输出处理器

Item Loader 的每个字段包含一个输入处理器和一个输出处理器。

  • 提取数据时,输入处理器会处理它,并将结果存储在 ItemLoader 中。

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

  • 最后,您可以将输出处理器的结果分配给 Item。

以下代码演示了如何为特定字段调用输入和输出处理器:

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]

第 1 行 - 从 xpath1 提取 title 的数据,并通过输入处理器传递,并将结果收集并存储在 ItemLoader 中。

第 2 行 - 同样,从 xpath2 提取 title,并通过相同的输入处理器传递,并将结果添加到为 [1] 收集的数据中。

第 3 行 - 从 css 选择器提取 title,并通过相同的输入处理器传递,并将结果添加到为 [1] 和 [2] 收集的数据中。

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

第 5 行 - 最后,从所有字段内部收集数据并传递给输出处理器,并将最终值分配给 Item。

声明输入和输出处理器

输入和输出处理器在 ItemLoader 定义中声明。除此之外,它们也可以在Item 字段元数据中指定。

例如:

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 上下文

Item Loader 上下文是一个字典,其中包含在输入和输出处理器之间共享的任意键值。

例如,假设您有一个函数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 上下文的值:

  • 修改当前活动的 Item Loader 上下文:

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

loader = ItemLoader(product, unit = "mm")
  • 在为使用 Item Loader 上下文实例化的输入/输出处理器声明 Item Loader 时:

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

ItemLoader 对象

它是一个对象,它返回一个新的 Item Loader 来填充给定的 Item。它具有以下类:

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

下表显示了 ItemLoader 对象的参数:

序号 参数及描述
1

item

它是通过调用 add_xpath()、add_css() 或 add_value() 来填充的 Item。

2

selector

它用于从网站提取数据。

3

response

它用于使用 default_selector_class 构造选择器。

下表显示了 ItemLoader 对象的方法:

序号 方法及描述 示例
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)

它用于通过提供处理器和关键字参数来提取 Unicode 字符串,并接收XPath

# HTML code: <div class = "item-name">DVD</div>
loader.get_xpath("//div[@class = 
'item-name']")

# HTML code: <div id = "length">the length is 
45cm</div>
loader.get_xpath("//div[@id = 'length']", TakeFirst(), 
re = "the length is (.*)")
5

add_xpath(field_name, xpath, *processors, **kwargs)

它接收XPath到提取 Unicode 字符串的字段。

# HTML code: <div class = "item-name">DVD</div>
loader.add_xpath('name', '//div
[@class = "item-name"]')

# HTML code: <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 code: <div class = "item-name">DVD</div>
loader.replace_xpath('name', '
//div[@class = "item-name"]')

# HTML code: <div id = "length">the length is
 45cm</div>
loader.replace_xpath('length', '
//div[@id = "length"]', re = 'the length is (.*)')
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)

它类似于 add_value() 方法,区别在于它将 CSS 选择器添加到字段中。

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)

它使用 CSS 选择器替换提取的数据。

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

load_item()

收集完数据后,此方法使用收集到的数据填充 Item 并返回它。

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)

它用于使用 XPath 选择器创建嵌套加载器。

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 对象的属性:

序号 属性 & 描述
1

item

它是 Item Loader 执行解析的对象。

2

context

它是当前活动的 Item Loader 的上下文。

3

default_item_class

它用于表示 Item,如果在构造函数中未给出。

4

default_input_processor

仅对未指定输入处理器的字段使用 default_input_processors。

5

default_output_processor

仅对未指定输出处理器的字段使用 default_output_processors。

6

default_selector_class

它是一个用于构造选择器的类,如果在构造函数中未给出。

7

selector

它是一个可以用来从网站提取数据的对象。

嵌套加载器

它用于在从文档的子部分解析值时创建嵌套加载器。如果您不创建嵌套加载器,则需要为要提取的每个值指定完整的 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:[email protected]">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()

重用和扩展 Item Loaders

Item Loaders 旨在减轻维护工作,当您的项目获取更多爬虫时,这会成为一个基本问题。

例如,假设一个网站将其产品名称用三个短划线括起来(例如 --DVD---)。如果您不希望在最终的产品名称中包含这些短划线,则可以使用默认的 Product Item Loader 来删除它们,如下面的代码所示:

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)

可用的内置处理器

以下是一些常用的内置处理器:

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

它返回从接收到的值列表中第一个非空/非 null 的值。例如:

>>> 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

描述

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

配置 Shell

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

如果您在 Unix 平台上工作,则最好安装 IPython。如果无法访问 IPython,您也可以使用bpython

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

[settings]
shell = bpython

启动 Shell

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

scrapy shell <url>

url指定需要抓取数据 的URL。

使用 Shell

Shell 提供了一些额外的快捷方式和 Scrapy 对象,如下表所述:

可用的快捷方式

Shell 在项目中提供以下可用的快捷方式:

序号 快捷方式及描述
1

shelp()

它使用帮助选项提供可用的对象和快捷方式。

2

fetch(request_or_url)

它从请求或 URL 中收集响应,并且相关对象将正确更新。

3

view(response)

您可以在本地浏览器中查看给定请求的响应,以便观察并正确显示外部链接,它会将 base 标签附加到响应主体。

可用的 Scrapy 对象

Shell 在项目中提供以下可用的 Scrapy 对象:

序号 对象及描述
1

爬虫

它指定当前的爬虫对象。

2

spider

如果没有当前 URL 的爬虫,则它将通过定义新的爬虫来处理 URL 或爬虫对象。

3

request

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

4

response

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

5

设置

它提供当前的 Scrapy 设置。

Shell 会话示例

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

在继续之前,首先我们将启动 shell,如下面的命令所示:

scrapy shell 'https://scrapy.net.cn' --nolog

使用以上 URL 时,Scrapy 将显示可用的对象:

[s] Available Scrapy objects:
[s]   crawler    <scrapy.crawler.Crawler object at 0x1e16b50>
[s]   item       {}
[s]   request    <GET https://scrapy.net.cn >
[s]   response   <200 https://scrapy.net.cn >
[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     
... 

从 Spider 调用 Shell 以检查响应

只有在你期望获得该响应时,才能检查从 spider 处理的响应。

例如:

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)

如上代码所示,您可以使用以下函数从 spider 调用 shell 以检查响应:

scrapy.shell.inspect_response

现在运行 spider,您将看到以下屏幕:

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 是一种处理抓取项目的的方法。当一个项目发送到 Item Pipeline 时,它会被 spider 抓取并使用多个组件进行处理,这些组件按顺序执行。

每当收到一个项目时,它都会决定以下两种操作之一:

  • 继续处理项目。
  • 从管道中删除它。
  • 停止处理项目。

Item Pipeline 通常用于以下目的:

  • 将抓取的项目存储在数据库中。
  • 如果收到的项目重复,则它将删除重复的项目。
  • 它将检查项目是否包含目标字段。
  • 清除 HTML 数据。

语法

您可以使用以下方法编写 Item Pipeline:

process_item(self, item, spider) 

以上方法包含以下参数:

  • Item(item 对象或字典) - 它指定抓取的项目。
  • spider(spider 对象) - 抓取项目的 spider。

您可以使用下表中提供的其他方法:

序号 方法及描述 参数
1

open_spider(self, spider)

当 spider 打开时选择它。

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

2

close_spider(self, spider)

当 spider 关闭时选择它。

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

3

from_crawler(cls, crawler)

借助 crawler,pipeline 可以访问 Scrapy 的核心组件,例如信号和设置。

crawler(Crawler 对象) - 它指的是使用此 pipeline 的 crawler。

示例

以下是不同概念中使用的 item pipeline 示例。

删除没有标签的项目

在以下代码中,pipeline 为那些不包含增值税(excludes_vat 属性)的项目平衡(price)属性,并忽略那些没有价格标签的项目:

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) 

将项目写入 JSON 文件

以下代码将从所有 spider 抓取的所有项目存储到单个items.jl文件中,该文件包含每行一个项目,以 JSON 格式的序列化形式存储。JsonWriterPipeline 类用于在代码中演示如何编写 item pipeline:

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

将项目写入 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

重复过滤器

过滤器将检查重复的项目,并删除已处理的项目。在以下代码中,我们为项目使用了唯一的 ID,但 spider 返回了许多具有相同 ID 的项目:

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

激活 Item Pipeline

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

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

Scrapy - 数据导出

描述

Feed 导出是存储从站点抓取的数据的一种方法,即生成一个“导出文件”

序列化格式

Feed 导出使用 Item 导出器,并使用多种序列化格式和存储后端生成包含抓取项目的 Feed。

下表显示了支持的格式:

序号 格式和描述
1

JSON

FEED_FORMAT 为json

使用的导出器为class scrapy.exporters.JsonItemExporter

2

JSON 行

FEED_FROMAT 为jsonlines

使用的导出器为class scrapy.exporters.JsonLinesItemExporter

3

CSV

FEED_FORMAT 为CSV

使用的导出器为class scrapy.exporters.CsvItemExporter

4

XML

FEED_FORMAT 为xml

使用的导出器为class scrapy.exporters.XmlItemExporter

使用FEED_EXPORTERS设置,还可以扩展支持的格式:

序号 格式和描述
1

Pickle

FEED_FORMAT 为 pickel

使用的导出器为class scrapy.exporters.PickleItemExporter

2

Marshal

FEED_FORMAT 为 marshal

使用的导出器为class scrapy.exporters.MarshalItemExporter

存储后端

存储后端定义了使用 URI 将 Feed 存储在何处。

下表显示了支持的存储后端:

序号 存储后端和描述
1

本地文件系统

URI 方案为file,用于存储 Feed。

2

FTP

URI 方案为ftp,用于存储 Feed。

3

S3

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

4

标准输出

URI 方案为stdout,Feed 存储到标准输出。

存储 URI 参数

以下是存储 URL 的参数,在创建 Feed 时会被替换:

  • %(time)s:此参数将被时间戳替换。
  • %(name)s:此参数将被 spider 名称替换。

设置

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

序号 设置和描述
1

FEED_URI

它是导出 Feed 的 URI,用于启用 Feed 导出。

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 - 请求和响应

描述

Scrapy 可以使用RequestResponse对象来抓取网站。请求对象通过系统传递,使用 spider 执行请求并在返回响应对象时返回请求。

请求对象

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

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

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

序号 参数及描述
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

它是一个可调用的函数,当处理请求时引发异常时调用它。

将附加数据传递给回调函数

下载响应后,请求的回调函数将其作为第一个参数调用。

例如:

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

使用 errback 捕获请求处理中的异常

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 特殊键

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

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

序号 键和描述
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

它是一个键,用于为每个 spider 保留多个 cookie 会话。

7

dont_cache

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

8

redirect_urls

它是一个键,包含请求通过的 URL。

9

bindaddress

它是可以用于执行请求的传出 IP 地址的 IP。

10

dont_obey_robotstxt

如果设置为 True,则即使启用了 ROBOTSTXT_OBEY,也不会过滤 robots.txt 排除标准禁止的请求。

11

下载超时时间

用于设置每个蜘蛛的超时时间(以秒为单位),下载器将在超时前等待该时间。

12

下载最大大小

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

13

代理

可以为 Request 对象设置代理,以便在请求中使用 HTTP 代理。

请求子类

可以通过继承请求类来实现自定义功能。内置的请求子类如下:

FormRequest 对象

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 表单数据的字典,该字典分配给请求的主体。

注意 - 其余参数与请求类相同,并在请求对象部分进行了说明。

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

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

下表显示了上述类的参数:

序号 参数及描述
1

response

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

2

formname

如果指定,它是一个字符串,其中包含具有 name 属性的表单。

3

formnumber

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

4

formdata

它是表单数据中用于覆盖的字段的字典。

5

formxpath

如果指定,它是一个字符串,匹配 xpath 的表单将被使用。

6

formcss

如果指定,它是一个字符串,匹配 css 选择器的表单将被使用。

7

clickdata

它是用于观察被点击控件的属性字典。

8

dont_click

如果设置为 True,则表单中的数据将在不点击任何元素的情况下提交。

示例

以下是请求使用的一些示例:

使用 FormRequest 通过 HTTP POST 发送数据

以下代码演示了当您希望在蜘蛛中复制 HTML 表单 POST 时如何返回FormRequest 对象:

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

使用 FormRequest.from_response() 模拟用户登录

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

当您希望在抓取时自动填充这些字段时,可以使用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

响应对象

它是一个指示 HTTP 响应的对象,该响应被馈送到蜘蛛以进行处理。它具有以下类:

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

下表显示了 Response 对象的参数:

序号 参数及描述
1

url

它是一个指定 URL 响应的字符串。

2

状态

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

3

headers

它是一个包含响应头的字典。

4

body

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

5

标志

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

响应子类

可以通过继承响应类来实现自定义功能。内置的响应子类如下:

TextResponse 对象

TextResponse 对象用于二进制数据(如图像、声音等),它能够编码基本 Response 类。它具有以下类:

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

以下是参数:

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

注意 - 其余参数与响应类相同,并在响应对象部分进行了说明。

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

序号 属性 & 描述
1

文本

它是响应主体,其中可以多次访问 response.text。

2

encoding

它是一个包含响应编码的字符串。

3

selector

它是在第一次访问时实例化的属性,并使用响应作为目标。

下表显示了除了response 方法外,TextResponse 对象还支持的方法:

序号 方法及描述
1

xpath (查询)

它是 TextResponse.selector.xpath(query) 的快捷方式。

2

css (查询)

它是 TextResponse.selector.css(query) 的快捷方式。

3

body_as_unicode()

它是一个作为方法提供的响应主体,其中可以多次访问 response.text。

HtmlResponse 对象

它是一个支持编码和自动发现的对象,方法是查看 HTML 的meta httpequiv 属性。它的参数与响应类相同,并在响应对象部分进行了说明。它具有以下类:

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

XmlResponse 对象

它是一个支持编码和自动发现的对象,方法是查看 XML 行。它的参数与响应类相同,并在响应对象部分进行了说明。它具有以下类:

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

Scrapy - 链接提取器

描述

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

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

内置链接提取器的参考

通常,链接提取器与 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 一起使用。

序号 参数及描述
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。

示例

以下代码用于提取链接:

<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 - 设置

描述

可以使用 Scrapy 设置修改 Scrapy 组件的行为。设置还可以选择当前活动的 Scrapy 项目,以防您有多个 Scrapy 项目。

指定设置

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

填充设置

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

序号 机制和描述
1

命令行选项

在此,传递的参数优先级最高,覆盖其他选项。-s 用于覆盖一个或多个设置。

scrapy crawl myspider -s LOG_FILE = scrapy.log
2

每个蜘蛛的设置

蜘蛛可以拥有自己的设置,通过使用属性 custom_settings 覆盖项目设置。

class DemoSpider(scrapy.Spider): 
   name = 'demo'  
   custom_settings = { 
      'SOME_SETTING': 'some value', 
   }
3

项目设置模块

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

4

每个命令的默认设置

每个 Scrapy 工具命令都在 default_settings 属性中定义了自己的设置,以覆盖全局默认设置。

5

默认全局设置

这些设置位于 scrapy.settings.default_settings 模块中。

访问设置

它们可以通过 self.settings 获取,并在蜘蛛初始化后在基本蜘蛛中设置。

以下示例演示了这一点。

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

要在初始化蜘蛛之前使用设置,必须在蜘蛛的_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')) 

设置名称的原理

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

内置设置参考

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

序号 设置和描述
1

AWS_ACCESS_KEY_ID

它用于访问 Amazon Web Services。

默认值:None

2

AWS_SECRET_ACCESS_KEY

它用于访问 Amazon Web Services。

默认值:None

3

BOT_NAME

它是机器人的名称,可用于构建 User-Agent。

默认值:'scrapybot'

4

CONCURRENT_ITEMS

项目处理器中存在的最大项目数,用于并行处理。

默认值: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

使用 edit 命令编辑蜘蛛时使用。

默认值:取决于环境

30

EXTENSIONS

一个字典,包含在项目中启用的扩展。

默认值:{}

31

EXTENSIONS_BASE

一个字典,包含内置扩展。

默认值:{ 'scrapy.extensions.corestats.CoreStats': 0, }

32

FEED_TEMPDIR

用于设置自定义文件夹,爬虫临时文件可以存储在此文件夹中。

33

ITEM_PIPELINES

一个包含管道(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.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

一个类,该类实现 Stats Collector API 来收集统计信息。

默认值:'scrapy.statscollectors.MemoryStatsCollector'

64

STATS_DUMP

设置为 true 时,此设置会将统计信息转储到日志中。

默认值:True

65

STATSMAILER_RCPTS

蜘蛛完成抓取后,Scrapy 使用此设置发送统计信息。

默认值:[]

66

TELNETCONSOLE_ENABLED

定义是否启用 telnetconsole。

默认值:True

67

TELNETCONSOLE_PORT

定义 telnet 控制台的端口。

默认值:[6023, 6073]

68

TEMPLATES_DIR

包含在创建新项目时可用的模板的目录。

默认值:scrapy 模块内的 templates 目录

69

URLLENGTH_LIMIT

定义允许抓取的 URL 的最大长度限制。

默认值:2083

70

USER_AGENT

定义在爬取站点时使用的用户代理。

默认值:"Scrapy/VERSION (+https://scrapy.net.cn)"

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

Scrapy - 异常

描述

不规则事件被称为异常。在 Scrapy 中,由于配置丢失、从项目管道中删除项目等原因会导致异常。以下是 Scrapy 中提到的异常及其应用列表。

DropItem

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

exception (scrapy.exceptions.DropItem)

CloseSpider

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

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

它包含一个名为 reason (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)

如果禁用以下任何组件,则可以引发此异常。

  • 扩展
  • 项目管道
  • 下载中间件
  • 蜘蛛中间件

NotSupported

当任何功能或方法不受支持时引发此异常。可以写成:

exception (scrapy.exceptions.NotSupported)

Scrapy - 创建项目

描述

要从网页中抓取数据,首先需要创建 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 - 定义项目

描述

项目是用于收集从网站抓取的数据的容器。您必须通过定义项目来启动蜘蛛。要定义项目,请编辑位于目录 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 类继承自 Item,其中包含 Scrapy 已为我们构建的许多预定义对象。例如,如果要从站点中提取名称、URL 和描述,则需要为这三个属性中的每一个定义字段。

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

from scrapy.item import Item, Field  

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

Scrapy - 第一个爬虫

描述

蜘蛛是一个类,用于定义要从中提取数据的初始 URL、如何遵循分页链接以及如何提取和解析在 items.py 中定义的字段。Scrapy 提供不同类型的蜘蛛,每个蜘蛛都有特定的用途。

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

  • name - 定义蜘蛛的唯一名称。

  • allowed_domains - 包含蜘蛛要爬取的基本 URL。

  • start-urls - 蜘蛛开始爬取的 URL 列表。

  • 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 - 爬取

描述

要执行您的蜘蛛,请在您的 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,都有一行日志 (referer: None) 表示这些 URL 是起始 URL,并且没有引用方。接下来,您应该会看到在您的 first_scrapy 目录中创建了两个名为 Books.htmlResources.html 的新文件。

Scrapy - 提取项目

描述

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

  • /html/head/title - 这将选择 HTML 文档的 <head> 元素内的 <title> 元素。

  • /html/head/title/text() - 这将选择同一 <title> 元素内的文本。

  • //td - 这将选择所有 <td> 元素。

  • //div[@class = "slice"] - 这将选择所有包含属性 class = "slice" 的 div 元素

选择器有四种基本方法,如下表所示:

序号 方法及描述
1

extract()

它返回一个包含所选数据的 Unicode 字符串。

2

re()

它返回一个 Unicode 字符串列表,当正则表达式作为参数给出时提取。

3

xpath()

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

4

css()

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

在 Shell 中使用选择器

要使用内置的 Scrapy shell 演示选择器,您需要在系统中安装 IPython。这里需要注意的是,在运行 Scrapy 时,URL 应包含在引号中;否则,包含 '&' 字符的 URL 将无法工作。您可以在项目的顶级目录中使用以下命令启动 Shell:

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

Shell 如下所示:

[ ... 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]:

当 Shell 加载时,您可以分别使用 response.bodyresponse.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']

提取数据

要从普通的 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 - 使用项目

描述

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']}

Scrapy - 跟踪链接

描述

在本章中,我们将学习如何提取我们感兴趣的页面链接,跟踪它们并从该页面提取数据。为此,我们需要在我们的之前代码中进行以下更改,如下所示 -

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

以上代码包含以下方法 -

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

  • response.urljoin - parse() 方法将使用此方法构建一个新的 URL 并提供一个新的请求,该请求稍后将发送到回调。

  • 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 - 爬取数据

描述

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

scrapy crawl dmoz -o data.json

此命令将创建一个包含 JSON 格式抓取数据的data.json文件。此技术适用于少量数据。如果需要处理大量数据,则可以使用 Item Pipeline。就像 data.json 文件一样,在项目创建时会在tutorial/pipelines.py中设置一个保留文件。

Scrapy - 日志

描述

日志记录意味着跟踪事件,它使用内置的日志记录系统并定义函数和类来实现应用程序和库。日志记录是一种现成的材料,可以与列在日志记录设置中的 Scrapy 设置一起使用。

Scrapy 将设置一些默认设置并在运行命令时在 scrapy.utils.log.configure_logging() 的帮助下处理这些设置。

日志级别

在 Python 中,日志消息有五个不同的严重级别。以下列表按升序显示标准日志消息 -

  • logging.DEBUG - 用于调试消息(最低严重性)

  • logging.INFO - 用于信息消息

  • logging.WARNING - 用于警告消息

  • logging.ERROR - 用于常规错误

  • logging.CRITICAL - 用于严重错误(最高严重性)

如何记录消息

以下代码显示了使用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")

从 Spider 中记录日志

每个 Spider 实例在其内部都有一个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)

在以上代码中,记录器是使用 Spider 的名称创建的,但您可以使用 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)

日志记录配置

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

根据以下设置,Scrapy 将为记录器配置处理程序。

日志记录设置

以下设置用于配置日志记录 -

  • LOG_FILELOG_ENABLED决定日志消息的目标。

  • 当您将LOG_ENCODING设置为 false 时,它不会显示日志输出消息。

  • LOG_LEVEL将确定消息的严重性顺序;严重性较低的消息将被过滤掉。

  • LOG_FORMATLOG_DATEFORMAT用于指定所有消息的布局。

  • 当您将LOG_STDOUT设置为 true 时,进程的所有标准输出和错误消息都将重定向到日志。

命令行选项

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

序号 命令和描述
1

--logfile FILE

覆盖LOG_FILE

2

--loglevel/-L LEVEL

覆盖LOG_LEVEL

3

--nolog

LOG_ENABLED设置为 False

scrapy.utils.log 模块

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

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

序号 参数及描述
1

settings (dict, None)

它创建并配置根记录器的处理程序。默认情况下,它是None

2

install_root_handler (bool)

它指定安装根日志记录处理程序。默认情况下,它是True

以上函数 -

  • 通过 Python 标准日志记录路由警告和扭曲的日志记录。
  • 将 DEBUG 分配给 Scrapy,并将 ERROR 级别分配给 Twisted 记录器。
  • 如果 LOG_STDOUT 设置为 true,则将标准输出路由到日志。

可以使用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 Collector 是 Scrapy 提供的一个工具,用于以键/值对的形式收集统计信息,并且可以通过 Crawler API 访问它(Crawler 提供对所有 Scrapy 核心组件的访问)。统计信息收集器为每个蜘蛛提供一个统计信息表,其中统计信息收集器在蜘蛛打开时自动打开,并在蜘蛛关闭时关闭统计信息收集器。

常见的统计信息收集器用途

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

class ExtensionThatAccessStats(object): 
   def __init__(self, stats): 
      self.stats = stats  
   
   @classmethod 
   def from_crawler(cls, crawler): 
      return cls(crawler.stats)

下表显示了可用于统计信息收集器的各种选项 -

序号 参数 描述
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)} 
获取所有统计信息

可用的统计信息收集器

Scrapy 提供不同类型的统计信息收集器,可以通过STATS_CLASS设置访问它们。

MemoryStatsCollector

它是默认的 Stats 收集器,它维护每个用于抓取的蜘蛛的统计信息,并且数据将存储在内存中。

class scrapy.statscollectors.MemoryStatsCollector

DummyStatsCollector

此统计信息收集器非常高效,什么也不做。这可以通过STATS_CLASS设置来设置,并且可以用于禁用统计信息收集以提高性能。

class scrapy.statscollectors.DummyStatsCollector

Scrapy - 发送电子邮件

描述

Scrapy 可以使用其自己的名为Twisted 非阻塞 IO的功能发送电子邮件,该功能可以避免爬虫的非阻塞 IO。您可以配置发送电子邮件的一些设置,并提供发送附件的简单 API。

有两种方法可以实例化 MailSender,如下表所示 -

序号 参数 方法
1 from scrapy.mail import MailSender mailer = MailSender() 使用标准构造函数。
2 mailer = MailSender.from_settings(settings) 使用 Scrapy 设置对象。

以下行发送不带附件的电子邮件 -

mailer.send(to = ["[email protected]"], subject = "subject data", body = "body data", 
   cc = ["[email protected]"])

MailSender 类参考

MailSender 类使用Twisted 非阻塞 IO从 Scrapy 发送电子邮件。

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

下表显示了MailSender类中使用的参数 -

序号 参数及描述
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)

下表包含上述方法的参数 -

序号 参数及描述
1

to (list)

它指的是电子邮件接收者。

2

subject (str)

它指定电子邮件的主题。

3

cc (list)

它指的是接收者列表。

4

body (str)

它指的是电子邮件正文数据。

5

attachs (iterable)

它指的是电子邮件的附件、附件的 mimetype 和附件的名称。

6

mimetype (str)

它表示电子邮件的 MIME 类型。

7

charset (str)

它指定用于电子邮件内容的字符编码。

邮件设置

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

序号 设置和描述 默认值
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 控制台

描述

Telnet 控制台是一个在 Scrapy 进程内运行的 Python shell,用于检查和控制正在运行的 Scrapy 进程。

访问 Telnet 控制台

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

telnet localhost 6023

基本上,telnet 控制台列在 TCP 端口中,这在 **TELNETCONSOLE_PORT** 设置中进行了描述。

变量

下表中给出的一些默认变量用作快捷方式:

序号 快捷方式及描述
1

爬虫

这指的是 Scrapy 爬虫 (scrapy.crawler.Crawler) 对象。

2

engine

这指的是 Crawler.engine 属性。

3

spider

这指的是当前活动的 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

这指的是内存调试。

示例

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

暂停、恢复和停止 Scrapy 引擎

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

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

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

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

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

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

查看引擎状态

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 控制台信号

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

scrapy.extensions.telnet.update_telnet_vars(telnet_vars)

参数:

telnet_vars (dict)

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

Telnet 设置

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

序号 设置和描述 默认值
1

TELNETCONSOLE_PORT

这指的是 telnet 控制台的端口范围。如果设置为 none,则端口将被动态分配。

[6023, 6073]
2

TELNETCONSOLE_HOST

这指的是 telnet 控制台应该监听的接口。

'127.0.0.1'

Scrapy - Web 服务

描述

正在运行的 Scrapy Web 爬虫可以通过 **JSON-RPC** 进行控制。它由 JSONRPC_ENABLED 设置启用。此服务通过 JSON-RPC 2.0 协议提供对主爬虫对象的访问。访问爬虫对象的端点为:

https://127.0.0.1:6080/crawler

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

序号 设置和描述 默认值
1

JSONRPC_ENABLED

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

True
2

JSONRPC_LOGFILE

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

None
3

JSONRPC_PORT

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

[6080, 7030]
4

JSONRPC_HOST

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

'127.0.0.1'
广告