正常发起请求(进行了模拟登入),如果需要接着发起第二次请求(没有进行模拟登入),这第二次请求不会保留上次请求模拟登入的数据,也就是说第二次请求是没有进行登入的,如果需要基于第一次请求的登入状态,这里就需要使用到Cookie。Cookie是用来让服务端记录客户端的相关状态。session可以进行请求的发送,如果请求产生了Cookie,则该Cookie会被自动存储在该session中
需要保持登入状态发起多次请求流程流程:
1.创建session对象
2.使用session对象进行模拟登入POST请求的发生(cookie会自动存储在session)
3.使用session对象对个人主页对应的GET请求进行发送(携带了Cookie)
# 登入的URL
login_url = ''
# 登入带入的参数,如上面所说的email为账户,pwd为密码,code为验证码
data = {
'email': '',
'pwd': '',
'code': ''
}
# 抓取登入后的页面,使用session进行POST请求的发送
# 第一次请求,session中获取了Cookie
login_page_text = session.post(url=login_url, headers=headers, data=data)
# 爬取当前账户个人主页对应的页面数据(登入后的)
# 第二次请求登入后的页面,session包含了cookie
detail_url = ''
detail_page_text = session.get(url=login_url, headers=headers)
如果使用request.post发起两次请求,在第二次请求是未登入的状态
这里利用selenium模块实现模拟登入,简单方便易实现,selenium具体如何使用请看https://blog.csdn.net/weixin_46287157/article/details/129149265
以古诗文网为例(手动输入验证码)
首先进入古诗文网的登入界面,URL为https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx
利用selenium模块实现模拟登入,这里实现登入之后可以对登入后的页面进行操作(比如获取数据、点击、输入等操作)
首先对登入链接发起请求
接着定位email,密码,验证码,登入位子并输入内容
登入之后可以对登入后的页面进行操作
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
url = 'https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx'
# 初始化
browser = webdriver.Chrome()
# 发出请求
browser.get(url)
# 输出当前url
print(browser.current_url)
'''
https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx
'''
time.sleep(2)
# 定位email位子并输入
email_info = browser.find_element(By.ID, 'email')
email_info.send_keys('...')
# 定位密码位子并输入
pwd_info = browser.find_element(By.ID, 'pwd')
pwd_info.send_keys('...')
time.sleep(2)
# 手动输入验证码信息
code = browser.find_element(By.ID, 'code')
code.send_keys(input())
time.sleep(2)
# 定位登入按钮点击登入
button = browser.find_element(By.ID, 'denglu')
button.click()
time.sleep(2)
# 输出现在的url,现在的url已经是登入之后的url,这里可以对登入后的页面进行操作
print(browser.current_url)
'''
https://so.gushiwen.cn/user/collect.aspx
'''
# 对登入后的页面进行操作,比如下面点击作者栏目
button = browser.find_element(By.XPATH, '/html/body/div[1]/div/div[2]/div[1]/a[4]')
button.click()
time.sleep(2)
在这基础上,可以结合requests中的session发起请求,在上面代码下方添加如下代码,可以将session保存browser登入后的cookies,发起再次请求,此时发出的请求是包含登入信息的,这样可以对登入后的页面发起请求
import requests
...
...
...
session = requests.session()
cookies = browser.get_cookies()
# 保存登入状态的cookies
for cookie in cookies:
session.cookies.set(cookie['name'], cookie['value'])
page = session.get(browser.current_url)
page.encoding = "utf-8"
html = page.text
# 保存源码
with open('./a.html', 'w', encoding='utf-8') as fp:
fp.write(page.text)
上面是手动的方式,如果要使用自动的方式,可以使用第三方工具进行验证码处理,比如利用下面的超级鹰
超级鹰的基本用法:www.chaojiying.com/about.html
以登入某网站为例,为保证请求页面的验证码和登入的一样,不能做两次请求,可以借助于截图的方式,将页面进行截图,然后截取验证码部分,利用第三方工具进行处理,获取信息或操作后进行登入操作
流程如下:
截图裁剪
方式
from PIL import Image
# 请求页面全局截图且保存
bro.save_screenshot('a.png')
# 确定验证码坐标(裁剪区域)
code_img_ele = bro.find_element('') # 图片标签
location = code_img_ele.location # 验证码左上角坐标 x y
size = code_img_ele.size # 宽度
# 左上角和右下角位子
rangle = (int(location['x']), int(location['y']), int(location['x']+size['width']), int(location['y']+size['height']))
# 图片裁剪
i = Image.Open('./a.png')
frame = i.crop(rangle)
frame.save('code.png')