爬虫基础知识(叁)
一、cookie和session:
1、cookie和session的定义:
cookie是网站用来辨别用户身份,进行会话跟踪,存储在本地终端上的数据。
session起始含义是指有始有终的一系列动作和消息。在web中,session主要用来在服务器存储特定用户对象会话所需要的信息。
2、cookie和session产生的原因:
http协议是一个无状态协议,在特定操作的时候,需要保存信息,进而产生了cookie和session。
3、cookie原理:
由服务器来产生,浏览器第一次请求时,服务器发送给客户端进而保存在本地。
浏览器继续访问时,就会在请求头的cookie字段上附带cookie信息,这样服务器就可以识别是谁在访问了。
但是cookie也存在着缺陷:
1)、不安全---本地保存,容易被篡改。
2)、大小受限,本身最大大小为4KB,且每一个网站最多保存20个cookie。
所以cookie虽然在一定程度上解决了‘保持状态’的需求,但还是希望可以克服cookie的缺陷,而session就是为了克服其缺陷产生的。
4、session原理:
session在服务器保存。(解决了cookie的安全问题)
cookie中存在着一个字段,在客户端发送请求时,可以使服务器区识别出这个请求所对应的session。
若禁用了cookie,一般情况下,session也就无法使用了。但是在特殊情况下,可以使用url重写技术来使用session。(url重写技术就是将sessionid拼接到url里。)
session的生命周期:服务器创建开始至有效期结束(一般网站设定的有效期大约是30分钟左右)
5、常见误区:打开网页后将浏览器关闭,这个网页的session并不会失效,因为session是否失效取决于设置的session的生命周期。
6、cookie的字段:
(1)、name:该cookie的名称。一旦创建,该名称便不可更改。
(2)、value:该cookie的值。若值为Unicode字符,需要使用字符编码,若值为二进制数据,则需要使用BASE64编码。
(3)、domain:可以访问该cookie的域名。例如,如果设置为.zhihu.com,则所有以zhihu.com结尾的域名都可以访问该cookie。
(4)、maxage:该cookie失效的时间,以秒为单位,也常和expires一起使用,通过它可以计算出其有效时间。如果其为正数,则该cookie会在maxage秒后失效。如果为负数,则关闭浏览器时该cookie即失效,浏览器也不会以任何形式保存该cookie。
(5)、path:该cookie的使用路径。若设为/path/,则只有路径为/path/的页面可以访问该cookie。若设为/,则本域名下的所有页面均可访问该cookie。
(6)、size:该cookie的大小。
(7)、HTTP:该cookie的HTTPonly属性。若此属性为true,则只有在HTTP头中会带由此cookie的信息,而不能通过document.cookie来访问此cookie。
(8)、secure:该cookie是否仅被使用安全协议传输。安全协议有HTTPS和SSL等,在网络上传输数据之前先将数据进行加密。默认为false。
7、会话cookie和持久cookie:
会话cookie:maxage为负数,关闭浏览器时cookie即失效。是保存在内存中的cookie。
持久cookie:maxage为正数,cookie会在maxage秒之后失效。是保存在硬盘上的cookie。
持久化:将内存中的数据保存到硬盘上。其实就是将数据保存到文件或数据库中。
内存主要的作用就是由于速度快,启动应用软件或程序的时候,就会分配一定的内存空间作为该程序运行内存。内存一旦断点,就会被清空。
序列化:将对象保存到硬盘中。
8、用requests登录页面:
将登录后的cookie封装到请求头字典中就可以了。
二、代理:
1、代理的作用:
(1)、突破自身IP访问限制,访问一些平时不能访问的站点。
(2)、访问一些单位或团体内部资源,比如使用教育网内地址段免费代理服务器,就可以用于对教育网开放的各类FTP下载上传,以及各类资料查询共享等服务。
(3)、提高访问速度,通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息传给用户,以提高访问速度。
(4)、隐藏真实IP,上网者也可以通过这种方式隐藏自己的IP,免受攻击。对于爬虫来说,用代理就是为了隐藏自身IP,防止自身的被封锁。
2、代理的分类:
(1)、根据协议区分:
根据代理的协议,代理可以分为如下类别:
FTP代理服务器:主要用于访问FTP服务器,一般有上传、下载以及缓存功能,端口一般为21、2121等。
HTTP代理服务器:主要用于访问网页,一般有内容过滤和缓存功能,端口一般为80、8080、3128等。
SSL/TLS代理:主要用于访问加密网站,一般有SSL或TLS加密功能(最高支持128位加密强度),端口一般为443。
RTSP代理:主要用于访问Real流媒体服务器,一般有缓存功能,端口一般为554.
Telnet代理:主要用于Telnet远程控制(黑客入侵计算机时常用于隐藏身份),端口一般为23。
POP3/SMTP代理:主要用于POP3/SMTP方式收发邮件,一般有缓存功能,端口一般为110、25。
SOCKS代理:只是单纯传递数据包,不关心具体协议和用法,所以速度快很多,一般有缓存功能,端口一般为1080。SOCKS代理协议又分为SOCKS4和SOCKS5,前者只支持TCP,而后者支持TCP和UDP,还支持各种身份验证机制、服务器端域名解析等。简单来说,SOCKS4能做到的SOCKS5都可以做到,但SOCKS5能做到的SOCKS4不一定能做到。
(2)、根据匿名程度区分:
根据代理的匿名程度,代理可以分为如下类别:
高度匿名代理:会将数据包原封不动地转发,在服务器看来就好像真的是一个普通的客户端在访问,而记录的IP是代理服务器的IP。
普通匿名代理:会在数据包上做一些改动,服务端上有可能会发现这是个代理服务器,也有一定几率追查到客户端的真实IP,代理服务器通常会加入的HTTP头有HTTP_VIA和HTTP_X_FORWARDED FOR。
透明代理:不但改动了数据包,还会告诉服务器客户端的真实IP,这种代理除了能用缓存技术提高浏览速度、能用内容过滤提高安全性之外,并无其他显著作用,最常见的例子是内网中的硬件防火墙。
间谍代理:指组织或个人创建的用于记录用户传输的数据,然后进行研究、监控等目的的代理服务器。
3、代理的设置:
proxies={
'http':'http://114.99.11.179:9999',#http和https都可以用http作为key
}
response=requests.get/post(proxies=proxies)
三、正则表达式:
(一)、元字符:
1、匹配边界:
^ ------ 匹配字符串的开头
$ ------ 匹配字符串的结尾
2、表示重复次数:
? ------ 查询0次或1次
* ------ 查询0次或多次
+ ------ 至少查询1次
{n,} ------ 至少查询n次
{n,m} ------ 至少查询n次,最多查询m次
{n} ------ 查询n次
3、匹配文字:
[] ------ 匹配单字符
[abc] ------ 匹配a或b或c中的其中一个
\b ------ 匹配单词的边界
\d ------ 表示数字
\w ------ 数字、字母、下划线
\s ------ 空白字符(空格、换行、制表)
. ------ 除换行符以外的任意字符
/ ------ 匹配二者中的其中一个
(二)、re模块:
1、re模块使用步骤:
#(1)导包
import re
#(2)将正则表达式编译成一个pattern对象
pattern = re.compile(
r'正则表达式',
'匹配模式',#可以不指定,默认就按正则表达式本来的含义进行匹配。
)
#正则匹配模式:
#re.S----.可以匹配换行符
#re.I---忽略大小写
#(3)pattern对象的方法(match,search、findall)匹配字符串。
match对象的属性:
match.group()等价于match.group(0)----返回匹配结果内容
match.span()--匹配范围
match.start()
match.end()
2、pattern对象的方法:
(1)match方法:默认从头开始匹配,只匹配一次,返回一个match对象
Match对象 = pattern.match(
string,#要匹配的目标字符串
start,#要匹配目标字符串的起始位置(可选)
end#结束位置(可选)
)
(2)search方法:默认全局匹配,只匹配一次,返回一个match对象
Match对象 = pattern.search(
string,#要匹配的目标字符串
start,#要匹配目标字符串的起始位置(可选)
end#结束位置(可选)
)
(3)findall方法:默认全局匹配,匹配多次,返回一个list对象
list对象= pattern.findall(
string,#要匹配的目标字符串
start,#要匹配目标字符串的起始位置(可选)
end#结束位置(可选)
)
findall配合分组,它只会取分组中的内容以此放入元组中,list对象中存储的就是所有的元组。
(4)、finditer方法:全局匹配,匹配多次,返回一个迭代器,迭代器里面存储的是match对象
迭代器=pattern.finditer(
string,#要匹配的目标字符串
start,#要匹配目标字符串的起始位置(可选)
end#结束位置(可选)
)
(5)、split:按正则方法表示内容进行分割字符串,返回分割后的list
list=pattern.split(
string,#要匹配的目标字符串
maxsplit#指定最大分割次数,默认全局分割,可选
)
(6)、sub:按照正则表示的内容替换字符串
string=pattern.sub(
repl,#替换后的字符串
string,#要替换掉的字符串
count#替换次数,默认全部替换,可选
)
a、repl为字符串时
例:
import re
p = re.compile(r'(\w+) (\w+)')
s = 'hello 123,hello 456'
#提前用p去匹配目标串,找到能匹配出来的内容,就是替换找出来的这个内容的。
print(p.sub(r'hello world',s))#使用‘hello world'替换'hello 123'和'hello 456'
print(p.sub(r'\2 \1',s))#引用分组
b、当repl是一个函数时,这个函数是有要求的:
首先,函数必须带一个参数,这个参数其实就是提前用p去匹配目标字符串后得到的match对象;其次,这个函数必须有返回值,返回值是一个字符串,这个字符串将作为替换后的内容。
3、分组:
分组在正则表达式中就是用()来表示的,一个括号就是一个分组。分组的作用主要有以下两点:
1)、筛选特定内容。
2)、引用分组。
4、贪婪模式与非贪婪模式:
(1)、贪婪模式是用"*"来控制的,python默认的就是贪婪模式,所以默认所有的数量控制符都是取所能匹配的最大值。
(2)、非贪婪模式是用"?"来控制的,?放在数量控制符后面,表示数量控制符匹配最小的次数。
5、.*?大法