1.http & https 协议
- http协议
- 概念:服务器与客户端进行数据交互的一种形式。
- 常用请求头信息
- User-Agent: 请求载体的身份标识
- Connection: 请求完毕后,是断开连接还是保持连接
- 常用响应头信息
- Content-Type: 服务器响应回客户端的数据类型
- https协议
- s(secure)安全的超文本传输协议
- 加密方式
- 对称密钥加密
- 非对称密钥加密
- 证书密钥加密
2.requests模块
requsets模块的编码流程
作用:模拟浏览器发请求。
如何使用:
- 指定url
- 发起请求
- 获取响应数据
- 持久化存储
3.反爬机制
UA检测
- 门户网站的服务器会检测对应请求的载体身份标识,如果检测到一个请求载体的身份是一个浏览器,则为正常请求。 但是如果检测到的请求载体不是一个浏览器,则不是一个正常请求(爬虫),服务器可以拒绝这次请求。
UA伪装
- 让爬虫对应的请求载体身份标识伪装成浏览器
下面贴一个简单的爬虫代码:
1 | import requests |
4. 聚焦爬虫
爬取页面中指定的页面内容
数据解析分类:
- 正则
- bs4
- xpath
数据解析原理概述:
- 解析的局部的文本内容都会在标签之间或者标签对应的属性中进行存储
- 1.进行指定标签的定位
- 2.标签或者标签对应的属性中存储的数据值进行提取(解析)
获得响应数据格式
- text:得到网页的html源码数据
- json:阿贾克斯请求的json数据
- content:图片的二进制数据
5.正则表达式
[Pp]ython
:用来匹配[Pp]中出现一次的[Pp]ython[0-9a-z]
:用来匹配0到9,a到z之间的任意字符[^0-9]
:匹配除数字外的任意字符\d
:匹配所有数字\w
:匹配所有字符(包括数字大写字母小写字母)\s
:匹配空白(包括空格Tab换行)\b
:匹配单词的边界上述四种效果取反,只需要将各个字母取大写即可,\D,\W,\S,\B
^python
:匹配以p开头python$
:匹配以n结尾.
:匹配任意字符(只有换行不能匹配)?
:可选字符(如:honou?r,表示u可以出现0次或1次){3}
:出现三次(如\d{3}匹配3个数字){3,4}
:出现三或四次(如\d{3,4}匹配3个或4个数字){3,}
:出现三次以上(如\d{3,}匹配3个以上的数字)+
等价于{1,} ,*
等价于{0,}|
:或者的含义()
:捕获一个分组(?:表达式)
:非捕获分组\1
:(回溯引用)匹配第一个分组(如前面匹配多个分组,此写法会使得此匹配与第一个分组一模一样匹配)(?=)
:(正向先行断言) 如:因为(?=你),匹配因为后面为你,提取因为分组(?!)
:(反向先行断言) 如:因为(?!你),匹配因为后面不为你,提取因为分组(?<=)
:(正向后行断言) 如:(?<=我)因为(?=你),匹配因为前面是我后面是你,提取因为分组(?<!)
:(反向后行断言) 如:(?<=我)因为(?<!你),匹配因为前面是我后面不是你,提取因为分组
6.bs4数据解析原理
- 实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中。
- 通过调用BeautifulSoup中相关属性和方法进行标签定位与数据提取。
如何实例化Beautifulsoup对象?
- from bs4 import BeautifulSoup
- 对象的实例化
- 将本地的html数据加载到该对象中
fp = open(./test.html,"r",encording="utf-8")
soup = BeautifulSoup(fp,"lxml")
- 将互联网上的页面源码加载到该对象中
page_text = response.text
soup = BeautifulSoup(page_text,"lxml")
- 将本地的html数据加载到该对象中
- 提供用于数据解析的方法与属性:
- soup.tagName:返回的是文档中第一次出现的tagName对应的标签
- soup.find():
- find(‘tagName’):等同于soup.tagName
- 属性定位:soup.find(‘tagName’,class_/id/attr=’’)
- soup.find_all(‘tagName’):返回符合要求的所有标签(列表)
- select(‘某种选择器(id/class/标签…选择器)’),返回的是一个列表。
- 层级选择器:
- soup.select(‘.tang > ul >li >a’):>表示的是一个层级,定位到a标签上
- soup.select(‘.tang > ul > a’):空格表示多个层级,也是定位到a标签上
- 获取标签之间的文本数据:
- soup.a.text/string/get_text()
- text/get_text():可以获取一个标签中的所有文本内容
- string:只能获取该标签下面的直系的文本内容
- 获取标签属性值
- soup.a[‘herf’]
7.Problem(requests库中文乱码)
对网页页面源码进行抓取时,出现了中文乱码问题,对网页进行抓包,可以看到:
reqponse header只指定了type,但是没有指定编码(一般现在页面编码都直接在html页面中),我们查看一个正常的网页:
《HTTP权威指南》里第16章国际化里提到,如果HTTP响应中Content-Type字段没有指定charset,则默认页面是’ISO-8859-1’编码,于是在爬取网页源码时出现了乱码现象。
解决方法:
1 | response = requests.get(url=url, headers=headers) |
8. xpath解析(最常用且最便捷高效的一种解析方法)
- xpath解析原理
- 实例化一个etree对象,且需要将被解析的页面源码数据加载到该对象中
- 调用entree对象中的xpath方法结合这xpath表达式实现标签的定位和内容的捕获。
- 如何实例化一个etree对象:from lxml import etree
- 将本地的html文档中的源码数据加载到该对象中etree对象中:etree.parse(filePath)
- 可以将从互联网上获取到源码数据加载到该对象中etree.HTML(page_text)
- xpath(‘xpath表达式’)
- xpath表达式:
- /:表示的是从根节点开始定位,表示的是一个层级。
- //:表示的是多个层级,可以表示从任意位置开始定位。
- 属性定位: //div[@class=’song’] (形式:tag[@attrName=”attrValue])
- 索引定位: //div[@class=’song’]/p[3] (注意:索引是从1开始的。)
- 取文本:
- /text()获取的是标签中直系的文本内容
- //text()获取标签中非直系的文本内容(所有的文本内容)
- 取属性: /@attrName (如 img/@src)
9.分页爬取
对于url处理爬取分页时对每个页面的url进行一个通用的循环,借鉴代码如下:
1 | url = "https://sc.chinaz.com/moban/%s.html" |
注意:%s为字符串格式,%d为整形格式
10. 反爬机制(验证码)
识别验证码图片中的数据,用于模拟登入操作。
识别验证码的操作:
- 人工肉眼识别(不推荐)
- 第三方自动识别(推荐)
使用超级鹰进行验证码的处理。
11.响应状态码
- 1开头的http状态码
表示临时响应并需要请求者继续执行操作的状态代码。- 100 (继续) 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。
- 101 (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。
- 2开头的http状态码
表示请求成功- 200 成功处理了请求,一般情况下都是返回此状态码;
- 201 请求成功并且服务器创建了新的资源。
- 202 接受请求但没创建资源;
- 203 返回另一资源的请求;
- 204 服务器成功处理了请求,但没有返回任何内容;
- 205 服务器成功处理了请求,但没有返回任何内容;
- 206 处理部分请求;
3xx (重定向)
重定向代码,也是常见的代码- 300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
- 301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
- 302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
- 303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
- 304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
- 305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
- 307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
4开头的http状态码
表示请求出错
- 400 服务器不理解请求的语法。
- 401 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
- 403 服务器拒绝请求。
- 404 服务器找不到请求的网页。
- 405 禁用请求中指定的方法。
- 406 无法使用请求的内容特性响应请求的网页。
- 407 此状态代码与 401类似,但指定请求者应当授权使用代理。
- 408 服务器等候请求时发生超时。
- 409 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
- 410 如果请求的资源已永久删除,服务器就会返回此响应。
- 411 服务器不接受不含有效内容长度标头字段的请求。
- 412 服务器未满足请求者在请求中设置的其中一个前提条件。
- 413 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
- 414 请求的 URI(通常为网址)过长,服务器无法处理。
- 415 请求的格式不受请求页面的支持。
- 416 如果页面无法提供请求的范围,则服务器会返回此状态代码。
- 417 服务器未满足”期望”请求标头字段的要求。
5开头状态码并不常见,但是我们应该知道
- 500 (服务器内部错误) 服务器遇到错误,无法完成请求。
- 501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
- 502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
- 503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
- 504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
- 505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。
12.记录客户端相关的状态(cookie)
由于http/https协议特性:无状态
因此在登录之后没有请求到页面数据的原因:
发起的第二次页面数据请求的时候,服务器并不知道该请求是基于登录状态下的请求。
cookie:用来让服务器端记录客户端的相关状态。
- 手动处理:通过抓包工具获取cookie值,将该值封装到headers中。(不推荐)
- 自动处理:
- cookie值的来源是哪里? 模拟登录post请求后,由服务器端创建。
- session会话对象:
- 作用:1. 可以进行请求的发送 2.如果请求过程中产生了cookie,则该cookie会被自动存储/携带在该session对象中。
- 步骤:
- 创建一个session对象:session=requests.Session()
- 使用session对象进行模拟登录post请求的发送(cookie就会被存储在session中)
- session对象对页面数据对应的get请求进行发送(携带了cookie)
13.反爬机制(代理)
代理:破解封IP这样的反爬机制
什么是代理? 代理服务器。
代理的作用?
- 突破自身IP访问限制。
- 隐藏自身真实IP。
代理相关的网站?
- 快代理
- 西祠代理
- www.goubanjia.com
代理IP的类型:
- http:应用到http协议的url中
- https:应用到https协议的url中
代理IP的匿名度:
- 透明:服务器知道该次请求使用了代理,也知道请求对应的真实IP。
- 匿名:服务器知道盖茨请求使用了代理,但不知道真实IP。
- 高匿:不知道使用了代理,也不知道真实IP。
14. 高性能的异步爬虫
目的:在爬虫中使用异步实现高性能的数据爬取操作。
异步爬虫的方式:
- 多线程,多进程(不建议)
- 好处:可以为相关阻塞的操作单独开启线程或者进程,阻塞操作就可以异步执行。
- 弊端:无法无限制的开启多线程或者多进程。
- 线程池,进程池(适当使用)
- 好处:我们可以降低系统对进程或者线程创建和销毁的一个频率,从而很好的降低系统开销
- 弊端:池中线程或者进程的数量是有上限的。
- 单线程+异步协程(推荐):
- event_loop:事件循环,相当于一个无限循环,我们可以把一些函数注册到这个事件循环上,当满足某些条件的时候,函数就会被循环执行。
- coroutine:协程对象,我们可以将协程对象注册到事件循环中,它会被事件循环调用。我们可以使用async关键字来定义一个方法,这个方法在调用是不会被立即执行,而是返回一个协程对象。
- task:任务,它是对协程对象的进一步封装,包含来任务的各个状态。
- future:代表将来执行或还没有执行的任务,实际上和task没有本质区别。
- async:定义一个协程。
- await:用来挂起阻塞方法的执行。
下面粘贴主要爬取函数的代码:
1 | async def get_page(url): |
在异步协程中如果出现同步模块相关代码,那就无法实现异步。当在asyncio中遇到阻塞操作必须进行手动挂起使用await关键字。
15.selenium模块的基本使用
问题:selenium模块和爬虫之间具有怎样的关联?
- 便捷的获取网站动态加载的数据
- 便捷实现模拟登录
什么是selenium模块? - 基于浏览器自动化的一个模块。