1、session与cookie的区别
- session 在服务器端,cookie 在客户端(浏览器)
- cookie用来跟踪会话,而session中保存着会话的状态
- session 默认被存在在服务器的一个文件里(不是内存)
- session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id)
- session 可以放在 文件、数据库、或内存中都可以
- 用户验证这种场合一般会用 session
- cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
- 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie
因此,维持一个会话的核心就是客户端的唯一标识,即 session id
2、爬虫处理cookie和session
带上cookie、session的好处:能够请求到登入后的页面;
带上cookie、session的弊端:一套cookie和session往往和一个用户对应请求太多,请求次数太多,容易被服务器识别为爬虫;
不需要cookie的时候尽量不去使用cookie
但是为了获取登录之后的页面,我们必须发送带有cookies的请求
请求登录之后的网站的思路:
- 实例化session
- 先使用session发送请求,登录对应网站,cookie会自动保存在session实例中
- 再使用session请求登录之后才能访问的网站,session能够自动携带登录成功时保存在其中的cookie,进行请求
3、模拟登入的第一种方式(session)
使用session类
requests提供了一个叫做session类,来实现客户端和服务端的会话保持
使用方法
1 实例化一个session对象
2 让session发送get或者post请求
session = requests.session()
response = session.get(url,headers)
人人网案例
注意:
(1)session实例化post登入后,在session中就已经有了登入后的cookie,可以将其保存在本地的某一个文件中,方便下次使用;
(2)ini文件的格式,注意rr_name是不需要引号的;
[username]
rr_name: 13
[password]
rr_pwd: 31
(3)ini文件的读取,使用configparser模块中的ConfigParser类来读取,先read读取文件,再get获取对应的内容;
(4)模拟登入发送表单数据,可以考虑从element中的form表单得出提交了哪些数据(有些情况下适用),form表单中的action属性是要提交的地址,input中的name属性就是要提交的数据;
人人网登入代码如下:
cfg = ConfigParser()
cfg.read("password.ini")
rr_name = cfg.get("username", "rr_name")
rr_pwd = cfg.get("password", "rr_pwd")
import requests
from configparser import ConfigParser
def account():
cfg = ConfigParser()
cfg.read("password.ini")
rr_name = cfg.get("username", "rr_name")
rr_pwd = cfg.get("password", "rr_pwd")
return rr_name, rr_pwd
class RrSpider(object):
def __init__(self, rr_name, rr_pwd):
self.login_url = "http://www.renren.com/PLogin.do"
self.profile_ulr = "http://www.renren.com/974376660"
self.session = requests.session()
self.headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
}
self.data = {
"email": rr_name,
"password": rr_pwd
}
def login(self):
self.session.post(self.login_url, headers=self.headers, data=self.data)
def rr_parse(self):
res = self.session.get(self.profile_ulr, headers=self.headers)
return res
def save_html(self, res):
with open("人人网.html", "wb") as f:
f.write(res.content)
def run(self):
# 1 使用session登入,保存cookie
self.login()
# 2 使用session请求登入后的url
res = self.rr_parse()
# 3 保存HTML文件
self.save_html(res)
if __name__ == '__main__':
rr_name, rr_pwd = account()
rr_spider = RrSpider(rr_name, rr_pwd)
rr_spider.run()
4、模拟登入的第二种方式
- 在headers字典中添加键值对cookie
- 先在浏览器中登入一次账号
- 在登入后跳转要需要的页面中,在network中找到该页面,从请求头中找到Cookie,将其复制下添加到headers
- 发送获取请求即可 ```python import requests
class RrSpider(object): def init(self): self.profile_ulr = “http://www.renren.com/974376660“ self.headers = { “User-Agent”: “Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36”, “Cookie”: “ano77e” }
def rr_parse(self):
res = requests.get(self.profile_ulr, headers=self.headers)
return res
def save_html(self, res):
with open("人人网.html", "wb") as f:
f.write(res.content)
def run(self):
res = self.rr_parse()
# 3 保存HTML文件
self.save_html(res)
if name == ‘main‘: rr_spider = RrSpider() rr_spider.run()
<a name="bZUkx"></a>
###
<a name="qY6Dl"></a>
### 5、模拟登入的第三种方式
一般用于:
- cookie过期时间很长的网站
- 在cookie过期之前能够拿到所有的数据,
- 配合其他程序一起使用,其他程序专门获取cookie,当前程序专门请求页面
**在requests.get()方法中设置cookies的值,但cookies必须是一个字典**<br />**请求头中Cookie的每一个等号对应一个键值对**,需要将其变成字典中的形式,可以使用**split**来切割<br />cookies = {i.split("=")[0]: i.split("=")[1] for i in cookie.split(";")}
```python
import requests
class RrSpider(object):
def __init__(self, cookie):
self.profile_ulr = "http://www.renren.com/974376660"
self.headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
}
self.cookies = cookie
def rr_parse(self):
res = requests.get(self.profile_ulr, headers=self.headers, cookies=self.cookies)
return res
def save_html(self, res):
with open("人人网.html", "wb") as f:
f.write(res.content)
def run(self):
res = self.rr_parse()
# 3 保存HTML文件
self.save_html(res)
if __name__ == '__main__':
cookie = "anl=123;alksjf=456"
coo = {i.split("=")[0]: i.split("=")[1] for i in cookie.split(";")}
rr_spider = RrSpider(coo)
rr_spider.run()