模拟登录
模拟登录:爬取基于某些用户的用户信息。
cookie
cookie:用来让服务器端记录客户端的相关状态。
-
手动处理:通过抓包工具获取cookie值,将该值封装到headers中(不建议)
-
自动处理:
-
cookie值的来源在哪里?
- 模拟登录post请求后,由服务器端创建
-
session会话对象:
-
作用:可以进行请求的发送
如果请求过程中产生了cookie,则该cookie会被自动存储/携带在该session对象中
-
-
创建一个session对象:session=requests.Session()
-
使用session对象进行模拟登录post请求的发送(cookie就会被存储在session对象中)
-
session对象对个人主页对应的get请求进行发送(携带了cookie)
-
实战
需求1:对古诗文网进行模拟登录
流程:
-
点击登录按钮之后会发起一个post请求
-
post请求中会携带登录之前录入的相关登录信息(用户名,密码,验证码…)
-
验证码:每次请求都会变化
代码
编码流程:
- 验证码的识别,获取验证码图片的文字数据
- 对post请求进行发送(处理请求参数)
- 对响应数据进行持久化存储
以下是代码的实现,其中验证码识别代码(VerificationCode),点这里
import requests
from lxml import etree
from VerificationCode import VerificationCode
def getCodeText(imgPath):
"""
封装识别验证码图片的函数
:param imgPath:验证码图片路径
:return: 返回识别的验证码文本
"""
a = VerificationCode(imgPath)
result = a.image_str()
return result
if __name__ == '__main__':
# UA伪装,相关的头信息封装在字典结构中
headers = {
"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36'
}
# 创建一个session对象,该对象会自动将请求中的cookie进行存储和携带
session = requests.session()
# 对验证码图片进行捕获和识别
url = 'https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx'
response = session.get(url=url,headers=headers)
response.encoding = 'utf-8' # 将编码设置为‘utf-8',不然会出现乱码
page_text = response.text
tree = etree.HTML(page_text)
# 保存html
with open('./result/gushiwen.html','w',encoding='utf-8') as fp:
fp.write(page_text)
# 判断是否为验证码的页面,如果是,进行验证码识别、模拟登录
title = tree.xpath('//*[@id="aspnetForm"]/div[4]/div[4]/span/text()')
print(title)
if '验证码' in title:
print("登录存在验证码,需要进行验证码识别!!")
code_img_src = tree.xpath('//*[@id="imgCode"]/@src')[0]
code_img_url = 'https://so.gushiwen.cn/' + code_img_src
print(code_img_url)
code_img_data = session.get(url=code_img_url, headers=headers).content
with open('./result/code_gsw.jpg','wb') as fp:
fp.write(code_img_data)
print("图片保存成功!!")
# 调用OCR图片识别代码进行验证码图片数据识别,识别率不太高
print("图片识别中....")
code_text = getCodeText('./result/code_gsw.jpg')
if code_text == '' or code_text == None:
print("未识别成功!!!")
else:
print("识别结果为:", code_text)
# post请求的发送(模拟登录)
login_url = 'https://so.gushiwen.cn/user/login.aspx?from=http%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx'
data = {
'__VIEWSTATE': 'J4lKFTZmKFCNCqJLPTrKQ/7J32z28jdpXU8l41kXfvKh60kKv5eXR9PdfNwW06f2mPSDL61OATQFdEPf+8JbjiVsqiHnrBSw7mA38Rn+n+r73+7pYhtlKr7i6UU=',
'__VIEWSTATEGENERATOR': 'C93BE1AE',
'from': 'http://so.gushiwen.cn/user/collect.aspx',
'email': '用户名',
'pwd': '密码',
'code': code_text,
'denglu': '登录'
}
response = session.post(url=login_url, headers=headers, data=data)
# 判断是否登录成功
if response.status_code == 200:
print("模拟登录成功!!!")
else:
print("模拟登录失败!!!")
运行代码后,结果如下:
需求2:爬取古诗文网当前用户的我的背诵页数据
- http/https协议特性:无状态
- 没有请求到对应页面数据的原因:发起的第二次基于个人主页页面请求的时候,服务器端并不知道该次请求是基于登录状态下的请求
代码
import requests
from lxml import etree
from VerificationCode import VerificationCode
def getCodeText(imgPath):
"""
封装识别验证码图片的函数
:param imgPath:验证码图片路径
:return: 返回识别的验证码文本
"""
a = VerificationCode(imgPath)
result = a.image_str()
return result
if __name__ == '__main__':
# UA伪装,相关的头信息封装在字典结构中
headers = {
"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36'
}
# 创建一个session对象,该对象会自动将请求中的cookie进行存储和携带
session = requests.session()
# 对验证码图片进行捕获和识别
url = 'https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx'
response = session.get(url=url, headers=headers)
response.encoding = 'utf-8' # 将编码设置为‘utf-8',不然会出现乱码
page_text = response.text
tree = etree.HTML(page_text)
# 保存html
with open('./result/gushiwen.html', 'w', encoding='utf-8') as fp:
fp.write(page_text)
# 判断是否为验证码的页面,如果是,进行验证码识别、模拟登录
title = tree.xpath('//*[@id="aspnetForm"]/div[4]/div[4]/span/text()')
if '验证码' in title:
print("登录存在验证码,需要进行验证码识别!!")
code_img_src = tree.xpath('//*[@id="imgCode"]/@src')[0]
code_img_url = 'https://so.gushiwen.cn/' + code_img_src
print("验证码的url地址: ",code_img_url)
code_img_data = session.get(url=code_img_url, headers=headers).content
with open('./result/code_gsw.jpg', 'wb') as fp:
fp.write(code_img_data)
print("图片保存成功!!")
# 调用OCR图片识别代码进行验证码图片数据识别,识别率不太高
print("图片识别中....")
code_text = getCodeText('./result/code_gsw.jpg')
if code_text == '' or code_text == None:
print("未识别成功!!!")
else:
print("识别结果为:", code_text)
# post请求的发送(模拟登录)
login_url = 'https://so.gushiwen.cn/user/login.aspx?from=http%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx'
data = {
'__VIEWSTATE': 'J4lKFTZmKFCNCqJLPTrKQ/7J32z28jdpXU8l41kXfvKh60kKv5eXR9PdfNwW06f2mPSDL61OATQFdEPf+8JbjiVsqiHnrBSw7mA38Rn+n+r73+7pYhtlKr7i6UU=',
'__VIEWSTATEGENERATOR': 'C93BE1AE',
'from': 'http://so.gushiwen.cn/user/collect.aspx',
'email': '用户名称',
'pwd': '密码',
'code': code_text,
'denglu': '登录'
}
# 使用session进行post请求的发送
response = session.post(url=login_url, headers=headers, data=data)
# 判断是否登录成功
if response.status_code == 200:
print("模拟登录成功!!!")
else:
print("模拟登录失败!!!")
login_page_text = response.text
# 持久化存储
with open('./result/gushiwen.html', 'w', encoding='utf-8') as fp:
fp.write(login_page_text)
# 爬取当前用户的个人主页对应的页面数据
detail_url = 'https://so.gushiwen.cn/user/collectbei.aspx?sort=t'
# 使用携带cookie的session进行get请求的发送
detail_page_text = session.get(url=detail_url, headers=headers).text
with open('./result/user_page.html', 'w', encoding='utf-8') as fp:
fp.write(detail_page_text)
运行结果如下:
代理
- 代理相关的网站:
具体实战代码地址,点这里
如果本文对你有帮助,记得“点赞、收藏”哦~