# I.Scrapy框架架构:
# 1)框架概念:写一个爬虫,需要[发送网络请求,数据解析,数据存储,反反爬虫机制(更换ip代理、设置请求头等),异步请求等]这些工作如果每次都要自己从零开始写的话,比较浪费时间,因此Scrapy把一些基础的东西封装好了,在他上面写爬虫可以变的更加的高效(爬取效率和开发效率)
# 2)框架模块功能:
# 1.Engine:核心部分,负责在Spider和ItemPipeline,Downloader,Scheduler中间通信,传递数据等
# 2.Spider:爬虫部分,发送需要爬取的链接给引擎
# 3.Scheduler:调度器,负责接收引擎发送过来的请求,并按照一定的方式进行排列和整理,负责调度请求的顺序
# 4.Downloader:下载器,负责接收引擎传过来的下载请求,然后去网络上下载对应的数据再交还给引擎
# 5.Item Pipeline:管道,负责将Spider传递过来的数据进行保存
# 6.Downloader Middlewares:下载中间件,扩展下载器和引擎之间通信功能的中间件
# 7.Spider Middlewares:Spider中间件,扩展引擎和爬虫之间通信功能的中间件
# 3)框架入门:
# 3-1.安装(先装Twisted,pywin32,再装Scrapy)
# 3-2.创建项目(在命令行进入合适的路径创建:scrapy startproject [项目名称]->进入到项目所在的路径:scrapy genspider [爬虫名字] [爬虫的域名])
# # !!!注意!!!:爬虫名称不能和项目名称重复
# 3-3.项目结构目录介绍
# object_name
# spiders包:所有的爬虫,都是存放到此处
# items.py:用来存放爬虫爬取下来数据的模型
# middlewares.py:用来存放各种中间件的文件
# pipelines.py:用来将items的模型存储到本地磁盘中
# settings.py:本爬虫的一些配置信息(比如请求头,多久发送一次请求,ip代理池等)
# scrapy.cfg:项目的配置文件
# 3-4.调用项目(pycharm->file->open->上述创建的scrapy项目对应文件夹)
# 4)Scrapy框架爬取糗事百科及笔记:
# url:https://pan.baidu.com/s/12UtanoTD_mZrDkGlKSwDFw
# key:2cmy
# 4-1.!!!会遇到很多新的type,多打印type查看类型,然后import一下并且去查看这个类继承自哪个类,有什么方法可用!!!
# 例如:response是一个HtmlResponse类,继承自response类,可以使用xpath语法
# 上述用xpath语法提取出来的数据是Selector或是SelectorList类,继承自select类,如果想要获取其中的字符串,可以使用get():获取第一个文本str,或者getall():获取全部文本list
# 4-2.默认配置settings.py的修改:
# 修改配置信息中的ROBOTSTXT_OBEY = False,取消遵守机器协议
# 修改配置信息中的请求头将User-Agent加上
# 4-3.在spider下新建一个run.py,原因:scripy要用cmd执行爬虫,很麻烦,此处写上这个文件后续执行该文件即可
# 4-4.如果数据解析回来要传给pipelines保存,可以收集所有的items,统一return
# 4-5.item:建议在item.py文件中定义好模型,scrapy框架中放弃字典的使用
# 4-6.pipline:专门用做数据的保存,通常要定义四个方法:
# __init__(self):初始化
# open_spider(self,spider):当爬虫被打开时执行
# process_item(self,item,spider):当爬虫有item传过来时执行
# close_spider(self,spider):当爬虫被关闭时时执行
# 最后要激活pipline,应该修改默认配置settings.py,开启ITEM_PIPELINES部分
# 4-7.yield:生成器,运用于函数中会把函数包装为generator,然后对该generator进行迭代
# yield的功效理解为暂停和播放:在一个函数中,程序执行到yield语句的时候,程序暂停,返回yield后面表达式的值,在下一次调用的时候,从yield语句暂停的地方继续执行,如此循环直到函数执行完
# II.CrawlScrapy框架:
# 大体都是和普通的Scrapy框架是一致的,配置文件中取消遵守机器协议,请求头的添加,下载间隔开启,piplines的开启
# 1)框架概念:
# 传统Scrapy框架的变种,继承自Spider,在传统的Scrapy的基础之上增加了新的功能(定义爬取的url的规则:Scrapy碰到满足条件的url都进行爬取,而不用手动的yield Request)
# 2)创建项目:
# 在命令行进入合适的路径创建:scrapy startproject [项目名称]->进入到【项目所在的路径】:scrapy genspider -t crawl [爬虫名字] [爬虫的域名]
# 3)重要部分:
# 3-1.LinkExtractors链接提取器:爬取页面中满足【正则规则】的url,主要参数:
# allow:允许的url,所有满足这个正则表达式的url都会被提取
# deny:禁止的url,所有满足这个正则表达式的url都不会被提取
# allow_domains:允许的域名,只有在这个里面指定的域名的url才会被提取
# deny_domains:禁止的域名,所有在这个里面指定的域名的url都不会被提取
# 3-2.Rule规则类,主要参数:
# link_extractor:一个LinkExtractor对象,用于定义爬取规则
# callback:满足rule规则的url,要执行哪个回调函数
# follow:满足rule规则的从response中提取的链接是否需要跟进
# process_links:从link_extractor中获取到链接后会传递给这个函数,用来过滤不需要爬取的链接
# 4)CrawlScrapy框架爬取小程序社区
# url:https://pan.baidu.com/s/1ZNsxJkIBvryECQb41iACYg
# key:9ecp
# III.Scrapy中的Request和Response对象
# 1)!!!注意!!!
# 如果要在请求的第一步【直接发送(要去获取验证码这些不算)】POST请求需要注意三点:
# 1.需要重写默认的parse函数,改为start_request(self)
# 2.request不能用默认的scrapy.Request,需改成scrapy.FromRequest
# scrapy.Request -> GET , scrapy.FromRequest -> POST
# 2)Request对象:发送请求
# 常用参数:
# url:request对象发送的url
# callback:回调函数
# method:默认使用GET方法
# headers:请求头,通常固定的设置放在settings.py里就可以了,非固定的,可以再发送请求时特别指定
# encoding:编码,默认为utf-8
# dont_filter:表示不由调度器过滤,在执行多次重复请求时使用
# errback:报错时执行的函数
# 3)Response对象:用作提取信息,通常是Scrapy自动构建的
# 常用参数
# meta:保持多个请求之间的数据连接
# encoding:返回当前字符串编码和编码格式
# text:将返回来的数据作为unicode字符串返回
# body:将返回来的数据作为bytes字符串返回
# xpath:xpath选择器
# 4)Request,Response案例1-人人网登录
# 登录->访问大鹏主页->下载大鹏主页
# url:https://pan.baidu.com/s/1m6ch0rDCx4K9mPfALWfvOQ
# key:feoj
# 5)Request,Response案例1-豆瓣网登录
# 登录(识别验证码)->进入个人主页->修改个人签名
# url:https://pan.baidu.com/s/1HlHKj0SPlSo0KlH5-pC6gg
# key:50by
# 心得:可以尝试正常操作一下,找network中的信息(包括请求方式及请求地址等)
# IV.Scrapy内置的下载文件方法(Files Pipeline,Images Pipeline)
# 1)使用内置方法的原因:
# 1.异步下载,效率高(主要)
# 2.避免重新下载最近已经下载过的文件
# 3.可以方便的指定文件存储的路径
# 4.可以将下载的图片转换成通用的格式,比如png或jpg
# 5.可以方便的生成缩略图
# 6.可以方便的检测图片的宽和高,确保他们满足最小限制
# 2)下载文件的Files Pipeline:
# 1.定义好一个Item,然后在这个item中定义两个属性,分别为file_urls以及files(file_urls是用来存储需要下载的文件的url链接,要求列表的形式)
# 2.当文件下载完成后,会把文件下载的相关信息存储到item的files属性中(比如下载路径、下载的url和文件的校验码等)
# 3.在配置文件settings.py中配置FILES_STORE,这个配置是用来设置文件下载下来的路径
# 4.启动pipeline:在ITEM_PIPELINES中设置scrapy.pipelines.files.FilesPipeline:1
# 3)下载图片的Images Pipeline:
# 1.定义好一个Item,然后在这个item中定义两个属性,分别为image_urls以及images(image_urls是用来存储需要下载的文件的url链接,要求列表的形式)
# 2.当文件下载完成后,会把文件下载的相关信息存储到item的images属性中(比如下载路径、下载的url和文件的校验码等)
# 3.在配置文件settings.py中配置IMAGES_STORE,这个配置是用来设置文件下载下来的路径
# 4.启动pipeline:在ITEM_PIPELINES中设置scrapy.pipelines.images.ImagesPipeline:1
# 4)汽车之家图片下载
# url:https://pan.baidu.com/s/1SqNEjQ_KjkmDjAPaHgLilg
# key:tkoq
# 心得:
# 1.os.path.dirname(__file__)获取当前文件上一层的文件名
# 2.os.path.join()拼接生成路径
# 3.os.makedirs(2的路径),生成对应文件夹
# V.下载器中间件(Downloader Middlewares)
# 1)概念:下载器中间件是引擎和下载器之间通信的中间件,在这个中间件中我们可以设置代理,更换请求头等来达到反反爬虫的目的,要写下载器中间件,可以在下载器中间件中实现两个方法:
# 1.process_request(self,request,spider),请求发送之前执行
# 参数:
# 1.request:发送请求的request对象
# 2.spider:发送请求的spider对象
# 返回值:
# 1.返回None:Scrapy将继续处理该request,执行其他中间件中的相应方法,直到合适的下载器处理函数被调用
# 2.返回Response对象:Scrapy将不会调用任何其他的process_request方法,将直接返回这个response对象。已经激活的中间件的process_response()方法则会在每个response返回时被调用
# 3.返回Request对象:不再使用之前的request对象去下载数据,而是根据现在返回的request对象返回数据
# 2.process_response(self,request,response,spider),数据下载到引擎之前执行
# 参数:
# 1.request:request对象
# 2.response:被处理的response对象
# 3.spider:spider对象
# 返回值:
# 1.返回Response对象:会将这个新的response对象传给其他中间件,最终传给爬虫
# 2.返回Request对象:下载器链被切断,返回的request会重新被下载器调度下载
# 3.如果抛出一个异常,那么调用request的errback方法,如果没有指定这个方法,那么会抛出一个异常
# 2)设置随机请求头
# 1.通用操作(关闭机器人协议,添加请求头等)
# 2.middleware.py中配置:[文件名]DownloaderMiddleware
# i.设定随机请求头列表
# ii.process_request中调用rand.choice()选取随机请求头并赋值到request.headers["User-Agent"]
# 3.激活settings.py中的DOWNLOADER_MIDDLEWARES
# 3)设置随机请求头例子
# url:https://pan.baidu.com/s/1y98CT5WjF-ngerplNf4cuA
# key:c4ya
# 4)设置随机代理ip
# 1.购买并获取代理,及上述通用操作
# 2.middleware.py中配置:[文件名]DownloaderMiddleware
# i.设定随机代理ip列表
# ii.process_request中调用rand.choice()选取ip并赋值到request.meta["proxy"]
# 3.激活settings.py中的DOWNLOADER_MIDDLEWARES
# 5)设置随机代理ip例子
# url:https://pan.baidu.com/s/1S8aHmf0sWjd_bXxpGS_UkQ
# key:lm19