9.3 Scrapy 命令行工具、选择器、数据容器
9.3.1 Scrapy 常用命令行工具

Scrapy 常用命令
1. scrapy startproject myproject
这条命令用来创建一个 Scrapy 爬虫项目,myproject 代表项目名称。
2. scrapy genspider mydomain mydomain.com
这条命令在项目中使用 BasicSpider 模板生成一个爬虫文件,所以此命令需要在项目目录中运行。
3. scrapy crawl myspider
在项目中启动爬虫命令,myspider 代表爬虫名称。
以上 3 个命令上一节都使用过了。Scrapy 还有几个经常使用的命令行工具,可以在命令行中运行 scrapy -h,查看所有可用的命令,Scrapy 提供了两种类型的命令,一种必须在 Scrapy 项目中运行,另一种属于全局命令,不需要项目。读者学习使用命令行工具时,要注意其是否需要项目。下面简单介绍最常用的其他几个命令行工具。
4. scrapy shell [url]
这条命令是全局命令。以给定的 URL(如果给出)或者空(没有给出 URL)启动 Scrapy shell。这个命令经常用来在交互模式下检查 XPath 语法提取数据是否正确,例如执行如下命令,就启动了 Python 交互模式。如果安装了 Ipython,默认进入 Ipython 交互界面,如图 9-6 所示。
>scrapy shell https://www.baidu.com/
图 9-6 显示了运行这条命令后的交互终端界面。可以看到 Scrapy 已经准备好了许多可用的 Scrapy 对象,如请求对象 request,返回响应对象 response 等,因此可以在 response 上直接使用 XPath 语法,查看解析结果。

图 9-6 交互界面
In[1]: response.xpath('//*[@id="u1"]/a[1]/text()').extract()
['新闻'] 可以看到系统正确地返回了所要提取的信息。注意 Ipython 解析器提示符为类似 In[1]:这样的运行序号。
5. scrapy view [url]
这条命令是全局命令。它会在浏览器中打开给定的 URL,并以 Scrapy spider 获取到的形式展现。有些时候 spider 获取到的页面和普通用户看到的并不相同。因此该命令可以用来检查 spider 所获取到的页面,并确认这是用户所期望的。
例如执行如下命令,可以看到 spider 下载的网页,与原来的网页看上去基本相同。
>scrapy view https://www.baidu.com/
6. scrapy list
这条命令需要在项目中运行,它会列出当前项目中所有可用的 spider(每行输出一个 spider)。运行这条命令还可以帮助用户检查错误,因为它可以提示 spider 的语法错误。例如在 pachong1 项目中执行这个命令,结果显示 pachong1 项目中只有 baidu 这一个爬虫,如图 9-7 所示。

图 9-7 scrapy list 显示项目中的爬虫
7. scrapy parse <url> [options]
这条命令需要在项目中运行,它获取给定的 URL 并使用相应的 spider 分析处理。如果我们提供--callback 选项,则使用 spider 的对应方法处理,否则使用 parse 解析。这条命令也可以帮助人们检查解析函数是否正确。
以上就是比较常用 Scrapy 命令行工具,Scrapy 还有很多其他的命令行工具,读者可以关注 Scrapy 文档。
9.3.2 Scrapy 选择器高级应用
上一节简单讲解了 Scrapy 选择器的用法,下面再看一下 Scrapy 选择器的其他用法。
1. 嵌套选择器
选择器方法(.xpath() 或.css())返回相同类型的选择器列表,因此可以对这些选择器继续调用选择器方法。还是用爬取百度首页作为例子,在命令行中执行如下命令。
>scrapy shell https://www.baidu.com/
系统进入交互界面,然后运行如下代码。
In[1]: title_list = response.xpath('//*[@id="u1"]/a') 这行代码帮我们获得了百度页面右上面角的栏目列表代码。对这个列表迭代,继续执行 XPath,提取栏目名称。
In[2]: for sel in title_list:
title = sel.xpath('text()').extract_first()
print(title)
新闻
hao123
地图
视频
贴吧
更多产品读者应该注意,在 for 循环里的 XPath 路径要填写相对路径,也可以用下面的形式(其中的。/代表当前路径)。
In[3]: title = sel.xpath('./text()').extract_first() 2. 结合正则表达式使用选择器
Scrapy 的选择器有一个 re() 方法,用来通过正则表达式提取数据。不同于使用 xpath() 或者 css() 方法,re() 方法返回 unicode 字符串的列表。因此,无法构造嵌套式的 re() 调用。
还是用上面百度的例子,现在想提取“新闻”栏目网址中的英文名称,可编写如下代码。
In[4]: response.xpath(
'//*[@id="u1"]/a[1]/@href').re(r'http://(.*).baidu.com')
['news'] 另外还有一个糅合了 extract_first() 与 re() 的函数 re_first()。使用该函数可以提取第一个匹配到的字符串。
In[5]: response.xpath(
'//*[@id="u1"]/a[1]/@href').re_first(r'http://(.*).baidu.com')
'news' 9.3.3 Scrapy 数据容器
为了方便存储结构性数据,Scrapy 提供了 Item 类。Item 对象是一种简单的容器,保存了爬取到的数据。其提供了类似于字典(dictionary-like)的 API,以及用于声明可用字段的简单语法。
许多 Scrapy 组件使用了 Item 提供的额外信息,将数据导出的 exporter 类根据 Item 声明的字段来导出数据,序列化可以通过 Item 字段的元数据(metadata)来定义等,因此在编写爬虫时,首先要声明 Item。
1. 声明 Item
正如上一节百度爬虫例子中演示的那样,Item 使用简单的 class 定义语法及 Field 对象来声明,示例如下。
import scrapy
class Product(scrapy.Item):
name = scrapy.Field()
price = scrapy.Field()
stock = scrapy.Field()
last_updated = scrapy.Field(serializer=str) 2. Item 字段
Field 对象指明了每个字段的元数据(metadata),例如上面的例子中,last_updated 中指明了该字段的序列化函数。Item 的 API 和 dict API 非常相似,使用起来就像 Python 字典。
(1)创建 item
>>>product = Product() #初始化
>>>product['name'] = 'Desktop PC' #添加 name 字段
>>>product['price'] = 1000 #添加 price 字段
>>>print(product)
{'name': 'Desktop PC', 'price': 1000} (2)获取字段的值
>>>product['name']
Desktop PC
>>>product.get('name') #使用 GET 方法获取 Desktop PC
Desktop PC
>>>product['price']
1000 (3)获取不存在的 key 会报错
>>>product['last_updated'] Traceback (most recent call last): KeyError: 'last_updated'
(4)可以使用类似字典的 GET 方法,避免报错
>>>product.get('last_updated', 'not set')
not set (5)根据 item 创建字典(dict)
>>>dict(product)
{'price': 1000, 'name': 'Desktop PC'} 绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论