爬虫在使用场景中的分类
通用爬虫:抓取系统重要组成部分。抓取的是一张页面数据
聚焦爬虫:是建立在通用爬虫的基础之上。抓取的是页面中特定的局部内容
增量是爬虫:检测网站中数据更新的情况。只会抓取网站中最新更新出的数据
爬虫的矛与盾
反爬机制:门户网站,可以制定相应的策略或者技术手段,防止爬虫程序进入网站爬取数据
反反爬策略:爬虫程序可以制定相关的策略或者技术手段,破解门户网站中具备的反爬机制,从而获得门户网站数据
robots.txt协议:规定了网站中那些数据可以被爬虫抓取哪些不能
http协议
概念:服务器和客户端进行数据交互的一种形式
常用请求头信息
User-Agent:请求载体的身份标识
Connection:请求完毕后,是断开连接还是保持链接
常用响应头信息
Connent-Type:服务器响应客户端的数据类型
https协议
安全的超文本传输协议
加密方式
对称秘钥加密
非对称秘钥加密
证书秘钥加密
作用:模拟浏览器发请求
如何使用:(requests模块的编码流程)
指定rul
发起请求
获取响应数据
持久化存储
环境安装:
pip install requests
实战巩固
需求:爬取搜狗指定词条对应的搜索结果页面(简单网页采集器)
UA检测、UA伪装
需求:破解百度翻译
需求:爬取豆瓣电影分类排行榜
需求:爬取肯德基餐厅查询
需求:爬取国家药品监督管理总局基于中华人民共和国化妆品生产许可证相关数据
课程1-10
聚焦爬虫:爬取页面中指定的页面内容
编码流程:
指定url
发起请求
获取响应数据
数据解析
持久化存储
数据解析分类:
正则
bs4
xpath
数据解析原理:
解析的局部的文本内容都会在标签之间或者标签对应的属性中进行存储
进行指定标签的定位
标签或者标签对应的属性中存储的数据值进行提取(解析)
数据解析原理
标签定位
提取标签、标签属性中存储的数据值
bs4数据解析的原理
实例化一个BeautifulSoup对象,并且将页面源码数据加载到对象中
通过调用BeautifulSoup对象中相关的属性或者方法进行标签定位和数据提取
如何实例化BeautifulSoup对象:
对象实例化
将本地的html文档中的数据加载到该对象中
fp = open('./test,html','r',encoding='utf-8') soup = BeautifulSoup(fp,'lxml')
将互联网上获取的页面源码加载到该对象中
page_text = response.text soup = BeautifulSoup(page_text,'lxml')
提供的用于数据解析的方法和属性:
soup.tagname: 返回的是文档中第一次出现的tagname对应的标签
soup.find():
find('tagname'):等同于soup.tagname
属性定位 soup.find('div',class_='song')
soup.find_all('tagname'):返回符合要求的所有标签
soup.select():
select('某种选择器(id,class,标签。。。选择器),返回的是一个列表
层级选择器:
soup.select('.tang > ul > li > a'): >表示的是一个层级
soup.select('.tang > ul a'):空格表示的多个层级
获取标签之间的文本数据:
soup.a.text/string/get_text()
text/get_text():可以获取某个标签中所有文本的内容
string:只可以获取改标签下面直系的文本内容
获取标签中属性值
soup.a['href']
xpath解析原理:
实例化一个etree的对象,且需要将被解析的页面源码数据解析到该对象中
调用etree对象中的xpath方法结合着xpath表达式实现标签定位和内容捕获
环境安装
pip install lxml
如何实例化一个etree的对象,且需要将被被解析的页面源码数据解析到该对象中
将本地的html文档中源码数据加载到etree对象中
etree.parse(filepath)
可以将互联网上获取的源码数据加载到etree对象中
xpath表达式
/ :表示的是从根节点开始定位,表示的是一个层次
//: 表示的是多个层级,可以表示从任意位置开始定位
属性定位://div[@class='song'] tag[@attrname='attrvalue']
索引定位: //div[@class='song']/p[3] 索引是从1开始的
取文本:
/text() 获取的是标签中直系的文本内容
//text() 标签中非直系的文本内容(所有的文本内容)
取属性:
/@ttrname -------> img/src
反爬机制:验证码。识别验证码图片中的数据,用于模拟登陆操作
识别验证码的操作
人工肉眼识别(不推荐)
第三方自动识别(推荐)
云打码:http://www.yundama.com/demo.html
云打码的使用流程:
注册:普通和开发者用户
登录
普通用户的登录:查询该用户是否还有剩余的题分
开发者用户的登录
创建一个软件:我的软件-->添加新软件-->录入软件名称-->提交(软件id和秘钥)
下载示例代码:开发文档-->点此下载-->pythonHTML实例下载
http、https协议特性:无状态
没有请求到对应页面数据的原因:
发起的第二次基于个人主页面请求的时候,服务器端并不知道该次请求是基于登录状态的请求
cookie:用来让服务器端记录客户端的相关状态
方法:
手动处理
通过抓包工具获取cookie值,将该值封装到headers中
自动处理
cookie来自哪里:模拟登陆post请求后,有服务器端创建
session回话对象:
作用1:可以进行请求的发送
作用2:如果请求过程中产生cookie,则cookie会被自动存储、携带在该session对话中
创建一个session对象:session=requests.Session()
使用session对象进行模拟登陆post请求的发送(cookie就会被存储在session中)
session对象对个人主业对应的get请求进行发送(携带了cookie)
解释:破解封IP这种反爬机制
什么是代理:代理服务器
代理的作用:
突破自身IP访问的限制
隐藏自身真是IP
代理相关网站:
快代理
西刺代理
www.goubanjia.com
代理IP类型:
http:应用到http协议对应的url中
https:应用到https协议对应的url中
代理IP的匿名度:
透明:
匿名
高匿
目的:在爬虫中使用异步实现高性能的数据爬取操作
异步爬虫的方式:
多线程,多进程(不建议):
好处:可以为相关阻塞的操作单独开启线程或者进程,阻塞操作就可以异步执行
弊端:无法无限制的开启多线程或者多进程
线程池、进程池(适当使用):
好处:我们可以降低系统对进程或者线程创建和销毁的频率,从而很好地降低系统的开销
弊端:池中线程或进程的数量是有上限
※单线程+异步携程(推荐):
event_loop:事件循环,相当于一个无限循环,我们可以把一些函数注册到这件事件循环上,当满足某些条件的时候,函数会被循环执行
coroutine:协程对象,我们可以将协程对象注册到事件循环中,它会被事件循环调用,我们可以使用async关键字来定义一个方法,这个方法在调用时不会立即被执行,而是返回一个协程对象
task:任务,他是对协程对象的进一步封装,包含了任务的各个状态
future:代表将来执行或还没有执行的任务,实际上和task没有本质区别
async:定义一个协程
await:用来挂起阻塞方法的执行
就是一个集成了很多功能并且具有很强通用性的一个项目模板
专门学习框架封装的各种功能的详细用法
爬虫中分装好一个明星框架。功能:高性能的持久化存储,异步的数据下载,高性的数据解析,分布式
环境安装:pip install scrapy
创建一个工程:
scrapy startproject xxxPro
cd xxxPro
在spiders子目录中创建一个爬虫文件
scrapy genspider spiderName www.xxx.com
执行工程 scrapy crawl spiderName
scrapy数据解析:
scrapy持久化存储
基于终端指令
要求:只可以将parse方法的返回值存储到本地文本文件中
注意:持久化存储对应的文本文件的类型只可以为:json,jsonlines,jl,csv,xml
指令:scrapy crawl xxx -o filepath
优点:简介高效便捷
缺点:局限性比较强(数据只可以存储到指定后缀文本文件中)
基于管道
编码流程
数据解析
在item类中定义相关的属性
将解析的数据封装存储到item类型的对象
将item类型的对象提交给管道进行持久化存储的操作
在管道类的process_item中要将其接收到的item对象中存储的数据进行持久化存储操作
在配置文件中开启管道
好处:通用性强
面试题:将爬取到的数据一份存储到本地一份存储到数据库,如何实现?
管道文件中一个管道类对应的是将数据存储到一种平台
爬虫文件提交的item只会给管道文件中第一个被执行的管道类接收
process_item中return item表示将item传递给下一个即将被执行的管道类
就是将网站中某板块的全部页码对应的页面数据进行爬取
需求;爬取4k网站中照片的名称
实现方式:
将所有页面的url添加到start_urls列表(不推荐
自动手动进行请求发送(推荐
引擎(Scrapy)
用来处理整个系统的数据流处理、触发事务(框架核心)
调度器(Scheduler)
用来接收引擎发过来的请求,压入队列中,并在引擎再次请求的时候返回,想象成一个url(抓取网页的网址或者说是链接)的有限队列,由它来决定下一个要抓取的网址是什么,同时去除重复的网址
下载器(Downloader)
用于下载网页内容,并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted)这个高效的异步模型上的
爬虫(Spiders)
爬虫是主要干活的,用于从特定的网页中提取自己需要的信息,即所谓的实体。用户也可以从中提取链接,让Scrapy继续抓取下一个页面
项目管道(Pipeline)
负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体,验证实体的有效性,当网页被爬虫解析后,将被发送的项目管道,并经过几个特定的次序处理数据。
使用场景:如果爬取解析的数据不在同一张页面中(深度爬取)
基于scrapy爬取字符串类型的数据和爬取图片类型的数据区别?
字符串:只需要基于xpath进行解析且提交管道进行持久化存储
图片:xpath解析出图片src的属性值,单独的对图片地址发起请求获取图片二进制类型的数据
ImagesPipeline:
只需要将img的src的属性值进行解析,提交到管道,管道就会对图片的src进行请求发送获取图片的二进制类型的数据,且还会帮我们进行持久化存储
使用流程
数据解析(图片的地址)
将存储图片地址的item提交到指定的管道类
在管道文件中自定制一个基于ImagesPipeLine的一个管道类
get_media_request
file_path
item_completed
在配置文件中:
指定图片存储的目录:IMAGES_STORE='./imgs_bobo'
指定开启的管道:自定制的管道类
下载中间件
位置:引擎和下载器之间
作用:批量拦截到整个工程中所有的请求和响应
拦截请求:
UA伪装:process_request
代理IP:process_exception: return request
拦截响应:
篡改响应数据、响应对象
需求:爬取网易新闻中的新闻数据(标题和内容)
通过网易新闻的首页解析出五大板块对应的详情页的url(没有动态加载)
每一个板块对应的新闻标题都是动态加载出来的(动态加载)
通过解析出每一条新闻详情页的url获取详情页的页面源码,解析出新闻内容
全站数据爬取的方式:
基于Spider:手动请求
基于CrawSpider
CrawlSpider的使用:
创建一个工程
cd xxx
创建爬虫文件(CrawlSpider):
scrapy genspider -t crawl xxx www.xxx.com
链接提取器:
作用:根据指定的规则(allow)进行指定链接的提取
规则提取器:
作用:将链接提取器提取到的链接进行指定规则(callback)的解析
需求:爬取sun网站中的编号,新闻标题,新闻内容,标号
分析:爬取的数据没有在同一张页面中
可以使用链接提取器提取所有的页码链接
让链接提取器提取所有的新闻详情页的链接
概念
需要搭建一个分布式的机群,让其对一组资源进行分布联合爬取
作用
提升爬取数据的效率
如何实现分布式
安装一个scray-redis的组件
原生的scrapy是不可以实现分布式爬虫,必须要与scrapy-redis组合一起实现
为什么scrapy不可以实现分布式
调度器不可以被分布式集群共享
管道不可以被分布式机群共享
scrapy-redis组件作用:
可以给原生的scrapy框架提供可以被共享的管道和调度器
实现流程
创建一个工程
创建一个基于CrawlSpider的爬虫文件
修改当前的爬虫文件