大师兄的Python学习笔记(二十九): 爬虫(十)

大师兄的Python学习笔记(二十八): 爬虫(九)
大师兄的Python学习笔记(三十): 爬虫(十一)

十一、Scrapy框架

  • 基于Twisted的异步处理框架,是纯Python实现的爬虫框架。
  • 功能强大、爬取效率高,是目前使用最广泛的爬虫框架。
  • 模块间的耦合度低,扩展能力强,扩展组件多,几乎可以应对所有的反爬网站。
1. Scrapy的安装
  • Scrapy库依赖Twisted 14.0、lxml 3.4、pyOpenSSL 0.14等库,在安装Scrapy之前,需要先安装依赖库,之后再安装Scrapypip install scrapy
  • 如果你安装了Anaconda,可以跳过依赖库安装,直接使用conda install scrapy
2. Scrapy的架构
大师兄的Python学习笔记(二十九): 爬虫(十)_第1张图片
组件 功能
Scrapy Engine
引擎
处理整个系统的数据流、触发事务,是整个框架的核心。
Items
项目
定义爬取结果的数据结构,爬取的数据会被赋值成该Item对象。
Scheduler
调度器
接收引擎发过来的请求并将其加入其队列中,在引擎再次请求时将请求提供给引擎。
Downloader
下载器
下载网页内容,并将网页内容返回给爬虫。
Spiders
爬虫
定义了爬取的逻辑和网页的解析规则,主要负责解析响应并生成提取结果和新的请求。
Item Pipeline
项目管道
负责处理由爬虫从网页抽取的项目,主要任务是清洗、验证和存储数据。
Downloader Middlewares
下载器中间件
位于引擎和下载器之间的Hook框架,主要处理引擎和下载器之间的请求及响应。
Spider Middlewares
爬虫中间件
位于引擎和爬虫间的Hook框架,主要处理向爬虫输入的响应和输出的结果及新的请求。
3. Scrapy的数据流
大师兄的Python学习笔记(二十九): 爬虫(十)_第2张图片
  • Scrapy的数据流由引擎控制,流程如下:

(1) 引擎打开网站,找到该网站的爬虫,并向该爬虫请求第一个要爬取的URL。
(2) 引擎爬虫中获取到第一个要爬取的URL,并通过调度器以Request的形式调度。
(3) 引擎调度器请求下一个要爬取的URL。
(4) 调度器返回下一个要爬取的URL给引擎,引擎将URL通过下载器中间件转发给下载器下载。
(5) 页面下载完毕,下载器生成页面的Response,并通过下载器中间件发送给引擎
(6) 引擎从下载器中接收到Response,并将其通过爬虫中间件发送给爬虫处理。
(7) 爬虫处理Response,并返回提取到的项目及新的Request给引擎
(8) 引擎将爬虫返回的项目项目管道,并将新的Request调度器
不断重复(2)至(8),直到调度器中没有更多的Request,引擎关闭网站,爬取结束。

4. Scrapy的项目结构
  • 项目创建后,文件夹结构如下:

scrapy.cfg
project/
 __init__.py
 items.py
 pipelines.py
 settings.py
 middlewares.py
 spiders/
  __init__.py
  spider1.py
  spider2.py
  ... ...

文件 功能
scrapy.cfg 项目配置文件,定义了项目的配置文件路径、部署相关信息等内容。
items.py 定义项目的数据结构,所有项目的定义都可以放在这里。
pipelines.py 定义项目管道的实现,所有的项目管道都可以放在这里。
settings.py 定义项目的全局配置。
middlewares.py 定义爬虫中间件和下载器中间件的实现。
spiders 所有爬虫的实现,每个爬虫是一个文件。
5. 运行Scrapy
5.1 创建项目
  • Scrapy项目需要再命令行使用scrapy命令生成。
  • 使用scrapy startproject 创建。
5.2 创建爬虫
  • 爬虫必须继承scrapy.Spider
  • 可以在项目文件夹中使用scrapy genspider 生成爬虫。
# -*- coding: utf-8 -*-
>>>import scrapy

>>>class DoubanSpider(scrapy.Spider):
>>>    name = 'douban'
>>>    allowed_domains = ['movie.douban.com']
>>>    start_urls = ['https://movie.douban.com/chart']

>>>    def parse(self, response):
>>>        pass
  • 生成的类包含了三个属性:nameallowed_domainsstart_urls
  • 生了一个方法:parse()
属性和方法 功能
name 爬虫名
allowed_domains 允许爬取的域名。
start_urls 爬虫启动时爬取的url列表,定义初始请求。
parse() 负责解析返回的响应,提取数据或进一步生成要处理的请求。
5.3 创建Item
  • Item是保存爬取数据的容器,使用方法类似字典。
  • 创建Item需要继承scrapy.Item类。
  • 需要定义类型为scrapy.Field的字段。
  • 编辑items.py:
