基于Session和Cookie的模拟登录实战

准备工作

安装好 requests 库, 并掌握基本用法

安装 Selenium 库, 并掌握基本用法

案例介绍

用到的网站: https://login2.scrape.center/

用户名和密码: admin 点击登录

这个网站是基于传统的 MVC 模式开发的,比较适合基于 Session 加 Cookie 的模拟登录

模拟登录

回到登录界面,打开开发者模式(F12), 勾选日志,进入到Network 然后在登录框输入账号密码点击登录

在登录的瞬间,浏览器发起了一个 POST 请求, 目标 URL 是 

https://login2.scrape.center/login

并通过表单提交的方式提交了登录信息,其中包括 username 和 password 两个字段,返回的状态码是 302 , Response 的 location 字段为根页面, 同时 Response Headers 还包含了 set-Cookie 字段,其中设置了 sessionID

由此我们可以想到,要实现模拟登录, 只需要模拟这个 POST 请求就好了

每次发出的请求都是独立互不干扰的, 例如第一次调用 POST 方法模拟登录网站,紧接着调用 get 方法请求主页面,这两个请求是完全独立的, 第一次请求到的 Cookie 不能传递给第二次请求因此常规的顺序调用无法达到模拟登录的效果

import requests
from urllib.parse import urljoin

BASE_URL = 'https://login2.scrape.center/'
LOGIN_URL = urljoin(BASE_URL, '/login')
INDEX_URL = urljoin(BASE_URL, '/page/1')
USERNAME = 'admin'
PASSWORD = 'admin'

response_login = requests.post(LOGIN_URL, data={
    'username': USERNAME,
    'password': PASSWORD
})

response_index = requests.get(INDEX_URL)
print('Response Status', response_index.status_code)
print('Response URL', response_index.url)

Response Status 200
Response URL https://login2.scrape.center/login?next=/page/1

这里我们先定义了 3 个URL ,用户名和密码, 然后调用 requests 库的 post 方法请求了登录页面进行模拟登录, 紧接着调用 get 方法请求网站首页来获取网站内容, 然后把响应内容中的 URL 打印出来。 如果模拟登录成功,那么打印出来的 URL 则是登录后页面的 URL ,如果不成功则是 登录界面的 URL , 这里可以看到是 登录界面的URL,表示模拟登录失败

模拟登录的关键在于两次发送的 Cookie 相同, 我们可以把第一次登录后的 Cookie 保存下来,在第二次请求的时候加上,就可以了

import requests
from urllib.parse import urljoin

BASE_URL = 'https://login2.scrape.center/'
LOGIN_URL = urljoin(BASE_URL, '/login')
INDEX_URL = urljoin(BASE_URL, '/page/1')
USERNAME = 'admin'
PASSWORD = 'admin'

response_login = requests.post(LOGIN_URL, data={
    'username': USERNAME,
    'password': PASSWORD
}, allow_redirects=False)

cookies = response_login.cookies
print('cookies', cookies)

response_index = requests.get(INDEX_URL, cookies=cookies)
print('Response Status', response_index.status_code)
print('Response URL', response_index.url)

Response Status 200
Response URL https://login2.scrape.center/page/1

由于 requests 具有自动处理重定向的能力,所以在模拟登录的过程要加上 allow_redirects 参数并设置为 False , 使 requests 不自动处理重定向。 这里将登录之后服务器返回的响应内容赋值为 reponse_login 变量, 然后调用 response_login 的 cookies 属性就可以获取网站的 Cookie 信息,由于 requests 自动不帮我们解析了响应头中的 Set-Cookie 字段并设置了 Cookie , 因此不需要我们手动再去解析

接着调用, requests 的 get 方法请求网站,与之前不同的是,这里 get 方法增加了一个参数 cookies , 传入的值是第一次模拟登录后获取的 Coolie , 这样第二次登录就携带了第一次模拟登录获取的 Cookie 信息, 之后网站会根据里面的 SessionID 信息找到同一个 Session , 并校验出当前发出请求的用户已处于登录状态, 然后返回正确结果

不过可以看出这种方式相对繁琐,每次都要传递 Cookie ,我们也可以借助 requests 内置的 Session  对象帮我们自动处理 Cookie , 使用 Session 对象之后, requests 会自动保存每次请求后设置的 Cookie , 并在下次请求时带上它

import requests
import time
from urllib.parse import urljoin
from selenium import webdriver
from selenium.webdriver.common.by import By


BASE_URL = 'https://login2.scrape.center/'
LOGIN_URL = urljoin(BASE_URL, '/login')
INDEX_URL = urljoin(BASE_URL, '/page/1')
USERNAME = 'admin'
PASSWORD = 'admin'

browser = webdriver.Chrome()
browser.get(BASE_URL)
browser.find_element(by=By.CSS_SELECTOR, value='input[name="username"]').send_keys(USERNAME)
browser.find_element(by=By.CSS_SELECTOR, value='input[name="password"]').send_keys(PASSWORD)
browser.find_element(by=By.CSS_SELECTOR, value='input[type="submit"]').click()
time.sleep(5)
# 从浏览器中获取 Cookie 信息
cookies = browser.get_cookies()
print('cookies:', cookies)
browser.close()

session = requests.Session()
for cookie in cookies:
    session.cookies.set(cookie['name'], cookie['value'])

response_index = session.get(INDEX_URL)
print('Response Status', response_index.status_code)
print('Response URL', response_index.url)

cookies: [{'domain': 'login2.scrape.center', 'expiry': 1724126750, 'httpOnly': True, 'name': 'sessionid', 'path': '/', 'sameSite': 'Lax', 'secure': False, 'value': 'jltw05oimowc740toy45e2qzpimgy8rt'}]
Response Status 200
Response URL https://login2.scrape.center/page/1

可以看到这里声明了一个 Session 对象,然后每次发出请求的时候直接调用 Session 对象的post 或 get 方法就好了, 使我们无需在关心 Cookie 的处理和传递问题

这种是比较简单的网站,如果遇到登录比较麻烦的网站。例如 带有验证码, 加密参数的网站,直接使用 requests 并不能很好的处理模拟登录,这时我们可以利用 类似 Selenium 模拟浏览器操作, 进而实现模拟登录,然后获取登录后成功后的 Cookie , 在把获取的 Cookie 交由 requests 等爬取

这里我们先使用 Selenium 打开浏览器, 然后访问登录页面, 模拟输入用户信息,并点击登录按钮。 浏览器会提示登录成功,并跳转到主页面

这时,调用 get_cookies 方法便能获取当前浏览器所有 Cookie 信息,这就是模拟登录之后的信息,用它就能访问其他信息了

之后,我们声明了一个 Session 对象,赋值给 session 变量, 然后遍历刚才获取的所有cookie 信息,将每个 Cookie 信息依次设置到 session 的 cookies 属性上, 随后拿这个 session 请求网站首页,就能够获取想要的信息了,而不会跳转到登录页面了

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值