古诗文网模拟用户登录
网址:https://www.gushiwen.cn/
前言:
加油!我们都是追梦人!
本篇文章将会基于 repuests 中的Session 会话模式实现模拟用户登录,会使用 ddddocr 进行验证码的识别,同时也会使用 xpath 进行数据解析。
-
Session:会话模式,简单的说,对于登录界面来说,通常是通过 Cookie 的值来实现登录后页面间的相互跳转,在跳转的时候,上个页面会将携带登录信息的Cookie 作为请求头发送给下个页面,以此来维持登录状态,使用 Session 进行访问,会将你访问页面返回的 Cookie 自动添加到你的请求头,进行下次访问。
-
ddddocr: 原理是结合深度学习的 CNN 和 RNN:
- 图像处理:优化输入图像。
- CNN:提取文字特征。
- RNN:识别文字顺序。
- 输出:转换为文本。
-
xpath:使用路径表达式来遍历和选择XML文档中的节点,可以根据元素的名称、属性值、位置等信息来精确地定位到所需的数据。例如:
'//img[@id="imgCode"]/@src'
本人对深度学习没有研究,上述 ddddocr 原理 基于资料寻找。
第一步:环境配置
# 导入需要使用的库
import requests
import ddddocr
from lxml import etree
这三个库都需要安装,在 cmd 中输入下面代码:
pip install requests lxml ddddocr -i https://mirrors.aliyun.com/pypi/simple/
需要注意的是,ddddocr 如果安装错误,可以在 cmd 中输入下面代码,解决百分之80的问题:
pip install requests lxml ddddocr opencv-python -i https://mirrors.aliyun.com/pypi/simple/
如果还是没有安装成功,可以留言或私信告诉我,本人乐意为你效劳^_^
需求
通过模拟登录获得用户的收藏信息和绑定手机号
第二步:实例化对象
我们需要实例化 Session 对象,和 ddddocr 对象
# 实例化对象
session = requests.Session()
ocr = ddddocr.DdddOcr(show_ad=False) # 由于 ddddocr 默认再使用的时候会弹出广告, show_ad=False 参数可以将广告关闭
第三步:思路
我们首先打开古诗文网的网页,跳转到登录页面
点击后会进入登录页面
我们打开开发者工具,输入验证码点击登录,找到登录的请求地址
我们就可以根据上面的信息构建 url 和请求参数
# 构建请求信息
url = "https://so.gushiwen.cn/user/login.aspx?from=http%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx"
params = {
'from': 'http://so.gushiwen.cn/user/collect.aspx',
'email': '用户账号',
'pwd': '用户密码',
'code': "验证码",
'denglu': '登录'
}
# 上面的请求参数,其中 用户账号 用户密码 验证码 需要我们自己来填写,其他的都是不会变的
但是现在有一个问题,就是验证码我们知道是多少,但是程序不知道呀,所以,我们要先访问网页,将验证码的图片地址获取到,并通过 ddddocr 进行识别,验证码识别后,再通过访问网页进行登录,通过数据解析获得数据。
第四步:获取验证码地址
我们先查看网页源码,找到验证码图片的地址在那个标签下。
根据上图可以得到的信息是,验证码的url地址是一个 id 属性是"imgCode" 的 img 标签的src 属性值。
根据这一信息,我们开始访问网页将验证码的图片地址获取到。
# 登录页面的 url 地址
base_url = "https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx"
# 使用 session 会话模式进行访问
response = session.get(base_url).text
# 实例化 etree 对象
tree = etree.HTML(response) # 由于我们使用的是网络请求得到的 HTML 不需要再本地读取,所以直接使用 etree.HTML
# 调用实例化对象的xpath方法进行解析,这个方法会根据定位返回列表
# '//img[@id="imgCode"]/@src' 这个表达式的意思是;定位 id = "imgCode" 的 img 标签的src属性的值
img_url = tree.xpath('//img[@id="imgCode"]/@src')[0]
# img 标签的src属性值只有一个,列表中只有一个值,所以我们取列表的第一个值
# 最后,由于获得的地址不是完整地址,所以需要将域名加上
img_url = "https://so.gushiwen.cn" + "/RandCode.ashx"
这样,我们就获得了验证码的地址。
第五步:通过ddddocr进行验证码识别
上面,我们实例化了 ddddocr 对象,调用 classification() 方法可以进行验证码识别,这个方法传入一个如PNG、JPEG等编码的二进制数据或者是图像文件的路径字符串。
我们需要将验证码图片先获取到,然后传进去进行破解。
img_url = "https://so.gushiwen.cn" + "/RandCode.ashx"
code_response = session.get(url=img_url).content
with open("code_img.jpg", "wb") as f:
f.write(code_response)
result = ocr.classification(code_response)
print(result)
我们可以将验证码保存在本地,运行一下,看看结果是否是对的
可以看到,输出的结果和验证码的数字是一致的,验证码识别成功后,我们就着手登录了。
第六步:模拟登录
# 上面找到的登录url
login_url = "https://so.gushiwen.cn/user/login.aspx?from=http%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx"
# 构建请求头
params = {
'from': 'http://so.gushiwen.cn/user/collect.aspx',
'email': '1783****9814',
'pwd': 'X*******60',
'code': result,
'denglu': '登录'
}
# 访问url进行登录
login_response = session.post(url=login_url, data=params)
# 如果不是 “我的” 页面,可以在请求一下下面的
# users_url = "https://so.gushiwen.cn/user/collect.aspx"
# login_response = session.post(url=login_url, data=params)
你们可以输出一下这个相应,这个是登录成功 “我的” 的界面,如果不是,可以在访问一遍 “我的” 的地址。
这样,我们就获得了登录后的 “我的” 页面的相应,接下来使用 xpath 解析到想要的数据就可以了
第七步:解析数据
# 实例化 etree 对象
tree = etree.HTML(login_response.text)
binding_info = tree.xpath('//div[@class="shisoncont"]/div[5]/a/text() | //div[@class="shisoncont"]/div[5]/span/text()')
这个表达式的意思是寻找 class 属性是 “shisoncont” 的div标签下的第5个div 标签下的a标签的文本 或者是 class 属性是 “shisoncont” 的div标签下的第5个div 标签下的 span 标签的文本,如果这两个都找到,就返回两个
而这个标签所对应的数据就是手机号的绑定情况
接下来就是进行格式化打印
title, state = binding_info
print("用户注册信息:")
print(f"{title}:{state}")
然后我们需要找到用户的收藏信息。
定位这个标签。
data_list = tree.xpath('//div[@class="sons"]/div')
定位到这个标签后,会返回7个 etree 对象再列表中。
我们循环这个列表,依次取出用户的所有收藏信息。
print("用户收藏信息:")
for data in data_list:
author = data.xpath('a/text()')[-1]
poetry = data.xpath('a/span/text()')[-1]
print(f"{author}{poetry}")
这样,我们就完成了模拟登录的所有流程。
完整代码
# code = "utf-8"
# 导入需要使用的库
import requests
import ddddocr
from lxml import etree
# 实例化对象
session = requests.Session()
ocr = ddddocr.DdddOcr(show_ad=False) # 由于 ddddocr 默认再使用的时候会弹出广告, show_ad=False 参数可以将广告关闭
# 登录页面url
base_url = "https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx"
response = session.get(base_url).text
# 实例化 etree 对象
tree = etree.HTML(response)
# 解析数据
img_url = tree.xpath('//img[@id="imgCode"]/@src')[0]
# 拼接 验证码url
img_url = "https://so.gushiwen.cn" + "/RandCode.ashx"
# 访问 验证码url
code_response = session.get(url=img_url).content
# 识别验证码
result = ocr.classification(code_response)
# 登录url
login_url = "https://so.gushiwen.cn/user/login.aspx?from=http%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx"
# 构建请求信息
params = {
'from': 'http://so.gushiwen.cn/user/collect.aspx',
'email': '**********', # 填入自己的账号
'pwd': '**********', # 填入自己的密码
'code': result,
'denglu': '登录'
}
# 访问登录页面
login_response = session.post(url=login_url, data=params)
# 实例化对象
tree = etree.HTML(login_response.text)
# 解析数据
binding_info = tree.xpath('//div[@class="shisoncont"]/div[5]/a/text() | //div[@class="shisoncont"]/div[5]/span/text()')
data_list = tree.xpath('//div[@class="sons"]/div')
# 格式化输出
title, state = binding_info
print("用户注册信息:")
print(f"{title}:{state}")
print("用户收藏信息:")
for data in data_list:
author = data.xpath('a/text()')[-1]
poetry = data.xpath('a/span/text()')[-1]
print(f"{author}{poetry}")
结果展示:
该文章仅供学习和交流。