【Python爬虫系列】_016.关于登录和验证码

news2024/11/8 12:07:02

无奋斗不青春

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈
入 门 教 程 推 荐 :👉👉 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......
    
  • 其中以 HmHM 开头的cookie是百度排名相关的,可以不用管

    • 在这里插入图片描述
  • 那么跟踪一下 usernamet 的cookie信息

    • 在这里插入图片描述
  • 可以看到 usernamet 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信息中 HmHM 开头的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请求

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2129948.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【UI】element ui table(表格)expand实现点击一行展开功能

文章目录 前言涉及知识点:代码部分隐藏小箭头总结 前言 element ui是一个非常不错的vue的UI框架,element对table进行了封装,简化了vue对表格的渲染。 element ui表格中有一个功能是展开行,在2.0版本官网例子中,只可以…

Linux和C语言(Day 12)

一、学习内容 存储类型 定义变量语法格式 数据类型 变量名; 存储类型 数据类型 变量名; 【定义变量可以省略存储类型,默认是auto】 定义函数语法格式 数据类型 函数名(参数){} 存储类型 数据类型 函数名(参数){} 【定义函数可以省略存储类型,默认是exte…

【PostgreSQL】安装及使用(Navicat/Arcgis),连接(C#)

简介 PostgreSQL 是一个功能强大的开源对象关系数据库系统 下载地址 PostgreSQL: Downloads 由于我电脑上安装的是arcgispro3.1所以需要下载对应的postgresql版本 PostgreSQL 12 对应的 PostGIS 版本主要是 3.5.0 或更高版本。 安装 一般设置为postgresql 安装扩展插件 此…

计算机的错误计算(九十一)

摘要 讨论自然对数 ln(x)的计算精度问题。 例1. 计算 ln(0.999999999999996) . 不妨用Python计算,则有: 若用Java代码计算: import java.lang.Math; public class Ln{public static void main(String[] args) {double x 0.9999999999999…

JMeter脚本开发

环境部署 Ubuntu系统 切换到root用户 sudo su 安装上传下载的命令 apt install lrzsz 切换文件目录 cd / 创建文件目录 mkdir java 切换到Java文件夹下 cd java 输入rz回车 选择jdk Linux文件上传 解压安装包 tar -zxvf jdktab键 新建数据库 运行sql文件 选择sql文件即…

操作系统 ---- 调度算法的评价指标

一、调度算法评价指标 1.1 CPU利用率 资源利用率。为提高系统的资源利用率,应使系统中的处理机和其它所有资源都尽可能地保持忙碌状态,其中最重要的处理机利用率可用以下方法计算: 例题: 1.2 系统吞吐量 由于吞吐量是指在单位…

Playwright与Selenium的对比:谁是更适合你的自动化测试工具?

在自动化测试领域,Selenium 一直是行业的标杆工具。它功能强大、支持多浏览器、广泛应用于各类项目中。然而,随着技术的发展,新的工具不断涌现,Playwright 作为其中的佼佼者,以其现代化的设计和强大的特性吸引了越来越…

828华为云征文|docker部署kafka及ui搭建

1.介绍 1.1 什么是华为云Flexus X实例 最近华为云828 B2B企业节正在举办,Flexus X实例的促销也非常给力,大家可以去看看。特别是对算力性能有要求,同时对自建MySQL、Redis、Nginx性能有要求的小伙伴,千万不要错过。Flexus云服务器…

你都学会栈和队列了赶紧手搓一个对象池吧!!!(超详细,超简单适合新手宝宝学习)

前置知识:en造数据结构与算法C# 用数组实现个栈还不简单???看我一秒破之!!!(unity演示)-CSDN博客 c#有官方造好的关于stack的轮子,建议学习学习拿来直接用 …

揭开OpenAI草莓模型神秘面纱——重塑大语言模型的逻辑能力

OpenAI即将发布“草莓”模型 来源:medium 据报道,OpenAI计划在未来两周内发布其新的AI模型Strawberry(草莓)。据 Seeking Alpha周二(9 月 10 日)援引The Information 的一篇付费文章报道,新模型…

Solana核心漏洞技术详解

8月9日,Solana团队齐心协力解决了一个严重的安全漏洞。这次秘密修复详情可以在GitHub上查询到。CertiK团队对这一漏洞进行了深入分析。 1. Solana漏洞起因 8月9日,Solana验证者和客户端团队齐心协力解决了一个严重的安全漏洞。Solana验证者Laine表示&am…

[WUSTCTF2020]颜值成绩

1.测试输入发现存在数字型sql注入 1 and 1 报错 尝试了几个字符,确定空格被过滤了 空格用/**/替换 1/**/and/**/1 构造轮子尝试成功,所以这里要用布尔注入 后面的思路就是比较常规的了,先爆破库名,再爆破表、字段 写了个脚本简…

第四部分:1---文件基础理解、C语言文件操作、Linux系统文件接口、使用一个变量传递多个标志位

目录 文件基础理解: 文件是如何组成的? 对文件操作的本质是什么? 文件被打开的本质是什么: 进程和文件的调度关系解析: 文件被打开后如何被管理(文件描述符/文件描述符表)? 文…

深度学习——基础知识

深度学习的重点在于优化,其中很重要的步骤在于如何调参,会涉及到一些微积分等数学知识。不同于以往接触到的数值运算,深度(机器)学习都是关于张量Tensor(向量)的计算,Python中最常用…

【oj刷题】滑动窗口篇:滑动窗口的应用场景和注意事项

前言: 滑动窗口其实基本原理还是双指针,但在双指针中左右指针可能会有回退操作,而滑动窗口的左右指针只会向前走,不会回退,下面就来讲解一下滑动窗口的概念和具体操作(主要是例题讲解) 目录 一、…

【 Linux】基础命令及常用小技巧

文章目录 Linux基础命令常用小技巧基本命令pwd : print work directory 打印当前的工作目录cd : change driectory 改变当前工作目录ls: list 查看指定目录下的文件mkdir: make directory 创建目录 文件操作命令查找命令管道命令和过滤命令wc : word count 单词统计echo 输出命…

Hotohiko Sakamoto算法,以及用其计算星期几【算法 15】

探索Hotohiko Sakamoto算法:构建素数排列的奥秘 在算法领域,Hotohiko Sakamoto算法以其独特的构造方式和深刻的数学背景,吸引了众多算法爱好者和研究者的关注。本文将带您一起探索Hotohiko Sakamoto算法的核心思想,了解它是如何构…

深度学习_GPT2Block详解(casual attention)

一、GTP2Block 整体结构 1.1 block准备 import torch from torch import nn from transformers import GPT2Model, GPT2Config from transformers.models.gpt2.modeling_gpt2 import GPT2Blockcfg GPT2Config() print(cfg.add_cross_attention) blk GPT2Block(cfg, layer_…

“汉语新解” Prompt新高度,火爆的李继刚

“汉语新解” prompt 是由李继刚设计的一个用于启发人工智能模型进行创意性文本生成的指令模板。这个 prompt 的设计初衷是为了让AI能够以一种独特的方式解析和重新诠释常见的中文词汇,从而产生出具有深刻洞察力和幽默感的文本内容,仿佛是由鲁迅或林语堂…

Linux线程同步:深度解析条件变量接口

🍑个人主页:Jupiter. 🚀 所属专栏:Linux从入门到进阶 欢迎大家点赞收藏评论😊 目录 🍑Linux线程同步🐉条件变量---实现线程同步💧同步概念与竞态条件🐆条件变量接口*初始…