'''
1.简述
之前自定义的爬虫,都是相似的过程,请求url,解析响应,保存数据,相同的逻辑,框架实现了封装结构,避免重复的逻辑,只关注不同点,
针对不同的网站解析方法不同,而且不同的业务需求保存的方式也不同,所以只关注这些部分,scrapy的性能优越底层使用twisted自定义协议框架来写的
而且实现分布式爬虫简单
框架结构:
Scrapy Engine: 中间商,核心引擎,其他部分都是通过引擎中转的
Scheduler: 调度器, 存放url列表的 消息队列, 不断从引擎获取url放入列表,然后再拿出url经过引擎发给 下载器
Downloader:下载器, 发出请求 获取响应, 通过引擎 把响应发送给 Spiders 解析
Spiders: 第一次请求的网页放在这,通过引擎发送给 调度器开始第一次请求
其中的方法来 解析响应 ,通过引擎发送给 Item Pipeline 保存,当解析出url的时候又再次发给调度器循环
Item Pipeline: 保存模块,Item是一个容器,写成字段格式来帮我们验证
Pipeline 管道 根据保存的方式不同写不同的管道
中间件: 伪装身份的部分
'''
'''
2.基本使用
创建项目:
scrapy startproject 项目名
scrapy.cfg 部署到线上使用
settings 配置
pipeline 保存模块
item 容器,写模型类的内容,建模
middlewares 中间件
spiders 所有的爬虫模块,解析模块
对建模的说明:
item是个容器,解析后的数据用它来保存,那么你解析出来的需要的是什么内容,
建模就校验相关内容,比如需要解析后的name,title,content,image_url,
那建模4个字段, name = scrapy.Field()
实例化item对象,解析的内容直接保存到item对象中
'''
'''
3.创建爬虫
scrapy genspider 爬虫名字 爬虫允许的爬取域名(这样友情链接属于另一家网址的内容就不会去爬)
根据允许的爬取范围自动生成 第一次请求的网址,注意写简写要不然需要检验一下start_url
'''
'''
4.运行 scrapy crawl 爬虫名(注意没有.py)
feed输出:scrapy crawl 爬虫名 -o 文件名.csv 输出成需要的格式文件
'''
'''
5.spider类
说明:
(1)extract_first : 所有的list out of index 报错都是因为对list有操作,但是你操作的index不成功不存在,
所以当xpath匹配节点获得的内容为空时,使用extract方法并且[0]切片会报错,这时候使用extract_first拿出第一个
如果为空那自动补充为None,但是要是段落的话其中有 '' 空,那拿出第一个之后可能会少内容
(2)spider模块,第一个功能解析,自带了函数默认第一次请求返回的响应使用parse函数来解析,
第二个功能新解析出来的url返回给引擎,使用 scrapy.Request 构造请求
参数 scrapy.Request(url, callback=解析函数名,没有())
callback指明新的请求结果由哪个函数来解析
比如:继续请求列表页面的下一页,那新获得的响应应该使用 原有parse继续解析继续翻页
当每次都需要请求详情页时,返回的内容应该指定新方法 parse_detail
(3)当在列表页提取部分数据,然后详情页也有部分数据时,使用mate参数(是个字典)
def parse():
解析完列表页,获得每个详情页的url,放入容器
item['detail_url'] = 前缀 + node.xpath()
yield scrapy.Request(item['detail_url'],callback=self.parse_detail,meta= {'meta这个写什么都行' : item})
这样我把列表页中需要的内容放入容器item中,然后请求详情页,在详情页响应 的对应请求的meta参数中能够拿出容器item继续保存
即:
def parse_detail():
item = response.request.meta['meta']
yield item 这样就实现了分开保存
(4)在管道pipeline部分,所有的爬虫管道都在这个模块,而且每次爬虫模块返回的都是item
那管道部分每个管道都会执行保存
判断 if isinstance(item,所属item类) 当前得到的item是不是这个管道对应的item类实例化的对象
(5)Request参数
(url 请求的地址, callback 针对响应的解析函数, meta 传参,headers 请求头,cookies ,dont_filter 不被调度器过滤,重复依然发起请求)
dont_filter : 所有的url是被放到调度器中的url列表,如果重复了有自动去重的功能,避免重复访问,参数设置True,那就是不过滤
(6)针对post请求
FormRequest类 ,请求体参数 formdata = { } 适用于 登录 和需要在请求体中传参
注意:需要重写 start_requests 方法,即手动实现第一次发出请求,而且这个页面是需要已经登录才能看的
def start_requests(self):
url = self.start_urls[0]
post_data = {
}
yield scrapy.FormRequest(url,formdata=post_data) 得到的响应就是已经登录才能看到的信息
from_response方法:
这个方法第一次请求的网页就是登录页面,从响应中获取登录表单,在对登录表单发送数据,走新的回调函数
def parse(self, response):
post_data = { }
yield scrapy.FormRequest.from_response(response, formdata=post_data, callback=self.parse_login)
从登录页面的响应中,获取表单,填入账号密码,再次请求回来的响应走parse_login函数, 比较局限只能登录,不能传请求体数据,而且表单多个需要声明填到哪个中
'''
'''
6.CrawlSpider类(根据Rules提取url并自动请求)
创建方法:
scrapy genspider -t crawl 爬虫名 限制域名
说明:使用比较局限, parse函数不能重写,注意它自己的解析函数是parse_item
# 编写规则部分
rules = (
# LinkExtractor 链接提取器 , 提取详情页面链接 自动请求 执行解析函数,注意是 字符串 ,就不再对详情页的连接继续提取了
Rule(LinkExtractor(allow=r'html/question/\d+/\d+.shtml'), callback='parse_item'),
# 列表页面链接 (这个链接是底下点击哪个就跳转到哪一页) follow参数,提取的连接自动访问,回来的响应继续根据规则提取,实现了翻页
Rule(LinkExtractor(allow=r'index.php/question/questionType\?type=4&page=\d+'), follow=True),
)
rules的参数:
linkextractor 链接提取器,提取的链接会自动补全域名,并发出请求
callback 响应的处理函数
follow 根据规则提取链接并请求,响应之后是否要跟进提取
process_links 对提取的连接进行过滤(提取器提取之后执行,处理之后形成链接列表)
process_requests 对生成的请求进行过滤(根据链接生成请求之后执行)
'''
'''
7.setting文件的配置说明
ROBOTSTXT_OBEY : 爬虫协议
DOWNLOAD_DELAY : 请求延时,网址会有正常访问的阈值,根据阈值来设置访问的休眠
COOKIES_ENABLED : cookie是否带上来
DEFAULT_REQUEST_HEADERS : 默认请求头
DOWNLOADER_MIDDLEWARES : 下载器中间件,需要注册
ITEM_PIPELINES : 管道,需要注册
LOG_ENABLED : 是否开启日志
LOG_ENCODING : 日志的编码
LOG_FILE : 日志保存到文件中的位置
LOG_LEVEL : 日志等级 DEBUG, INFO, WARNING, ERROR, CRITICAL(严重错误)
CONCURRENT_REQUESTS : 下载器并发数量,默认16
DEPTH_LIMIT : 爬取深度
DOWNLOAD_TIMEOUT : 下载超时
CONCURRENT_ITEMS : item管道同时处理item数量
CONCURRENT_REQUESTS_PER_DOMAIN : 域名的并发请求数量
CONCURRENT_REQUESTS_PER_IP : IP的并发请求数量
'''
1.简述
之前自定义的爬虫,都是相似的过程,请求url,解析响应,保存数据,相同的逻辑,框架实现了封装结构,避免重复的逻辑,只关注不同点,
针对不同的网站解析方法不同,而且不同的业务需求保存的方式也不同,所以只关注这些部分,scrapy的性能优越底层使用twisted自定义协议框架来写的
而且实现分布式爬虫简单
框架结构:
Scrapy Engine: 中间商,核心引擎,其他部分都是通过引擎中转的
Scheduler: 调度器, 存放url列表的 消息队列, 不断从引擎获取url放入列表,然后再拿出url经过引擎发给 下载器
Downloader:下载器, 发出请求 获取响应, 通过引擎 把响应发送给 Spiders 解析
Spiders: 第一次请求的网页放在这,通过引擎发送给 调度器开始第一次请求
其中的方法来 解析响应 ,通过引擎发送给 Item Pipeline 保存,当解析出url的时候又再次发给调度器循环
Item Pipeline: 保存模块,Item是一个容器,写成字段格式来帮我们验证
Pipeline 管道 根据保存的方式不同写不同的管道
中间件: 伪装身份的部分
'''
'''
2.基本使用
创建项目:
scrapy startproject 项目名
scrapy.cfg 部署到线上使用
settings 配置
pipeline 保存模块
item 容器,写模型类的内容,建模
middlewares 中间件
spiders 所有的爬虫模块,解析模块
对建模的说明:
item是个容器,解析后的数据用它来保存,那么你解析出来的需要的是什么内容,
建模就校验相关内容,比如需要解析后的name,title,content,image_url,
那建模4个字段, name = scrapy.Field()
实例化item对象,解析的内容直接保存到item对象中
'''
'''
3.创建爬虫
scrapy genspider 爬虫名字 爬虫允许的爬取域名(这样友情链接属于另一家网址的内容就不会去爬)
根据允许的爬取范围自动生成 第一次请求的网址,注意写简写要不然需要检验一下start_url
'''
'''
4.运行 scrapy crawl 爬虫名(注意没有.py)
feed输出:scrapy crawl 爬虫名 -o 文件名.csv 输出成需要的格式文件
'''
'''
5.spider类
说明:
(1)extract_first : 所有的list out of index 报错都是因为对list有操作,但是你操作的index不成功不存在,
所以当xpath匹配节点获得的内容为空时,使用extract方法并且[0]切片会报错,这时候使用extract_first拿出第一个
如果为空那自动补充为None,但是要是段落的话其中有 '' 空,那拿出第一个之后可能会少内容
(2)spider模块,第一个功能解析,自带了函数默认第一次请求返回的响应使用parse函数来解析,
第二个功能新解析出来的url返回给引擎,使用 scrapy.Request 构造请求
参数 scrapy.Request(url, callback=解析函数名,没有())
callback指明新的请求结果由哪个函数来解析
比如:继续请求列表页面的下一页,那新获得的响应应该使用 原有parse继续解析继续翻页
当每次都需要请求详情页时,返回的内容应该指定新方法 parse_detail
(3)当在列表页提取部分数据,然后详情页也有部分数据时,使用mate参数(是个字典)
def parse():
解析完列表页,获得每个详情页的url,放入容器
item['detail_url'] = 前缀 + node.xpath()
yield scrapy.Request(item['detail_url'],callback=self.parse_detail,meta= {'meta这个写什么都行' : item})
这样我把列表页中需要的内容放入容器item中,然后请求详情页,在详情页响应 的对应请求的meta参数中能够拿出容器item继续保存
即:
def parse_detail():
item = response.request.meta['meta']
yield item 这样就实现了分开保存
(4)在管道pipeline部分,所有的爬虫管道都在这个模块,而且每次爬虫模块返回的都是item
那管道部分每个管道都会执行保存
判断 if isinstance(item,所属item类) 当前得到的item是不是这个管道对应的item类实例化的对象
(5)Request参数
(url 请求的地址, callback 针对响应的解析函数, meta 传参,headers 请求头,cookies ,dont_filter 不被调度器过滤,重复依然发起请求)
dont_filter : 所有的url是被放到调度器中的url列表,如果重复了有自动去重的功能,避免重复访问,参数设置True,那就是不过滤
(6)针对post请求
FormRequest类 ,请求体参数 formdata = { } 适用于 登录 和需要在请求体中传参
注意:需要重写 start_requests 方法,即手动实现第一次发出请求,而且这个页面是需要已经登录才能看的
def start_requests(self):
url = self.start_urls[0]
post_data = {
}
yield scrapy.FormRequest(url,formdata=post_data) 得到的响应就是已经登录才能看到的信息
from_response方法:
这个方法第一次请求的网页就是登录页面,从响应中获取登录表单,在对登录表单发送数据,走新的回调函数
def parse(self, response):
post_data = { }
yield scrapy.FormRequest.from_response(response, formdata=post_data, callback=self.parse_login)
从登录页面的响应中,获取表单,填入账号密码,再次请求回来的响应走parse_login函数, 比较局限只能登录,不能传请求体数据,而且表单多个需要声明填到哪个中
'''
'''
6.CrawlSpider类(根据Rules提取url并自动请求)
创建方法:
scrapy genspider -t crawl 爬虫名 限制域名
说明:使用比较局限, parse函数不能重写,注意它自己的解析函数是parse_item
# 编写规则部分
rules = (
# LinkExtractor 链接提取器 , 提取详情页面链接 自动请求 执行解析函数,注意是 字符串 ,就不再对详情页的连接继续提取了
Rule(LinkExtractor(allow=r'html/question/\d+/\d+.shtml'), callback='parse_item'),
# 列表页面链接 (这个链接是底下点击哪个就跳转到哪一页) follow参数,提取的连接自动访问,回来的响应继续根据规则提取,实现了翻页
Rule(LinkExtractor(allow=r'index.php/question/questionType\?type=4&page=\d+'), follow=True),
)
rules的参数:
linkextractor 链接提取器,提取的链接会自动补全域名,并发出请求
callback 响应的处理函数
follow 根据规则提取链接并请求,响应之后是否要跟进提取
process_links 对提取的连接进行过滤(提取器提取之后执行,处理之后形成链接列表)
process_requests 对生成的请求进行过滤(根据链接生成请求之后执行)
'''
'''
7.setting文件的配置说明
ROBOTSTXT_OBEY : 爬虫协议
DOWNLOAD_DELAY : 请求延时,网址会有正常访问的阈值,根据阈值来设置访问的休眠
COOKIES_ENABLED : cookie是否带上来
DEFAULT_REQUEST_HEADERS : 默认请求头
DOWNLOADER_MIDDLEWARES : 下载器中间件,需要注册
ITEM_PIPELINES : 管道,需要注册
LOG_ENABLED : 是否开启日志
LOG_ENCODING : 日志的编码
LOG_FILE : 日志保存到文件中的位置
LOG_LEVEL : 日志等级 DEBUG, INFO, WARNING, ERROR, CRITICAL(严重错误)
CONCURRENT_REQUESTS : 下载器并发数量,默认16
DEPTH_LIMIT : 爬取深度
DOWNLOAD_TIMEOUT : 下载超时
CONCURRENT_ITEMS : item管道同时处理item数量
CONCURRENT_REQUESTS_PER_DOMAIN : 域名的并发请求数量
CONCURRENT_REQUESTS_PER_IP : IP的并发请求数量
'''