Scrapy框架是一个为了爬取网站数据,提取结构性数据而编写的应用框架,也就是说应用Scrapy框架的话,我们就不需要从零开始写一个爬虫项目。
通过pip install scrapy 命令即可安装Scrapy框架。
官方文档: https://doc.scrapy.org/en/latest/ 中文文档:https://scrapy-chs.readthedocs.io/zh_CN/0.24/#
前面安装好Scrapy框架之后,进入安装好Scrapy框架的虚拟环境中,执行如下命令创建一个新的Scrapy项目:
scrapy startproject qsbk
其中:qsbk 是你的scrapy项目的名称,根据实际情况替换。执行成功的结果如下图1所示。

通过前面的命令创建了一个名为qsbk的Scrapy项目,其目录结构如下图2所示

这些文件分别是:
scrapy genspider spider_qsbk "qiushibaike.com"
命令说明:
scrapy genspider 这部分固定不变。表示创建一个爬虫spider_qsbk 指定的爬虫的名字,该名字不能与scrapy项目的名字重名,不然就会出现Cannot create a spider with the same name as your project的错误。"qiushibaike.com"这部分指定的是爬虫的网站的域名。

执行该命令之后我们可以看到在qsbk/spider/ 目录下会出现一个名为spider_qsbk.py的文件。
进到spider_qsbk.py 文件里,可以看到已经生成了如下代码:
class SpiderQsbkSpider(scrapy.Spider):
# 标识爬虫的名字
name = 'spider_qsbk'
# 标识爬虫允许的域名
allowed_domains = ['qiushibaike.com']
# 开始的页
start_urls = ['https://www.qiushibaike.com']
def parse(self, response):
pass
要创建一个Spider,必须自定义一个类,继承自scrapy.Spider, 然后,在这个类中定义三个属性和一个方法。
在做爬虫之前,一定要记得修改settings.py中的设置。这两处地方强烈建议设置。
ROBOTSTXT_OBEY 设置为False。默认为True。即遵守机器协议,那么在爬虫的时候,Scrapy首先会去找robots.txt文件, 如果没有找到,则会停止爬虫。DEFAULT_REQUEST_HEADERS 添加User-Agent。这个就是告诉服务器,我这个请求是一个正常的请求,不是一个爬虫。如果不设置User-Agent的话,在请求爬虫时很可能会出现如下错误:

首先让我们来看下response的类型,首先从第一页开始爬取数据。
class SpiderQsbkSpider(scrapy.Spider):
# 标识爬虫的名字
name = 'spider_qsbk'
# 标识爬虫允许的域名
allowed_domains = ['qiushibaike.com']
# 开始的页
start_urls = ['https://www.qiushibaike.com/text/page/1/']
def parse(self, response):
print('=' * 40)
print(type(response))
print('=' * 40)
运行spider的话也需要通过命令来运行。在qsbk项目所在的虚拟环境下执行如下命令。
scrapy crawl spider_qsbk
执行的结果如下图3所示:

可以看出response是一个scrapy.http.response.html.HtmlResponse 类。后面的文章会对该类进行详细介绍,这里只需要知道该类下面有一个xpath方法即可。即可以直接调用xpath表达式。
这里只是简单的演示爬取第一页的数据,爬取的内容是段子的作者和段子的内容。
class SpiderQsbkSpider(scrapy.Spider):
# 标识爬虫的名字
name = 'spider_qsbk'
# 标识爬虫允许的域名
allowed_domains = ['qiushibaike.com']
# 开始的页
start_urls = ['https://www.qiushibaike.com/text/page/1/']
def parse(self, response):
print(type(response))
# SelectorList
div_list = response.xpath('//div[@class="article block untagged mb15 typs_hot"]')
print(type(div_list))
for div in div_list:
# Selector
author = div.xpath('.//h2/text()').get().strip()
print(author)
content = div.xpath('.//div[@class="content"]//text()').getall()
content = "".join(content).strip()
print(content)
response.xpath方法返回的是一个scrapy.selector.unified.SelectorList类,该类继承自list类。故该类是一个序列,可以进行遍历。遍历得到的对象是Selector对象。
通过getall 或者get 方法来获取其中的字符串。
其中:1. getall 方法:获取Selector中的所有文本,返回的是一个列表
2. get 方法:获取的是Selector 中的第一个文本,返回的是一个str类型。
再次执行scrapy crawl spider_qsbk 命令得到的结果是:

每次运行爬虫都要执行scrapy crawl spider_qsbk 命令,着实有点不好弄。我们可以将命令放在一个py文件中,每次执行该py文件即可。这里我定义了一个名为start.py 的文件。
from scrapy import cmdline
cmdline.execute('scrapy crawl spider_qsbk'.split())
"""
等价于
cmdline.execute(['scrapy','crawl','spider_qsbk'])
"""
以后运行爬虫只需要执行start.py文件即可。
本文以糗事百科为例,简单介绍了Scrapy框架的快速入门。