>>># -*- coding: utf-8 -*-

>>># Define here the models for your scraped items
>>>#
>>># See documentation in:
>>># https://doc.scrapy.org/en/latest/topics/items.html

>>>import scrapy

>>>class ProjectSampleItem(scrapy.Item):
>>>    # define the fields for your item here like:
>>>    url = scrapy.Field()
>>>    title = scrapy.Field()
>>>    actors = scrapy.Field()
>>>    rating = scrapy.Field()
5.4 解析Response并复制Item
  • 可以使用爬虫的parse(response)解析response,并将解析结果赋值给Item。
  • 可以使用CSS或Xpath选择器。
  • 修改爬虫的·parse()·函数:
  • 此外,还需要修改爬虫的request header。
# -*- coding: utf-8 -*-
>>>import scrapy

>>>class DoubanSpider(scrapy.Spider):
>>>    name = 'douban'
>>>    allowed_domains = ['https://movie.douban.com/']
>>>    start_urls = ['https://movie.douban.com/chart//']

>>>    def start_requests(self):
>>>        yield scrapy.Request("https://movie.douban.com/chart",
>>>                      headers={
>>>                          'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"})

>>>    def parse(self, response):
>>>        films = response.css('.article .item')

>>>        for film in films:
>>>            item = ProjectSampleItem()
>>>            item['url'] = film.css('a::attr(href)').extract_first()
>>>            item['title'] = (film.css('a::text').extract())[2].strip('\n /')
>>>            item['actors'] = film.css('.pl::text').extract_first()
>>>            item['rating'] = film.css('.rating_nums::text').extract_first()
>>>            yield item
5.5 运行爬虫
  • 在项目目录使用scrapy crawl 运行爬虫。
  • 如果一切顺利,运行爬虫后再控制台会显示爬取结果:
D:\project_sample>scrapy crawl douban
... ...
2020-09-09 10:30:32 [scrapy.core.engine] DEBUG: Crawled (200)  (referer: None)
2020-09-09 10:30:32 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/chart>
{'actors': '2020-09-04(美国网络) / 2020-09-11(中国大陆) / 刘亦菲 / 甄子丹 / 巩俐 / 李连杰 / 李截 / '
           '安柚鑫 / 马泰 / 赵家玲 / 郑佩佩 / 温明娜 / 曾晓童 / 袁文忠 / 唐辰瀛 / 道阿·茂阿 / 黄谷悦 / 尼尔森·李 '
           '/ 李勋 / 饶雪晶 / 袁之正 / 仁成外桥 / 加里·扬...',
 'rating': '4.7',
 'title': '花木兰',
 'url': 'https://movie.douban.com/subject/26357307/'}
2020-09-09 10:30:32 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/chart>
{'actors': '2020-07-15(韩国) / 姜栋元 / 李贞贤 / 权海骁 / 李来 / 金敏载 / 具教焕 / 金度允 / 李艺媛 / '
           '文宇振 / 韩国 / 延尚昊 / 115分钟 / 釜山行2:半岛 / 动作 / 惊悚 / 延尚昊 Sang-ho Yeon / 韩语 '
           '/ 英语 / 粤语',
 'rating': '5.1',
 'title': '釜山行2:半岛',
 'url': 'https://movie.douban.com/subject/30299515/'}
2020-09-09 10:30:32 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/chart>
{'actors': '2020-08-28(美国点映) / 2020-09-04(美国) / 杰西·普莱蒙 / 杰西·巴克利 / 托妮·科莱特 / '
           '大卫·休里斯 / 盖伊·博伊德 / 哈德莉·罗宾逊 / 格斯·伯尼 / 艾比·奎因 / 蔻碧·米纳菲 / 安东尼·格拉索 / '
           '泰迪·库卢卡 / 杰森·拉尔夫 / 奥利弗·普莱特...',
 'rating': '7.3',
 'title': '我想结束这一切',
 'url': 'https://movie.douban.com/subject/30129061/'}
2020-09-09 10:30:32 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/chart>
{'actors': '2020-09-03(中国大陆网络) / 许君聪 / 刘奔 / 龚小钧 / 杨蕊嘉 / 田璐 / 程汉 / 杨迪 / 邓宛千 / '
           '张钧涵 / 陈铮 / 中国大陆 / 周润泽 / 84分钟 / 剧情 / 喜剧 / 动作 / 朱子奇 Ziqi Zhu / 周润泽 '
           'Runze Zhou / 汉语普通话',
 'rating': '6.0',
 'title': '东北往事:我叫刘海柱',
 'url': 'https://movie.douban.com/subject/35141706/'}
2020-09-09 10:30:32 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/chart>
{'actors': '2020-07-29(韩国) / 郑雨盛 / 郭度沅 / 柳演锡 / 安古斯·麦克菲登 / 徐东甲 / 李南希 / 金重熙 / '
           '柳秀荣 / 李泰亨 / 申正根 / 廉晶雅 / 金容琳 / 金明坤 / 张光 / 李在勇 / 安内相 / 孙钟学 / 白龙 / '
           '寇比·法兰奇 / 斯科特·洛威尔 / 克里斯汀·达尔顿...',
 'rating': '5.8',
 'title': '铁雨2:首脑峰会',
 'url': 'https://movie.douban.com/subject/30479644/'}
2020-09-09 10:30:32 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/chart>
{'actors': '2020-07-02(匈牙利) / 2020-08-25(加拿大网络) / 2020-09-25(美国) / 杰西卡·查斯坦 / '
           '科林·法瑞尔 / 约翰·马尔科维奇 / 吉娜·戴维斯 / 陈冲 / 戴安娜·西尔弗斯 / 科曼 / 艾恩·格拉法德 / '
           '杰丝·威克斯勒 / 埃夫卡·科瓦拉西尤斯 / 安妮·比萨比亚...',
 'rating': '4.9',
 'title': '艾娃',
 'url': 'https://movie.douban.com/subject/30289869/'}
2020-09-09 10:30:32 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/chart>
{'actors': '2020-06-24(韩国) / 刘亚仁 / 朴信惠 / 全裴修 / 李铉旭 / 苏熙静 / 韩国 / 赵一亨 / 98分钟 / '
           '#活着 / 动作 / 惊悚 / 灾难 / 赵一亨 Il Cho / 马特·奈勒 Matt Naylor / 韩语',
 'rating': '5.6',
 'title': '#活着',
 'url': 'https://movie.douban.com/subject/34462775/'}
2020-09-09 10:30:32 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/chart>
{'actors': '2019-12-04(海南电影节) / 2020-07-27(上海电影节) / 2020-08-27(中国大陆网络) / '
           '2021-03-25(中国大陆) / 张晓晨 / 隋咏良 / 上白 / 刘泳希 / 萧子墨 / 赵健 / 中国大陆 / 李云波 / '
           '92分钟 / 动作 / 悬疑 / 武侠 / 李云波 Yunbo Li / 汉语普通话',
 'rating': '5.1',
 'title': '无名狂',
 'url': 'https://movie.douban.com/subject/27131969/'}
2020-09-09 10:30:32 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/chart>
{'actors': '2020-08-14(美国) / 杰米·福克斯 / 约瑟夫·高登-莱维特 / 多米尼克·菲什巴克 / 罗德里戈·桑托罗 / '
           '考特尼·万斯 / 艾米·兰德克 / 机关枪凯利 / 泰特·弗莱彻 / 阿伦·马尔多纳多 / 安德烈·沃德·哈蒙德 / '
           '可亚娜·西蒙妮·辛普森 / C.J.勒布朗...',
 'rating': '5.6',
 'title': '超能计划',
 'url': 'https://movie.douban.com/subject/30330875/'}
2020-09-09 10:30:32 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/chart>
{'actors': '2020-08-28(美国) / 麦茜·威廉姆斯 / 安雅·泰勒-乔伊 / 艾莉丝·布拉加 / 安东尼奥·班德拉斯 / 查理·希顿 '
           '/ 海皮·安德森 / 亨利·扎格 / 布鲁·亨特 / 莎拉·贝纳尼 / 美国 / 约什·布恩 / 98分钟 / 新变种人 / 动作 '
           '/ 科幻 / 恐怖 / 约什·布恩...',
 'rating': None,
 'title': '新变种人',
 'url': 'https://movie.douban.com/subject/26389321/'}
2020-09-09 10:30:32 [scrapy.core.engine] INFO: Closing spider (finished)
2020-09-09 10:30:32 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 525,
 'downloader/request_count': 2,
 'downloader/request_method_count/GET': 2,
 'downloader/response_bytes': 10137,
 'downloader/response_count': 2,
 'downloader/response_status_count/200': 1,
 'downloader/response_status_count/403': 1,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2020, 9, 9, 2, 30, 32, 810781),
 'item_scraped_count': 10,
 'log_count/DEBUG': 12,
 'log_count/INFO': 9,
 'response_received_count': 2,
 'robotstxt/request_count': 1,
 'robotstxt/response_count': 1,
 'robotstxt/response_status_count/403': 1,
 'scheduler/dequeued': 1,
 'scheduler/dequeued/memory': 1,
 'scheduler/enqueued': 1,
 'scheduler/enqueued/memory': 1,
 'start_time': datetime.datetime(2020, 9, 9, 2, 30, 32, 379758)}
