我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈
入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈
虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈
PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈
Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈
优 质 资 源 下 载 :👉👉 资源下载合集 👈👈
优 质 教 程 推 荐:👉👉 Python爬虫从入门到入狱系列 合集👈👈
关于登录和验证码
- 关于登录和验证码
- 关于登录
- 关于验证码
- 方式一:免费
- 方式二:付费
- 登录
- 总结
关于登录和验证码
关于登录
-
跟踪登录流程,了解Cookie的生成过程
-
本次学习以 http://www.woaidu.cc/ 为例进行练习
-
登录网站 —— 随意找几本小说 —— 在线月度 —— 加入书架 —— 点击右上角的用户名(User) 可以查看到当前账户所有加入书架的书本
-
要求:获取当前账户下加入书架内所有书本名称
-
方式一:人工登录,进入书架后,在抓包工具中复制Requests Headers
-
优点:简单、粗暴
-
缺点:每次都需要人工登录,手动复制Headers
import requests from lxml import etree shuj_url = f'http://www.woaidu.cc/bookcase.php' session = requests.session() # 设置Headers session.headers = { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "accept-encoding": "gzip, deflate", "accept-language": "zh-CN,zh;q=0.9", "cache-control": "no-cache", "connection": "keep-alive", "cookie": "你的cookie信息", "host": "www.woaidu.cc", "pragma": "no-cache", "referer": "http://www.woaidu.cc/book_1255314.html", "upgrade-insecure-requests": "1", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" } # 通过session发送请求 resp = session.get(shuj_url) html_code = resp.content.decode("UTF-8") tree = etree.HTML(html_code) # type: etree._Element names = tree.xpath('//h4[@class="bookname"]/a/text()') for name in names: print(name)
-
方式二:使用session自动获取cookie
-
需要看到书架,前提就是需要登录账号
-
可以先通过代码测试一下没有登录(不携带cookie信息)的时候查看书架是否能看到内容
import requests url = 'http://www.woaidu.cc/bookcase.php' my_headers = { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "accept-encoding": "gzip, deflate", "accept-language": "zh-CN,zh;q=0.9", "cache-control": "no-cache", "connection": "keep-alive", "host": "www.woaidu.cc", "pragma": "no-cache", "referer": "http://www.woaidu.cc/", "upgrade-insecure-requests": "1", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" } resp = requests.get(url, headers=my_headers) print(resp.content.decode('utf-8'))
-
查看结果
-
结果发现,当不给cookie信息时,是获取不到书架内容的
-
测试携带cookie信息
import requests url = 'http://www.woaidu.cc/bookcase.php' my_headers = { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "accept-encoding": "gzip, deflate", "accept-language": "zh-CN,zh;q=0.9", "cache-control": "no-cache", "connection": "keep-alive", "cookie": "你的cookie信息", "host": "www.woaidu.cc", "pragma": "no-cache", "referer": "http://www.woaidu.cc/", "upgrade-insecure-requests": "1", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" } resp = requests.get(url, headers=my_headers) print(resp.content.decode('utf-8'))
-
查看结果
-
添加了cookie信息之后,就能访问到书架了
-
分析cookie,可以看到当前cookie由以下几个信息组成
Hm_lvt_1...... HMACCOUNT Hm_lpvt_1...... username...... t......
-
其中以
Hm
和HM
开头的cookie是百度排名相关的,可以不用管 -
那么跟踪一下
username
和t
的cookie信息 -
可以看到
username
和t
cookie信息都是通过网址http://www.woaidu.cc/login.php
响应返回的 -
清空cookie信息后访问网址,发现是登录页面,说明这两个cookie信息是登录后返回的
-
此时,需要再跟踪一下登录时发送请求的情况
-
打开登录界面,随意输入一个错误的账号密码,点击登录,查看抓包情况
-
抓包可以看到,登录的时候发送了一个post请求,请求参数包含了账号、密码、验证码等
-
同时,在发送这个post请求的时候,请求头中也是包含了cookie信息
-
分析改cookie信息,可以看到cookie信息中包含
Hm_lvt_155d53bb19b3d8127ebcd71ae20d55b1=1725245999; Hm_lpvt_155d53bb19b3d8127ebcd71ae20d55b1=1725245999; HMACCOUNT=832C549F34E314E4; c=tq84hVrepXPs......
-
这个cookie信息中
Hm
和HM
开头的cookie是百度排名相关的,可以不用管 -
那么还有一个
c
的cookie信息,我们尝试不带这个cookie信息是否能登录import requests my_headers = { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "accept-encoding": "gzip, deflate", "accept-language": "zh-CN,zh;q=0.9", "cache-control": "no-cache", "connection": "keep-alive", "content-length": "153", "content-type": "application/x-www-form-urlencoded", "cookie": "你的cookie信息", "host": "www.woaidu.cc", "origin": "http://www.woaidu.cc", "pragma": "no-cache", "referer": "http://www.woaidu.cc/login.php", "upgrade-insecure-requests": "1", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" } my_data = { "LoginForm[username]": "123123123", "LoginForm[password]": "aaaa", "LoginForm[captcha]": "4748", "action": "login", "submit": "登 录" } url = 'http://www.woaidu.cc/login.php' resp = requests.post(url, headers=my_headers, data=my_data) print(resp.content.decode('utf-8'))
-
查看结果
-
这里返回的结果,提示的是验证码异常,与之前页面提示的
用户名和密码错误
并不相同 -
说明这个
c
的cookie信息必须要携带 -
此时,我们又不能直接复制这个cookie信息,那么我们就需要找到
c
这个cookie信息是通过哪个请求响应携带回来的 -
清空抓包数据,重新访问登录页面,全局查找
c=
,查看这个cookie是通过那个响应数据携带返回的 -
再次清空cookie信息和抓包数据,重新访问登录页面,查看刚刚返回
c=
相关cookie信息的请求 -
同时,预览这个请求,返回回来的是一个验证码图片
-
可以看到,发送这个请求的时候,请求头中没有再需要携带其他cookie信息,只需要直接访问,就会在返回响应一个验证码图片的时候携带一个cookie信息
-
此时,通过发送请求,拿到了需要的cookie信息和验证码图片,接下来就是登录了!
-
问题来了:那拿到这个验证码图片怎么将验证码识别出来添加到请求参数中呢?
关于验证码
- 验证码识别有两种方式
方式一:免费
- 使用第三方库:ddddocr
- 安装
pip install ddddocr # 指定安装源 pip install -i https://mirrors.aliyun.com/pypi/simple ddddocr
- 官方文档
- https://github.com/sml2h3/ddddocr
- 使用
import requests import ddddocr url = 'http://www.woaidu.cc/code.php?0.056086518443781985' my_headers = { "accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", "accept-encoding": "gzip, deflate", "accept-language": "zh-CN,zh;q=0.9", "cache-control": "no-cache", "connection": "keep-alive", "host": "www.woaidu.cc", "pragma": "no-cache", "referer": "http://www.woaidu.cc/login.php", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" } resp = requests.get(url, headers=my_headers) image_b = resp.content # 创建Ddddocr对象, show_ad=False表示不显示广告 # 使用默认ocr模型 ddd1 = ddddocr.DdddOcr(show_ad=False) result1 = ddd1.classification(image_b) print(result1) # 使用第二ocr模型 ddd2 = ddddocr.DdddOcr(show_ad=False, beta=True) result2 = ddd2.classification(image_b) print(result2)
方式二:付费
-
使用第三方api识别
- 超级鹰:http://www.chaojiying.com/
- 图鉴:http://ttshitu.com/
- 两个网站可自行注册、充值
-
这里以图鉴为例进行测试
-
打开网址,登录账号 —— 开发文档
-
此页面可以先了解一下API如何使用
-
点击左侧
Python
进入python调用API示例 -
复制代码,稍作修改就可以直接用了
import base64 import json import requests # uname # 用户名 # pwd # 密码 # img # 图片地址 # typeid # 识别类型 def base64_api(uname, pwd, img, typeid): with open(img, 'rb') as f: base64_data = base64.b64encode(f.read()) b64 = base64_data.decode() data = {"username": uname, "password": pwd, "typeid": typeid, "image": b64} result = json.loads(requests.post("http://api.ttshitu.com/predict", json=data).text) if result['success']: return result["data"]["result"] else: # 注意:返回 人工不足等 错误情况 请加逻辑处理防止脚本卡死 继续重新 识别 return result["message"] return ""
-
测试API
import base64 import json import requests url = 'http://www.woaidu.cc/code.php?0.056086518443781985' my_headers = { "accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", "accept-encoding": "gzip, deflate", "accept-language": "zh-CN,zh;q=0.9", "cache-control": "no-cache", "connection": "keep-alive", "host": "www.woaidu.cc", "pragma": "no-cache", "referer": "http://www.woaidu.cc/login.php", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" } resp = requests.get(url, headers=my_headers) with open('code.png', 'wb') as f: f.write(resp.content) def base64_api(uname, pwd, img, typeid): """ 通过api接口识别图片中的验证码 :param uname: 用户名 :param pwd: 密码 :param img: 图片地址 :param typeid: 识别类型 :return: """ # base64.b64encode() 对图片进行base64编码 with open(img, 'rb') as f: base64_data = base64.b64encode(f.read()) b64 = base64_data.decode() data = {"username": uname, "password": pwd, "typeid": typeid, "image": b64} result = json.loads(requests.post("http://api.ttshitu.com/predict", json=data).text) if result['success']: return result["data"]["result"] else: # 注意:返回 人工不足等 错误情况 请加逻辑处理防止脚本卡死 继续重新 识别 return result["message"] return "" result = base64_api('你的账号', '账号密码', '图片地址', 1001) print(result)
登录
- 验证码可以获取到了,那么可以使用代码进行登录了
import base64 import json import requests import ddddocr code_url = 'http://www.woaidu.cc/code.php?0.056086518443781985' my_headers = { "accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", "accept-encoding": "gzip, deflate", "accept-language": "zh-CN,zh;q=0.9", "cache-control": "no-cache", "connection": "keep-alive", "host": "www.woaidu.cc", "pragma": "no-cache", "referer": "http://www.woaidu.cc/login.php", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" } # 创建session对象 session = requests.session() # 给session对象设置头信息 session.headers = my_headers # 使用session发送请求,获取验证码图片 code_resp = session.get(code_url) # 保存验证码图片 with open('code.jpg', 'wb') as f: f.write(code_resp.content) # 方法一:使用第三方API识别验证码 def base64_api(uname, pwd, img, typeid): """ 通过api接口识别图片中的验证码 :param uname: 用户名 :param pwd: 密码 :param img: 图片地址 :param typeid: 识别类型 :return: """ # base64.b64encode() 对图片进行base64编码 with open(img, 'rb') as f: base64_data = base64.b64encode(f.read()) b64 = base64_data.decode() data = {"username": uname, "password": pwd, "typeid": typeid, "image": b64} result = json.loads(requests.post("http://api.ttshitu.com/predict", json=data).text) if result['success']: return result["data"]["result"] else: # 注意:返回 人工不足等 错误情况 请加逻辑处理防止脚本卡死 继续重新 识别 return result["message"] return "" # 调用函数,获取验证码 yzm = base64_api('图鉴网账号', '密码', './code.jpg', 1) # # 方法二:使用ddddocr库识别验证码 # ocr = ddddocr.DdddOcr(show_ad=False) # with open('code.jpg', 'rb') as f: # img_bytes = f.read() # # yzm = ocr.classification(img_bytes) # 发送post请求,登录,需要携带验证码 login_url = 'http://www.woaidu.cc/login.php' login_data = { "LoginForm[username]": "我爱读电子书网账号", "LoginForm[password]": "密码", "LoginForm[captcha]": yzm, "action": "login", "submit": "登 录" } # 目的是为了将登录后的cookie信息保存到session对象中 resp = session.post(login_url, data=login_data) # 登录成功后,访问个人中心(书架) shujia_url = 'http://www.woaidu.cc/bookcase.php' shujia_content = session.get(shujia_url) print(shujia_content.text)
总结
- 首先查看登录时发送的请求中,请求头中cookie信息
- 查找cookie信息的来源(通过哪个请求的响应携带回来的)
- 这个案例中,登录请求的cookie信息是通过验证码请求返回携带的
- 但有些网站并不是,所以每个网站可能都不同,需要具体跟踪分析
- 通过session对象发送请求,获取验证码图片,并自动保存cookie信息
- 识别验证码图片,获取验证码
- 登录账号、密码、验证码等创建post请求参数
- 使用保存了cookie信息的session对象向登录页面发送post请求
- 登录成功之后,session对象会自动保存用户信息到cookie中
- 最后,使用携带了用户信息cookie的session对象向书架发送get请求