Scrapy 教程(二)-操作流程
scrapy 是个爬虫框架,是由python编写的,用法类似 django 框架。
创建工程
在开始爬虫之前,先创建工程
scrapy startproject projectname
目录结构如下图

文件说明
顶层的scrapy1是工程名
第二层的scrapy1相当于app名
scrapy.cfg 工程的配置信息,目的是使得工程能够正常运行
# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# https://scrapyd.readthedocs.io/en/latest/deploy.html [settings]
default = scrapy1.settings [deploy]
#url = http://localhost:6800/
project = scrapy1
spiders 用来创建具体的爬虫
settings.py 具体爬虫的配置文件,相当于django中app的settings
BOT_NAME = 'scrapy1' SPIDER_MODULES = ['scrapy1.spiders']
NEWSPIDER_MODULE = 'scrapy1.spiders'
items.py 设置数据存储的模板,用于结构化数据,相当于django中app的model
import scrapy class Scrapy1Item(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
pass
pipelines.py 数据处理行为,如数据持久化
class Scrapy1Pipeline(object):
def process_item(self, item, spider):
return item
middlewares.py 中间件
创建爬虫
一、在 spiders 文件夹中创建爬虫文件
可以手动创建,跟创建普通py文件一样;
也可以命令行创建;
进入工程目录,运行
scrapy genspider baidu baidu.com
baidu 表示文件名,也是爬虫名,也是爬虫类名;baidu.com是网站域名
class BaiduSpider(scrapy.Spider):
name = 'baidu'
allowed_domains = ['baidu.com']
start_urls = ['http://baidu.com/']
allowed_domains 表示搜索域,如果 start_urls 不在搜索域内,不会发送请求,但是经我实验,貌似也可以
注意 爬虫名不能和工程名相同

二、爬虫类的开发
1. 爬虫类需要继承自 scrapy的爬虫类型,如 scrapy.Spider
2. 必须显式定义 name 类属性,表示爬虫名;
3. 明确爬取的网址;
4. 重写 scrapy 的 start_requests 方法,用于下载页面,这个方法内显式调用解析器,网址也可以写在这个方法内(可选) 【start_requests 必须返回一个可迭代对象】
5. 解析器定义(也可选,如果没有,只下载就是了)
6. 也可以设置 custom_settings、crawler 属性【不常用,具体请百度】
7. close 方法,爬虫结束时,调用该方法。【不常用】
class Kachezhijia(scrapy.Spider): # 需要继承scrapy.Spider类
name = "kache" # 定义蜘蛛名 def start_requests(self):
''' 下载器'''
# 爬取的链接
urls = ['https://bbs.360che.com/thread-3119294-1-1.html']
for url in urls:
yield scrapy.Request(url=url, callback=self.parse) # 爬取到的页面提交给parse方法处理 def parse(self, response):
''' 解析器'''
# 这里只是做个简单存储
page = response.url.split("/")[-2]
filename = 'mingyan-%s.html' % page
with open(filename, 'wb') as f:
f.write(response.body)
self.log('保存文件: %s' % filename) # 调用父类的log方法
scrapy.Spider 类 并没有提供什么特殊方法,仅仅提供了 start_requests 的默认实现,即 读取并请求 start_urls 中的url,并根据 返回 response 调用 parse 方法。
如果不重写 start_requests,会运行父类的该方法,需要在 start_urls 中定义url;
如果不重写 start_requests ,解析器的名字必须为 parse,框架自动调用,如果不是parse,无法调用,如果重写了 start_requests,解析器名字随意,反正是显示调用
class Test2Spider(scrapy.Spider):
name = 'test2'
allowed_domains = ['baidu.com']
start_urls = ['https://bbs.360che.com/thread-3119294-1-1.html'] def parse(self, response):
''' 解析器'''
filename = 'test2.html'
with open(filename, 'wb') as f:
f.write(response.body)
self.log('保存文件: %s' % filename) # 调用父类的log方法
爬虫文件与items.py、pipelines.py 的关系
爬虫文件 返回 item,【item的格式是item.py中的类格式,类似字典】
这个item会被交给 scrapy 引擎,
引擎把item交给pipelines.py,
pipelines 会判断item是否是item.py的类型,如果是,会执行后续操作,然后必须返回item,【如果不返回,整个下载存储的链条会断掉】
item被交给后面的pipelines,如果只有一个pipelines,那item被交给 scrapy 引擎,引擎告知解析器。
运行爬虫
进入工程目录,运行
scrapy crawl test2
注意最后的 test2 是爬虫名,不是文件名,也不是爬虫类名
这里其实已经可以爬了,但是还有更专业的作法。
上面是解析的同时已经存储了,但是可以分开做。
数据模型
items.py,设定数据格式
class TianqiItem(scrapy.Item):
# define the fields for your item here like:
test = scrapy.Field()
管道操作
如存储数据
class TianqiPipeline(object):
def __init__(self):
self.f = open('save.txt', 'wb') def process_item(self, item, spider):
self.f.write(str(dict(item)))
return item def close_spider(self, spider): # 爬虫结束时执行该方法
self.f.close()
要执行管道需要在settings中进行设置
补充教程
这部分详见 《python 爬虫开发与项目实战》第13章
1. 在编写 spider 类时,我们继承了 scrapy.Spider,当然也可以继承其他类,如 CrawlSpider、XMLFeedSpider,来实现不同的爬虫任务,其用法都类似。
2. 在编写 parse 构建 item 时,可以使用 item loader,灵活高效,便于大型项目的维护

我们看到 name 字段从页面中两个位置提取,直接赋给一个字段
Scrapy 教程(二)-操作流程的更多相关文章
- Miniconda安装scrapy教程
一.背景说明 前两天想重新研究下Scrapy,当时的环境是PyCharm社区版+Python 3.7.使用pip安装一直报错 “distutils.errors.DistutilsPlatformEr ...
- Scrapy教程
Scrapy教程 原文地址https://doc.scrapy.org/en/latest/intro/tutorial.html 此教程我们假设你已经装好了Scrapy,如果没有请查看安装指南.. ...
- CRL快速开发框架系列教程二(基于Lambda表达式查询)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- 手把手教从零开始在GitHub上使用Hexo搭建博客教程(二)-Hexo参数设置
前言 前文手把手教从零开始在GitHub上使用Hexo搭建博客教程(一)-附GitHub注册及配置介绍了github注册.git相关设置以及hexo基本操作. 本文主要介绍一下hexo的常用参数设置. ...
- C#微信公众号开发系列教程二(新手接入指南)
http://www.cnblogs.com/zskbll/p/4093954.html 此系列前面已经更新了两篇博文了,都是微信开发的前期准备工作,现在切入正题,本篇讲解新手接入的步骤与方法,大神可 ...
- 无废话ExtJs 入门教程二十一[继承:Extend]
无废话ExtJs 入门教程二十一[继承:Extend] extjs技术交流,欢迎加群(201926085) 在开发中,我们在使用视图组件时,经常要设置宽度,高度,标题等属性.而这些属性可以通过“继承” ...
- 无废话ExtJs 入门教程二十[数据交互:AJAX]
无废话ExtJs 入门教程二十[数据交互:AJAX] extjs技术交流,欢迎加群(521711109) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C ...
- 无废话ExtJs 入门教程二[Hello World]
无废话ExtJs 入门教程二[Hello World] extjs技术交流,欢迎加群(201926085) 我们在学校里学习任何一门语言都是从"Hello World"开始,这里我 ...
- Android Studio系列教程二--基本设置与运行
Android Studio系列教程二--基本设置与运行 2014 年 11 月 28 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处! 上面一篇博客,介绍了Studio的 ...
随机推荐
- 19.顺时针打印矩阵(python)
题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数 ...
- 2019学军集训记&PKUWC2020游记
题解:https://www.cnblogs.com/gmh77/p/12051260.html 集训(×) 被虐(√) Day1 二段考 Day2 绝对不鸽 没那回事 还在路上 其实就是咕了两天 晚 ...
- UNIX标准C - socket套接字
一.计算机网络 1.计算机网络的功能 a.数据通信 b.资源共享 c.提高系统的可靠性 d.分布式网络处理和负载均匀. 2.计算机网络的组成 1.通信子网:由网卡.线缆.集线器.中继器.交换器.路由器 ...
- Codeforces 1203F1 Complete the Projects (easy version)
cf题面 Time limit 2000 ms Memory limit 262144 kB 解题思路 看见这题觉得贪心可做,那就贪吧.(昨天真是贪心的一天,凌晨才被这两道贪心题虐,下午多校又来,感觉 ...
- 编译依赖ndt_gpu库的包,遇到Eigen报错
背景: 使用NDT建图,帧率比较慢,打算使用gpu加速计算. ndt_gpu是一个使用gpu加速ndt计算的库,首先在工作空间编译这个包. 然后在ndtMap包中链接这个库,其CMakelists.t ...
- 随堂小测APP使用体验
随堂小测APP使用体验 先要去注册账号需要填写用户名.密码.手机号.学号/教师号.学校.专业.即可注册,注册成功后,即可登录APP进,登陆进去以后.会有两个界面,课堂和我的,注册.登录简单,通俗易懂, ...
- FP回写阶段卡住或报错
FP在autosap阶段往往会因各种各样的因素导致回写报错,卡住等异常: 本次由于一个视图的性能突然下降导致回写长期卡住没有完成: 这时如果要重新执行回写的话就要检查哪部分的数据回写到SAP端,一般有 ...
- es之索引的别名操作
1:增加别名 为索引school添加一个别名alias1: 1.1:创建索引 PUT student{ "settings": {"number_of_shards&qu ...
- git创建公钥匙
目的: 使用SSH公钥可以让你在你的电脑和码云通讯的时候使用安全连接(git的remote要使用SSH地址) 1.打开终端进入.ssh目录输入当下命令 cd ~/.ssh 如果.ssh文件夹不存在,执 ...
- shell脚本之case用法
你会经常发现自己在尝试计算一个变量的值,在一组可能的值中寻找特定值.在这种情形下, 你不得不写出很长的if-then-else语句,就像下面这样. $ cat test25.sh #!/bin/bas ...