2020-09-09 10:30:32 [scrapy.core.engine] INFO: Spider closed (finished)
5.6 爬取子页面
  • 需要在爬虫中使用scrapy.Request(url,callback)函数。
  • url可以传递子页面的请求URL。
  • callback是用于解析的回调函数。
  • 首先在settings.py中加入request header:
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
  • 修改items.py
>>>import scrapy

>>>class ProjectSampleItem(scrapy.Item):
>>>    # define the fields for your item here like:
>>>    url = scrapy.Field()
>>>    title = scrapy.Field()
>>>    director = scrapy.Field()
>>>    actors = scrapy.Field()
  • 修改爬虫
>>># -*- coding: utf-8 -*-
>>>import scrapy
>>>from project_sample.items import ProjectSampleItem

>>>class DoubanSpider(scrapy.Spider):
>>>    name = 'douban'
>>>    allowed_domains = ['movie.douban.com']
>>>    start_urls = ['https://movie.douban.com/chart']

>>>    def parse(self, response):
>>>        # 爬取排行页并跳转爬取子页面
>>>        films = response.css('.article .item')

>>>        for film in films:
>>>            next = film.css('a::attr(href)').extract_first()
>>>            url = response.urljoin(next)
>>>            yield scrapy.Request(url=url,callback=self.parse_sub)

