cookie 和 session
产生的原因:http协议无状态,访问之间不能通讯
cookie
-
指某些网站为了辨别用户身份、进行会话跟踪而存储在用户本地终端上的数据。
-
做爬虫时,使用账号登录,封装cookie信息到headers字典
-
cookie和session一般配合使用
-
cookie被禁用时:
1.提示他必须开启。
2.使用url重传。—就是将sessionid附带url后面传递给服务器。 -
会话cookie和持久cookie
-
会话cookie就是指存储在浏览器内存中的cookie,当浏览器关闭,会话 cookie失效。
持久cookie是保存在硬盘上的cookie。
这两中cookie的分类标准主要是通过maxAge或者expires这个cookie的字段来 定义的----->为负数,则为会话cookie。
session
- cookie中包含session_id
- 没有session信息会创建
- 当session的失效时间到达时失效,一般是30分钟。
- 在session有效期内,继续访问该页面,服务器就会直接查找到这个session返回给客户端。
爬虫实现登录
- 账号登录后封装cookie信息到headers头
- 使用requests的session对象,提交账号密码登录
代理
原理
用户通过提交数据到代理服务器,代理服务器转发给业务服务器,这时业务服务器无法获取用户的真实ip地址,从而达到保护的作用。
作用
1、突破自身IP 访问限制, 访问一些平时不能访问的站点。
2、访问一些单位或团体内部资源
3、提高访问速度(代理作为缓存)
4、隐藏真实IP
分类
按匿名程度:
高度匿名代理
普通匿名代理:能查到
透明代理
间谍代理
按协议类型:
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 不一定能做到。
代理用法
代理ip:http://ip:port
在requests模块中如何设置代理?
1.创建一个代理字典
proxies = {
'http':代理ip,
‘https’:'https://ip:port'
}
2.用get或者post方法请求时候,增加proxies这个参数就可以了。
requests.get(proxies=proxies)
数据分类
一、结构化数据
实例:关系型数据库中存在表中的数据。
特点:数据以行为单位,一行数据表示一个实体的信息,每一行的数据的属性是相同的。
二、半结构型数据
实例:XML、HTML、JSON
特点:是以树或者图的结构来存储的。不符合关系型数据库或其他数据表的形式关联起来的数据模型结构,但包含相关标记,用来分隔语义元素以及对记录和字段进行分层。自描述特性
三、非结构性数据
实例:各种文档,图片,视频或者音频都属于非结构化数据。
特点:就是没有固定的结构。对于这类数据,我们一般直接整体进行存储,而且一般存储为二进制形式。
json数据
(二)json数据
json(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式。他基于ECMAScript(w3c制定的JS规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简介和清晰的层次结构使得JSON成为理想的数据交换语言。
特点:易于阅读、易于机器生成、有效提升网络速度。
JSON语法规则:在JS语言中,一切都是对象。因此,任何支持的类型都可以通过json来表示。例如字符串、数字,对象,数组。
Js中对象和数组是比较特殊并且常用的两种类型:
1.对象表示为键值对{name:’zhangsan’,age:’7’}
2、数据有逗号分隔[1,2,3,4,5]
3.花括号保存对象
4.方括号保存数组。
json键值对是用来保存js对象的一种方式,和js对象的写法页大同小异,比如:
{“firstName”:“Json”,“Class”:“aid1111”}等价于下面这条js语句:{firstName:“Json”,Class:“aid1111”}。
很多人搞不清楚json和js对象的关系,甚至谁是谁都不清楚。其实可以这么理解:【JSON是JS对象的字符串表达式,他使用文本形式表示一个JS对象的信息,本质是一个字符串。】
如var obj = {a:“hello”,b:“World”}这是一个js对象。注意,键名也是可以用引号包裹的var json = ’ {“a”:“hello”,“b”:“World”}'这是一个json字符串,本质上是一个字符串。
JSON作为数据包格式传输的时候具有更高的效率,这是因为JSON不想xml那样具有严格的闭合标签,这就让有效数据量与总数据包比大大提升,从而减少同等数据流量的情况下,网络的传输的压力大大减低。
正则
元字符
(1)匹配边界
^ -----行首
$ ----- 行尾
(2)重复次数
? ----- 0或1
* ----- 》0
+ ----- 》1
{n,}----- 》n
{n,m}----- 》n,《m
{n} ----- 重复n次
(3)各种字符的表示
[] ---表示单字符
[abc] ---匹配a、b、c其中的一个。
[a-z]
[0-9a-zA-Z_]
\d 数字
\w 数字字母下划线
\s 空白字符(空格,制表、换行)
\b 单词的开始和结束
. 匹配任意字符,除换行符以外。
re模块的使用步骤
(1)pattern = re.compile('正则表达式')将正则表达式编译成一个pattern对象。
(2)pattern提供一系列的方法,来对文本进行匹配,一般返回一个match对象。
(3)通过使用match对象提供的方法来获取匹配结果。
match对象有以下方法:
match.group(0)----获取匹配结果
match.group()----获取匹配结果
match.span()----获取匹配范围
match.start()---匹配开始位置
match.end()---匹配结束位置
3.pattern对象的方法。
(1)match方法:默认从头开始匹配,只匹配一次,返回一个match对象。
pattern.macth(
'要匹配的字符串',必须指定,
start,匹配的开始位置
end,匹配的结束位置。
)---->match对象
(2)serach方法:从任意位置匹配,只匹配一次,返回一个match对象。
pattern.search(
'要匹配的字符串',必须指定,
start,匹配的开始位置
end,匹配的结束位置。
)---->match对象
(3)findall:全文匹配,将匹配到的结果放到一个list中返回给我们,多次匹配。
pattern.findall(
'要匹配的字符串',必须指定,
start,匹配的开始位置
end,匹配的结束位置。
)---->list
(4)finditer:全文匹配,多次匹配,返回一个包含匹配结果的迭代器。
pattern.finditer(
'要匹配的字符串',必须指定,
start,匹配的开始位置
end,匹配的结束位置。
)---->iteror
(5)split:切分字符串,按照整个表达式所指定的内容切分。
str.split(',')
pattern.split(
'要切分的字符串',
切分的次数。不指定就是默认,默认全部切割
)---->list
(6)sub:用指定的字符串,替换正则表达式匹配的到目标字符串的内容。
pattern.sub(
repl,替换成什么。
content,替换什么。
count,可以不指定,替换的次数。默认替换所有。
)
repl可以是字符串,也可以是函数。
当repl是函数的时候,这个函数有一下要求:
1,函数必须带一个参数,这个参数是一个match对象。
def func(match):
'''
对match对象的操作。
'''
print(macth.group())
2.当在sub方法里面传入这个参数时,这个match对象其实就是用正则匹配到的每一个match对象。
3.这个函数是有返回值的,返回值必须是一个字符串,将来是用这个字符串进行替换目标字符串的。
正则表达式中的分组
分组时通过()来表示的,一个括号就表示一个分组。
分组的作用:
(1)筛选特定内容。
取分组内容可以通过match对象的group方法来去。
group(1)表示取正则表达式中第一个括号的内容,依次类推。
import re
content = '{name:"zhangsan",age:"10",hobby:["basktball","football","read"]}'
pattern = re.compile(r'{name:"(\w+)",age:"(\d+)".+')
match = pattern.search(content)
print(match.group(1))#zhangsan
print(match.group(2))#10
(2)可以在同一个表达式的后面引用前面的分组表达式。
s = "<html><h1>正则表达式</h1></html>"
import re
s = "<html><h1>正则表达式</h1></html>"
pattern = re.compile(r'<(html)><(h1)>(.*)</\2></\1>')
match = pattern.search(s)
print(match.group(3)))#正则表达式
4.正则表达式的模式
pattern = re.compile(
'正则表达式',
‘正则表达式的模式’
)
正则表达式的模式有以下几种:
re.I 使匹配对大小写不敏感
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符
5.贪婪和非贪婪模式。
(1)贪婪是用*控制的
(2)非贪婪是用?来控制。
(3)*和?都是作用表示重复次数的元字符的。
(4)正则默认是贪婪模式,所以数量控制符默认是取最大值,也是贪婪。
(5)在表示重复的元字符后面加一个?,此时就是非贪婪,取这个重复元字符的最小值。
6.通用匹配正则表达式
.*? 配合re.S
import re
content = '{name:"zhangsan",age:"10",hobby:["basktball","football","read"]}'
pattern = re.compile(r'.*?"(.*?)".*?"(.*?)".*?')
match = pattern.search(content)
print(match)
print(match.group(1))
print(match.group(2))
正则实例
(1)非负整数
rl = r'\d+'
(2)匹配正整数
rl = r'[\d^0]+'
(3)非正整数
rl = r'-?[\d^0]+'
(4)非负浮点数
rl = '\d+\.\d+'
(5)整数
rl='-?\d+'
(6)长度为8-10的用户密码(以字母开头、数字、下划线)
rl='^[a-zA-Z]\w{7,9}'
(7)qq邮箱验证
rl = '\d{5,20}@qq.com'
(8)匹配出wahaha,banana,qqxing内容
rl='(wohaha)+?.*?(banana)+?.*?(qqxing)+?'
(9)11位的电话号码
rl='1[3578]\d{9}'
(10)匹配年月日日期 格式2018-12-6
rl=r'\d{1,4}-[1]?\d-[1-3]?\d'