使用CookieJar提取cookie信息

首先,推荐几个帖子,大伙可以先看看。国内通过cookiejar主要获取cookie的方法,大致都是如此的。

http.cookiejar库之CookieJar_pigYanYan的博客-CSDN博客

Python编程:cookiejar的使用_彭世瑜的博客-CSDN博客

再推荐一个资料帖,这个帖子主要涉及后面介绍的一种获取cookie的过程中所使用的一个方法。

cookielib_网络 | Internet_Python_参考手册_非常教程

本此,之所以写这个贴子主要是记录下,国外通过cookiejar是如何获取cookie的。总的来说,要比国内搞得复杂的多,但是也底层的多。

import gzip, os
from http import cookiejar
from urllib.request import Request
from xmlrpc.client import Transport

BUGZILLA_COOKIE_FILE = '/tmp/.bugzilla-cookies.txt'


class CookieTransport(Transport):
    """
    A subclass of xmlrpclib.Transport that supports cookies.
    """
    cookiejar = None

    def __init__(self, use_datetime=0, url=None):
        """
        Extend xmlrpclib.Transport's constructor to include url
        """
        self.url = url
        super(CookieTransport, self).__init__(use_datetime=use_datetime)

    def send_cookies(self, connection, cookie_request):
        """
        Send cookies to Bugzilla server
        """
        if self.cookiejar is None:
            # 实例化 MozillaCookieJar,这里国内外用法一致
            # BUGZILLA_COOKIE_FILE是用来存储具体的cookie信息的文件
            self.cookiejar = cookiejar.MozillaCookieJar(BUGZILLA_COOKIE_FILE)

            if os.path.exists(BUGZILLA_COOKIE_FILE):
                # 再次运行的时候,就可以直接读取cookie信息了
                self.cookiejar.load(BUGZILLA_COOKIE_FILE)
            else:
                # 初次运行,文件BUGZILLA_COOKIE_FILE是不存在的,所以save一把,用于创建文件
                self.cookiejar.save(BUGZILLA_COOKIE_FILE)

        # 将cookie信息从MozillaCookieJar对象中提取出来,添加到 cookie_request 对象的header里去
        # cookie_request对象就是 urllib.request.Request 对象,如果,有先看国内搞cookie的那几个
        # 帖子,就应该知道,用国内的方法,只需传入 urllib.request.Request 对象,去实际访问服务器的时候
        # 就可以直接获取到 cookie 信息了。而其具体实现的过程,就包括了下面的这个步骤,这里相当与将国内
        # 介绍的一体化操作,又分解了
        # 这里注意,初次运行代码到这里的时候,是不会添加啥东西出来的,因为这个时候,MozillaCookieJar
        # 对象此时还没有获取到cookie信息呢,只有再次运行到此处的时候,代码执行 self.cookiejar.load(BUGZILLA_COOKIE_FILE)
        # 动作的时候,self.cookiejar中才会存在具体的cookie信息,然后才能将其添加到cookie_request(即urllib.request.Request)
        # 对象的header中
        self.cookiejar.add_cookie_header(cookie_request)

        # 从 urllib.request.Request 对象中提取cookie信息
        cookielist = list()
        for header, headerdata in cookie_request.header_items():
            if header.startswith('Cookie'):
                cookielist.append([header, headerdata])
        # 将cookie添加到connection对象
        for header, headerdata in cookielist:
            connection.putheader(header, headerdata)
    
    def single_request_with_cookies(self, host, handler, request_body, verbose=False):
        # 首先一样是先造一个Request对象(其作用本身就是用于存储一些信息的,比如:url,header等)
        request_url = "https://%s%s" % (host, handler)
        cookie_request = Request(request_url)

        # 然后造一个发送请求的对象, 本来按照如下方法正常创造即可,但是,
        # 由于我们后续需要对header添加cookie,所以就不能如此使用了,python2.7版本可以这样用
        # 但是3.8版本是完全不行了,3.8版本对send_request方法做出了高度的集成改动,总体来说
        # 可以更加方便的创建可以发送请求的connect对象了,但是同样降低了其使用的灵活性,就比如
        # 给connect对象添加cookie,就会变得无法实现

        # h = self.send_request(host, handler, request_body, debug=verbose)

        # 这里我将python3.8版本里的 send_request 函数里的内容直接从xmlrpc库提取出来,直接用
        # 注意具体的使用会和send_request中略有不同,send_request方法的原始内容,我放到下面了
        h = self.make_connection(host)
        headers = self._headers + self._extra_headers
        if verbose:
            h.set_debuglevel(1)
        if self.accept_gzip_encoding and gzip:
            h.putrequest("POST", handler, skip_accept_encoding=True)
            headers.append(("Accept-Encoding", "gzip"))
        else:
            h.putrequest("POST", handler)
        headers.append(("Content-Type", "text/xml"))
        headers.append(("User-Agent", self.user_agent))
        self.send_headers(h, headers)

        # 注意,要修改header的内容,必须要在send_content动作之前
        # 这里就是添加cookie到header的地方, 也是实例化 MozillaCookieJar 对象的地方
        self.send_cookies(h, cookie_request)
        # 将request_body发送到服务器
        self.send_content(h, request_body)

        # 获取来自服务器的相应,而这个相应中,就蕴含着cookie信息
        response = h.getresponse()

        # 这个类是有必要造的,因为后续从response中提取cookie的时候,需要这样一种
        # 数据结构
        class CookieResponse:
            """
            parse headers and get cookies here
            fake a response object that we can fill with the headers above
            """

            def __init__(self, headers):
                self.headers = headers

            def info(self):
                return self.headers

        # 构建extract_cookies所需的参数
        cookie_response = CookieResponse(response.msg)
        # 从response中提取cookie信息
        # 正如上面send_cookies方法的注释中所提到的,这是将一体化动作拆分的过程。
        # cookie_request对象起一定的校验功能。另外就是,原本在一体化执行的过程,所有
        # 调用过程均存在于内部,外部仅需传入一个urllib.request.Request对象,所以
        # 此处在模仿内部调用的过程,就肯定也需要构造一个同样的对象,供其使用,因此在我
        # 看来,extract_cookies方法的重头戏就是从response提取cookie,传入cookie_request
        # 的目的更像是打个辅助罢了
        self.cookiejar.extract_cookies(cookie_response, cookie_request)

        # 将提取到的cookie信息,保存到文件中
        self.cookiejar.save(self.cookiejar.filename)

        if response.status == 200:
            self.verbose = verbose
            return self.parse_response(response)

    def send_request(self, host, handler, request_body, debug):
        """
        xmlrpc.client.Transport.send_request()的原始内容
        """
        connection = self.make_connection(host)
        headers = self._headers + self._extra_headers
        if debug:
            connection.set_debuglevel(1)
        if self.accept_gzip_encoding and gzip:
            connection.putrequest("POST", handler, skip_accept_encoding=True)
            headers.append(("Accept-Encoding", "gzip"))
        else:
            connection.putrequest("POST", handler)
        headers.append(("Content-Type", "text/xml"))
        headers.append(("User-Agent", self.user_agent))
        self.send_headers(connection, headers)
        self.send_content(connection, request_body)