>>>    def parse_sub(self,response):
>>>        # 爬取子页面
>>>        item = ProjectSampleItem()
>>>        item['url'] = response.url
>>>        item['title'] = response.css('#content span::text').extract_first()
>>>        item['actors'] = response.css('.actor .attrs a::text').extract()
>>>        item['director'] = response.css('#info span .attrs a::text').extract_first()
>>>        yield item
  • 运行后成功爬取
D:\project_sample>scrapy crawl douban
... ...
2020-09-09 11:18:48 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/34462775/>
{'actors': ['刘亚仁', '朴信惠'],
 'director': '赵一亨',
 'title': '#活着 #살아있다',
 'url': 'https://movie.douban.com/subject/34462775/'}
2020-09-09 11:18:48 [scrapy.core.engine] DEBUG: Crawled (200)  (referer: https://movie.douban.com/chart)
2020-09-09 11:18:48 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/35141706/>
{'actors': ['许君聪', '刘奔', '龚小钧', '杨蕊嘉', '田璐', '程汉', '杨迪', '邓宛千', '张钧涵', '陈铮'],
 'director': '周润泽',
 'title': '东北往事:我叫刘海柱',
 'url': 'https://movie.douban.com/subject/35141706/'}
2020-09-09 11:18:48 [scrapy.core.engine] DEBUG: Crawled (200)  (referer: https://movie.douban.com/chart)
2020-09-09 11:18:48 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/30479644/>
{'actors': ['郑雨盛',
            '郭度沅',
            '柳演锡',
            '安古斯·麦克菲登',
            '徐东甲',
            '李南希',
            '金重熙',
            '柳秀荣',
            '李泰亨',
            '申正根',
            '廉晶雅',
            '金容琳',
            '金明坤',
            '张光',
            '李在勇',
            '安内相',
            '孙钟学',
            '白龙',
            '寇比·法兰奇',
            '斯科特·洛威尔',
            '克里斯汀·达尔顿',
            '金胜泰',
            '郑镇珏',
            '俞成柱',
            '金重基',
            '申秀妍',
            '沈熙燮'],
 'director': '杨宇硕',
 'title': '铁雨2:首脑峰会 강철비2: 정상회담',
 'url': 'https://movie.douban.com/subject/30479644/'}
2020-09-09 11:18:48 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/26389321/>
{'actors': ['麦茜·威廉姆斯',
            '安雅·泰勒-乔伊',
            '艾莉丝·布拉加',
            '安东尼奥·班德拉斯',
            '查理·希顿',
            '海皮·安德森',
            '亨利·扎格',
            '布鲁·亨特',
            '莎拉·贝纳尼',
            'Colbi Gannett',
            'Tony Saquett',
            'Thomas Kee',
            'Mickey Gilmore',
            'Jeffrey Corazzini'],
 'director': '约什·布恩',
 'title': '新变种人 The New Mutants',
 'url': 'https://movie.douban.com/subject/26389321/'}
2020-09-09 11:18:48 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/30330875/>
{'actors': ['杰米·福克斯',
            '约瑟夫·高登-莱维特',
            '多米尼克·菲什巴克',
            '罗德里戈·桑托罗',
            '考特尼·万斯',
            '艾米·兰德克',
            '机关枪凯利',
            '泰特·弗莱彻',
            '阿伦·马尔多纳多',
            '安德烈·沃德·哈蒙德',
            '可亚娜·西蒙妮·辛普森',
            'C.J.勒布朗',
            'CG刘易斯',
            '约瑟夫·波利昆',
            'Jazzy De Lisser',
            '凯西·奈斯泰德',
            '珍妮特·罗斯·阮',
            '吉姆·克洛克',
            '乔恩·阿兹',
            '戴恩·罗兹',
            '怀尔德·韦恩',
            '贾斯汀·贾木什',
            '戈登·德克海默',
            '卢克·霍克斯',
            '彼得·詹梅斯',
            '托尼·查普曼·斯蒂尔',
            '约书亚·萨达索'],
 'director': '亨利·朱斯特',
 'title': '超能计划 Project Power',
 'url': 'https://movie.douban.com/subject/30330875/'}
2020-09-09 11:18:48 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/30289869/>
{'actors': ['杰西卡·查斯坦',
            '科林·法瑞尔',
            '约翰·马尔科维奇',
            '吉娜·戴维斯',
            '陈冲',
            '戴安娜·西尔弗斯',
            '科曼',
            '艾恩·格拉法德',
            '杰丝·威克斯勒',
            '埃夫卡·科瓦拉西尤斯',
            '安妮·比萨比亚',
            '克里斯托弗·J·多米格',
            'Janelle Feigley',
            'Rob Lévesque',
            'Omar Khan',
            'Matt Lindquist',
            'Nadezhda Russo',
            'Lin Hultgren'],
 'director': '泰特·泰勒',
 'title': '艾娃 Ava',
 'url': 'https://movie.douban.com/subject/30289869/'}
2020-09-09 11:18:48 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/27131969/>
{'actors': ['张晓晨', '隋咏良', '上白', '刘泳希', '萧子墨', '赵健'],
 'director': '李云波',
 'title': '无名狂',
 'url': 'https://movie.douban.com/subject/27131969/'}
2020-09-09 11:18:48 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/30129061/>
{'actors': ['杰西·普莱蒙',
            '杰西·巴克利',
            '托妮·科莱特',
            '大卫·休里斯',
            '盖伊·博伊德',
            '哈德莉·罗宾逊',
            '格斯·伯尼',
            '艾比·奎因',
            '蔻碧·米纳菲',
            '安东尼·格拉索',
            '泰迪·库卢卡',
            '杰森·拉尔夫',
            '奥利弗·普莱特',
            '弗雷德里克·沃丁',
            '瑞恩·斯蒂尔'],
 'director': '查理·考夫曼',
 'title': "我想结束这一切 I'm Thinking of Ending Things",
 'url': 'https://movie.douban.com/subject/30129061/'}
2020-09-09 11:18:48 [scrapy.core.engine] DEBUG: Crawled (200)  (referer: https://movie.douban.com/chart)
2020-09-09 11:18:48 [scrapy.core.engine] DEBUG: Crawled (200)  (referer: https://movie.douban.com/chart)
2020-09-09 11:18:48 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/30299515/>
{'actors': ['姜栋元', '李贞贤', '权海骁', '李来', '金敏载', '具教焕', '金度允', '李艺媛'],
 'director': '延尚昊',
 'title': '釜山行2:半岛 부산행2-반도',
 'url': 'https://movie.douban.com/subject/30299515/'}
2020-09-09 11:18:48 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/subject/26357307/>
{'actors': ['刘亦菲',
            '甄子丹',
            '巩俐',
            '李连杰',
            '李截',
            '安柚鑫',
            '马泰',
            '赵家玲',
            '郑佩佩',
            '温明娜',
            '曾晓童',
            '袁文忠',
            '唐辰瀛',
            '道阿·茂阿',
            '黄谷悦',
            '尼尔森·李',
            '李勋',
            '饶雪晶',
            '袁之正',
            '仁成外桥',
            '加里·扬',
            '欧文·邝',
            '乌特卡什·安邦德卡尔',
            '钱姆·艾希勒珀拉',
            '大卫·T·林',
            '詹森·郑',
            'Jun Yu'],
 'director': '妮琪·卡罗',
 'title': '花木兰 Mulan',
 'url': 'https://movie.douban.com/subject/26357307/'}
2020-09-09 11:18:48 [scrapy.core.engine] INFO: Closing spider (finished)
2020-09-09 11:18:48 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 4349,
 'downloader/request_count': 12,
 'downloader/request_method_count/GET': 12,
 'downloader/response_bytes': 244117,
 'downloader/response_count': 12,
 'downloader/response_status_count/200': 12,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2020, 9, 9, 3, 18, 48, 623165),
 'item_scraped_count': 10,
 'log_count/DEBUG': 22,
 'log_count/INFO': 9,
 'request_depth_max': 1,
 'response_received_count': 12,
 'robotstxt/request_count': 1,
 'robotstxt/response_count': 1,
 'robotstxt/response_status_count/200': 1,
 'scheduler/dequeued': 11,
 'scheduler/dequeued/memory': 11,
 'scheduler/enqueued': 11,
 'scheduler/enqueued/memory': 11,
 'start_time': datetime.datetime(2020, 9, 9, 3, 18, 47, 281069)}
2020-09-09 11:18:48 [scrapy.core.engine] INFO: Spider closed (finished)
5.7 保存结果到文件
  • 使用Scrapy的Feed Exports功能可以直接将抓取结果导出文件, 命令行指令是scrapy crawl -o
  • 支持csv、xml、pickle、marshal等多种格式,还支持ftp和s3等远程输出。
D:\project_sample>scrapy crawl douban -o douban.json
... ...
D:\project_sample>type douban.json
[
{"url": "https://movie.douban.com/subject/30289869/", "title": "\u827e\u5a03 Ava", "actors": ["\u6770\u897f\u5361\u00b7\u67e5\u65af\u5766", "\u79d1\u6797\u00b7\u6cd5\u745e\u5c14", "\u7ea6\u7ff0\u00b7\u9a6c\u5c14\u79d1\u7ef4\u5947", "\u5409\u5a1c\u00b7\u6234\u7ef4\u65af", "\u9648\u51b2", "\u6234\u5b89\u5a1c\u00b7\u897f\u5c14\u5f17\u65af", "\u79d1\u66fc", "\u827e\u6069\u00b7\u683c\u62c9\u6cd5\u5fb7", "\u6770\u4e1d\u00b7\u5a01\u514b\u65af\u52d2", "\u57c3\u592b\u5361\u00b7\u79d1\u74e6\u62c9\u897f\u5c24\u65af", "\u5b89\u59ae\u00b7\u6bd4\u8428\u6bd4\u4e9a", "\u514b\u91cc\u65af\u6258\u5f17\u00b7J\u00b7\u591a\u7c73\u683c", "Janelle Feigley", "Rob L\u00e9vesque", "Omar Khan", "Matt Lindquist", "Nadezhda Russo", "Lin Hultgren"], "director": "\u6cf0\u7279\u00b7\u6cf0\u52d2"},
{"url": "https://movie.douban.com/subject/34462775/", "title": "#\u6d3b\u7740 #\uc0b4\uc544\uc788\ub2e4", "actors": ["\u5218\u4e9a\u4ec1", "\u6734\u4fe1\u60e0"], "director": "\u8d75\u4e00\u4ea8"},
{"url": "https://movie.douban.com/subject/30330875/", "title": "\u8d85\u80fd\u8ba1\u5212 Project Power", "actors": ["\u6770\u7c73\u00b7\u798f\u514b\u65af", "\u7ea6\u745f\u592b\u00b7\u9ad8\u767b-\u83b1\u7ef4\u7279", "\u591a\u7c73\u5c3c\u514b\u00b7\u83f2\u4ec0\u5df4\u514b", "\u7f57\u5fb7\u91cc\u6208\u00b7\u6851\u6258\u7f57", "\u8003\u7279\u5c3c\u00b7\u4e07\u65af", "\u827e\u7c73\u00b7\u5170\u5fb7\u514b", "\u673a\u5173\u67aa\u51ef\u5229", "\u6cf0\u7279\u00b7\u5f17\u83b1\u5f7b", "\u963f\u4f26\u00b7\u9a6c\u5c14\u591a\u7eb3\u591a", "\u5b89\u5fb7\u70c8\u00b7\u6c83\u5fb7\u00b7\u54c8\u8499\u5fb7", "\u53ef\u4e9a\u5a1c\u00b7\u897f\u8499\u59ae\u00b7\u8f9b\u666e\u68ee", "C.J.\u52d2\u5e03\u6717", "CG\u5218\u6613\u65af", "\u7ea6\u745f\u592b\u00b7\u6ce2\u5229\u6606", "Jazzy De Lisser", "\u51ef\u897f\u00b7\u5948\u65af\u6cf0\u5fb7", "\u73cd\u59ae\u7279\u00b7\u7f57\u65af\u00b7\u962e", "\u5409\u59c6\u00b7\u514b\u6d1b\u514b", "\u4e54\u6069\u00b7\u963f\u5179", "\u6234\u6069\u00b7\u7f57\u5179", "\u6000\u5c14\u5fb7\u00b7\u97e6\u6069", "\u8d3e\u65af\u6c40\u00b7\u8d3e\u6728\u4ec0", "\u6208\u767b\u00b7\u5fb7\u514b\u6d77\u9ed8", "\u5362\u514b\u00b7\u970d\u514b\u65af", "\u5f7c\u5f97\u00b7\u8a79\u6885\u65af", "\u6258\u5c3c\u00b7\u67e5\u666e\u66fc\u00b7\u65af\u8482\u5c14", "\u7ea6\u4e66\u4e9a\u00b7\u8428\u8fbe\u7d22"], "director": "\u4ea8\u5229\u00b7\u6731\u65af\u7279"},
{"url": "https://movie.douban.com/subject/35141706/", "title": "\u4e1c\u5317\u5f80\u4e8b\uff1a\u6211\u53eb\u5218\u6d77\u67f1", "actors": ["\u8bb8\u541b\u806a", "\u5218\u5954", "\u9f9a\u5c0f\u94a7", "\u6768\u854a\u5609", "\u7530\u7490", "\u7a0b\u6c49", "\u6768\u8fea", "\u9093\u5b9b\u5343", "\u5f20\u94a7\u6db5", "\u9648\u94ee"], "director": "\u5468\u6da6\u6cfd"},
{"url": "https://movie.douban.com/subject/27131969/", "title": "\u65e0\u540d\u72c2", "actors": ["\u5f20\u6653\u6668", "\u968b\u548f\u826f", "\u4e0a\u767d", "\u5218\u6cf3\u5e0c", "\u8427\u5b50\u58a8", "\u8d75\u5065"], "director": "\u674e\u4e91\u6ce2"},
{"url": "https://movie.douban.com/subject/26389321/", "title": "\u65b0\u53d8\u79cd\u4eba The New Mutants", "actors": ["\u9ea6\u831c\u00b7\u5a01\u5ec9\u59c6\u65af", "\u5b89\u96c5\u00b7\u6cf0\u52d2-\u4e54\u4f0a", "\u827e\u8389\u4e1d\u00b7\u5e03\u62c9\u52a0", "\u5b89\u4e1c\u5c3c\u5965\u00b7\u73ed\u5fb7\u62c9\u65af", "\u67e5\u7406\u00b7\u5e0c\u987f", "\u6d77\u76ae\u00b7\u5b89\u5fb7\u68ee", "\u4ea8\u5229\u00b7\u624e\u683c", "\u5e03\u9c81\u00b7\u4ea8\u7279", "\u838e\u62c9\u00b7\u8d1d\u7eb3\u5c3c", "Colbi Gannett", "Tony Saquett", "Thomas Kee", "Mickey Gilmore", "Jeffrey Corazzini"], "director": "\u7ea6\u4ec0\u00b7\u5e03\u6069"},
{"url": "https://movie.douban.com/subject/26357307/", "title": "\u82b1\u6728\u5170 Mulan", "actors": ["\u5218\u4ea6\u83f2", "\u7504\u5b50\u4e39", "\u5de9\u4fd0", "\u674e\u8fde\u6770", "\u674e\u622a", "\u5b89\u67da\u946b", "\u9a6c\u6cf0", "\u8d75\u5bb6\u73b2", "\u90d1\u4f69\u4f69", "\u6e29\u660e\u5a1c", "\u66fe\u6653\u7ae5", "\u8881\u6587\u5fe0", "\u5510\u8fb0\u701b", "\u9053\u963f\u00b7\u8302\u963f", "\u9ec4\u8c37\u60a6", "\u5c3c\u5c14\u68ee\u00b7\u674e", "\u674e\u52cb", "\u9976\u96ea\u6676", "\u8881\u4e4b\u6b63", "\u4ec1\u6210\u5916\u6865", "\u52a0\u91cc\u00b7\u626c", "\u6b27\u6587\u00b7\u909d", "\u4e4c\u7279\u5361\u4ec0\u00b7\u5b89\u90a6\u5fb7\u5361\u5c14", "\u94b1\u59c6\u00b7\u827e\u5e0c\u52d2\u73c0\u62c9", "\u5927\u536b\u00b7T\u00b7\u6797", "\u8a79\u68ee\u00b7\u90d1", "Jun Yu"], "director": "\u59ae\u742a\u00b7\u5361\u7f57"},
{"url": "https://movie.douban.com/subject/30479644/", "title": "\u94c1\u96e82\uff1a\u9996\u8111\u5cf0\u4f1a \uac15\ucca0\ube442: \uc815\uc0c1\ud68c\ub2f4", "actors": ["\u90d1\u96e8\u76db", "\u90ed\u5ea6\u6c85", "\u67f3\u6f14\u9521", "\u5b89\u53e4\u65af\u00b7\u9ea6\u514b\u83f2\u767b", "\u5f90\u4e1c\u7532", "\u674e\u5357\u5e0c", "\u91d1\u91cd\u7199", "\u67f3\u79c0\u8363", "\u674e\u6cf0\u4ea8", "\u7533\u6b63\u6839", "\u5ec9\u6676\u96c5", "\u91d1\u5bb9\u7433", "\u91d1\u660e\u5764", "\u5f20\u5149", "\u674e\u5728\u52c7", "\u5b89\u5185\u76f8", "\u5b59\u949f\u5b66", "\u767d\u9f99", "\u5bc7\u6bd4\u00b7\u6cd5\u5170\u5947", "\u65af\u79d1\u7279\u00b7\u6d1b\u5a01\u5c14", "\u514b\u91cc\u65af\u6c40\u00b7\u8fbe\u5c14\u987f", "\u91d1\u80dc\u6cf0", "\u90d1\u9547\u73cf", "\u4fde\u6210\u67f1", "\u91d1\u91cd\u57fa", "\u7533\u79c0\u598d", "\u6c88\u7199\u71ee"], "director": "\u6768\u5b87\u7855"},
{"url": "https://movie.douban.com/subject/30299515/", "title": "\u91dc\u5c71\u884c2\uff1a\u534a\u5c9b \ubd80\uc0b0\ud5892-\ubc18\ub3c4", "actors": ["\u59dc\u680b\u5143", "\u674e\u8d1e\u8d24", "\u6743\u6d77\u9a81", "\u674e\u6765", "\u91d1\u654f\u8f7d", "\u5177\u6559\u7115", "\u91d1\u5ea6\u5141", "\u674e\u827a\u5a9b"], "director": "\u5ef6\u5c1a\u660a"},
{"url": "https://movie.douban.com/subject/30129061/", "title": "\u6211\u60f3\u7ed3\u675f\u8fd9\u4e00\u5207 I'm Thinking of Ending Things", "actors": ["\u6770\u897f\u00b7\u666e\u83b1\u8499", "\u6770\u897f\u00b7\u5df4\u514b\u5229", "\u6258\u59ae\u00b7\u79d1\u83b1\u7279", "\u5927\u536b\u00b7\u4f11\u91cc\u65af", "\u76d6\u4f0a\u00b7\u535a\u4f0a\u5fb7", "\u54c8\u5fb7\u8389\u00b7\u7f57\u5bbe\u900a", "\u683c\u65af\u00b7\u4f2f\u5c3c", "\u827e\u6bd4\u00b7\u594e\u56e0", "\u853b\u78a7\u00b7\u7c73\u7eb3\u83f2", "\u5b89\u4e1c\u5c3c\u00b7\u683c\u62c9\u7d22", "\u6cf0\u8fea\u00b7\u5e93\u5362\u5361", "\u6770\u68ee\u00b7\u62c9\u5c14\u592b", "\u5965\u5229\u5f17\u00b7\u666e\u83b1\u7279", "\u5f17\u96f7\u5fb7\u91cc\u514b\u00b7\u6c83\u4e01", "\u745e\u6069\u00b7\u65af\u8482\u5c14"], "director": "\u67e5\u7406\u00b7\u8003\u592b\u66fc"}
]
  • 也可以通过在settings.py中自定义ItemExporter实现其它输出。
设置 默认 功能
FEED_URI None 导出Feed的URI。
启用Feed导出时需要此设置。
FEED_FORMAT None 要用于Feed的序列化格式。
FEED_EXPORT_ENCODING None 要用于Feed的编码。
FEED_EXPORT_FIELDS None 要导出的字段的列表。
FEED_STORE_EMPTY False 是否导出空Feed
FEED_STORAGES_BASE 包含Scrapy支持的内置Feed存储后端的字典。
FEED_EXPORTERS {} 包含您的项目支持的其他导出器的字典。
FEED_EXPORTERS_BASE 一个包含Scrapy支持的内置feed导出器的dict。

参考资料


  • https://blog.csdn.net/u010138758/article/details/80152151 J-Ombudsman
  • https://www.cnblogs.com/zhuluqing/p/8832205.html moisiet
  • https://www.runoob.com 菜鸟教程
  • http://www.tulingxueyuan.com/ 北京图灵学院
  • http://www.imooc.com/article/19184?block_id=tuijian_wz#child_5_1 两点水
  • https://blog.csdn.net/weixin_44213550/article/details/91346411 python老菜鸟
  • https://realpython.com/python-string-formatting/ Dan Bader
  • https://www.liaoxuefeng.com/ 廖雪峰
  • https://blog.csdn.net/Gnewocean/article/details/85319590 新海说
  • https://www.cnblogs.com/Nicholas0707/p/9021672.html Nicholas
  • https://www.cnblogs.com/dalaoban/p/9331113.html 超天大圣
  • https://blog.csdn.net/zhubao124/article/details/81662775 zhubao124
  • https://blog.csdn.net/z59d8m6e40/article/details/72871485 z59d8m6e40
  • https://www.jianshu.com/p/2b04f5eb5785 MR_ChanHwang
  • 《Python学习手册》Mark Lutz
  • 《Python编程 从入门到实践》Eric Matthes
  • 《Python3网络爬虫开发实战》崔庆才

本文作者:大师兄(superkmi)

你可能感兴趣的:(大师兄的Python学习笔记(二十九): 爬虫(十))