返回介绍

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

发布于 2025-04-21 19:15:28 字数 4650 浏览 0 评论 0 收藏

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。