注意,上述内容,为演示,说明内容,并不是说,照搬可以完整执行哈。

关于 def send_cookies(self, connection, cookie_request): 方法做一个演示:

在执行 self.cookiejar.add_cookie_header(cookie_request) 之前,cookie_request 对象长这样:

 执行之后,长这样:

 这不是果断加进header了。

另外,关于 self.cookiejar.save(self.cookiejar.filename) 保存cookie信息到文件,也介绍一个:

执行保存动作之前,.bugzilla-cookies.txt 文件长这样:

 之后:

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux权限

Linux下有两种用户:超级用户(root)、普通用户。超级用户(root):可以在linux系统下做任何事,不受限制,只有1个。普通用户:在linux系统下做有限的事,有N个。超级用户的提示符#;普通用户的提示符$切换用户的命令:su切换root时可以直接…

MQ之kafka

一 概念 Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各种需…

Visual Studio Code2023(VSCode2023)安装包下载及安装教程(最新版接入了chat GPT)

[软件名称]: Visual Studio Code2023 [软件大小]: 88.6 MB [安装环境]: Win11/Win10/Win7 [软件安装包下载]:https://pan.quark.cn/s/ee94a4aa2abc Visual Studio Code简称“VS Code”是Microsoft在2015年4月30日Build开发者大会上正式宣布一个运行于 Mac OS X、Windows和 Lin…

【Datawhale动手学深度学习笔记】多层感知机代码实践

多层感知机 激活函数 激活函数(activation function)通过计算加权和并加上偏置来确定神经元是否应该被激活, 它们将输入信号转换为输出的可微运算。 大多数激活函数都是非线性的。 由于激活函数是深度学习的基础,下面简要介绍一…

多线程进阶学习09------ThreadLocal详解

ThreadLocal:提供线程的局部变量,对于线程共享变量如果使用ThreadLocal则无需加锁,更省事省心。 ThreadLocal本地线程变量,线程自带的变量副本(实现了每一个线程副本都有一个专属的本地变量,主要解决的就是让每一个线程绑定自己的值,自己用自…

FastReport .NET 2023.2.4 Crack

FastReport .NET Reporting and documents creation library for .NET 7 FastReport .NET适用于 .NET 7、.NET Core、Blazor、ASP.NET、MVC 和 Windows Forms 的全功能报告库。它可以在微软视觉工作室 2022 和 JetBrains Rider 中使用。 利用 .NET 7、.NET Core、Blazor、ASP.N…

React:九、组件的生命周期

1.生命周期的理解 组件从创建到死亡它会经历一些特定的阶段。React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。我们在定义组件时&#xff0c;会在特定的生命周期回调函数中&#xff0c;做特定的工作。2.生命周期小案例 <!DOCTYPE html> <html…

操作系统权限维持(十五)之Linux系统-inetd远程后门

系列文章 操作系统权限维持&#xff08;一&#xff09;之Windows系统-粘贴键后门 操作系统权限维持&#xff08;二&#xff09;之Windows系统-克隆账号维持后门 操作系统权限维持&#xff08;三&#xff09;之Windows系统-启动项维持后门 操作系统权限维持&#xff08;四&…

leaflet加载GPX文件,第2种图形显示方法(119)

第119个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中加载GPX文件,将图形显示在地图上,这是另外一种方式,看前一种方式请从目录中查找。GPX文件是以GPS数据交换格式保存的GPS数据文件,是一种通用的地图信息文件,可以被众多GPS应用和Web服务更轻松地导入和…

Jenksin pipeline: 全局变量 和 input中的局部变量

在jenkins的流水线中全局变量的定义基本有两种实现方法&#xff1a;参数化构建过程中定义&#xff0c;流水线中直接定义 参数化构建过程中定义 流水线中直接定义(Jenkins 2.x支持代码及即服务) 可以用流水线生成 在配置parameters后&#xff0c;往往需要先构建一遍&#…

耗时 24 小时整理了网络安全学习路线,非常详细!

前言上次发的文章【都2023年了&#xff0c;还在问网络安全怎么入门】很多小伙伴在评论区回复不知道怎么学习&#xff0c;我也反思了一下&#xff0c;确实没写到学习方法和路线&#xff0c;所以这一期就出一一个怎么学习网络安全的学习路线和方法&#xff0c;觉得有用的话三连收…

软件测试入门简单么?入行后如何做职业规划

软件测试的确是入门相对简单的一个学科&#xff0c;他们不常写代码&#xff0c;主要去检查代码&#xff0c;是不是出现了漏洞、程序是否能运行下去&#xff1f;那这部分程序员就是做软件测试。 这个类别没有做Java难没有大数据那么复杂&#xff0c;但还可以拿到程序员的高薪。…

一招解决macOS12 CleanMyMac闪退

距全新的macOS 12 Monterey正式版发布已经过去了快6个月&#xff0c;macOS Monterey 12 新增了同播共享功能、 Apple Music 声控方案、“数字遗产”计划、“照片”中重新设计的“回忆”&#xff0c;以及针对 Mac 的其他功能和错误修复等大量更新和改进。 很多Mac用户也已经升级…

【模板】树状数组

目录&#xff1a; 单点修改&#xff0c;区间查询&#xff1a; 题目描述&#xff1a; lowbit()运算&#xff1a; 插入、修改单点数据&#xff1a; 计算前缀和&#xff1a; 完整代码&#xff1a; 区间修改&#xff0c;单点查询&#xff1a; 计算差分数组&#xff1a; 计算每个点的…

Node.js 入门

转载请注明出处&#xff0c;点击此处 查看更多精彩内容。 什么是 Node.js &#xff1f; Node.js 是一个基于 Chrome V8 引擎的开源的跨平台的 JavaScript 运行时环境。 Node.js 采用了基于事件的、单线程的异步 I/O 架构。 Node.js 的组成部分 V8引擎 V8 引擎就是 JavaScrip…

使用 React 和 GPT-4 技术构建智能语言翻译应用

Midjourney 创作&#xff0c;Language Translation in future在今天的互联世界中&#xff0c;语言翻译在弥合沟通差距和促进全球合作方面发挥着至关重要的作用。随着像 OpenAI 的 GPT-4 这样先进的 AI 模型的出现&#xff0c;我们现在有机会创建高度精确和上下文感知的翻译工具…

USB键盘实现——带指示灯的键盘(九)

文章目录带指示灯的键盘set_report 类特殊请求实现类特殊请求USB 控制端点收到的数据增加一个输出端点实现配置描述符集合输出端点收到的数据带指示灯的键盘 要实现带指示灯的键盘&#xff0c;有两种方式 除控制端点和输入端点外&#xff0c;不额外增加端点&#xff0c;根据 …

不完全微分算法(SCL+ST代码)

PID控制器的基本算法,可以参看专栏的系列文章,链接如下: 三菱FX3U PLC 位置式PID算法(ST语言)_fx3u pid_RXXW_Dor的博客-CSDN博客三菱PLC自带的PID不必多说,大家可以自行查看指令说明。关于FX3U 增量式PID可以参看专栏的另一篇博客三菱PLC增量式PID算法FB(带死区设置和外部…

springCloud学习【3】之Docker完整版

文章目录一 初识Docker1.1 应用部署的环境问题1.2 Docker简介1.3 Docker解决操作系统环境差异1.4 Docker和虚拟机的区别1.5 Docker架构1.5.1 镜像和容器1.5.2 DockerHub1.5.3 Docker架构1.5.4 Docker工作流1.6 Docker的安装和启动1.7 安装步骤1.8 启动Docker1.9 配置镜像加速二…

总结802

早上&#xff1a; 6:23起床 6:43出门 7:00~7:40小湖读书 8:00~9:45机器人控制 9:50~11:30句句真研 11:31~12:10吃饭 12:12~12:22动漫 12:45~2:09午觉 2:00~4:15深度学习 4:26~4:39去图书馆 4:40~6:11高等数学第五讲 6:13~6:40跑步开合跳100胯下击掌100 6:50~7:20吃…