熟悉requests用法,实现简单网站爬虫

news2024/11/15 20:47:41

本文模拟的是前后端分离项目,使用账号密码登录获取到token,拿着token加载用户信息,加载分页列表数据并存储文件。
本文用到的知识点:
1、urllib.parse URL解析;
2、session用法,保存所有请求在一个会话中;取决于后台是否使用session传话保持;
3、requests请求,添加headers,data参数;
4、requests请求重定向获取重定向地址;
5、文件的写入;

创建Myspider 类,包含一个变量__token__和5个函数:

import json
import urllib.parse
import requests
from urllib.parse import urlparse
class MySpider:
    __token__ = ''

    def __init__(self, session):
        self.session = session
        
    def parseurlquery(self, str):
    
	def login(self):

	def initUserinfo(self):
	
	def findContractPlan(self):

	def moreInfo(self):
        

0 自定义工具函数:解析url参数

原格式:token=abcqowe222&a=123。
返回dict:{‘token’:‘abcqowe222’,‘a’:‘123’}

    def parseurlquery(self, str):
        data = {}
        d = str.split('&')
        for q in d:
            key, val = q.split('=')
            data[key] = val
        return data

1 login(self)模拟账号密码登录,获取通行凭证token

代码所示登录接口,访问后并非直接返回成功与失败,而是重定向到dict[‘service’]指向的地址并携带token作为参数。

    def login(self):
        url = "http://localhost:81/sso/v2/userLogin.html"
        dict = {'userName': 'louqun', 'passWord': '1', 'service': 'http://localhost:8088/#/home',
                'authAppUUIDQX': '20171205112924314GXKKP'}
        headers = {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Host': 'localhost:81',
            'Origin': 'http://localhost:81',
            'Referer': 'http://localhost:81/sso/v2/loginUI.html?authAppUUIDQX=20171205112924314GXKKP&service=http%3A%2F%2Flocalhost%3A8088%2F%23%2Fhome',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.34'
        }
        #allow_redirects=False,禁用重定向,可以对比=True的时候返回的status_code、text、url。看差异
        res = self.session.post(url=url, data=dict, allow_redirects=False)
        # 获取重定向后的地址,并将url进行解析
        urlData = urllib.parse.urlparse(res.headers['Location'], allow_fragments=False)
        #自定义函数,将参数进行一步解析返回dict,从中获取token的值。并赋值给__token__变量
        self.__token__ = self.parseurlquery(urlData.query).get('token')

urllib.parse.urlparse示例:

from urllib.parse import urlparse

result = urlparse('https://www.baidu.com/index.html;user?id=5#comment')
print(type(result))
print(result)

返回结果是一个 ParseResult 类型的对象,它包含 6 个部分,分别是 scheme、netloc、path、params、query 和 fragment。输出:

<class 'urllib.parse.ParseResult'>
ParseResult(scheme='https', netloc='www.baidu.com', path='/index.html', params='user', query='id=5', fragment='comment')

2 加载用户信息,返回json对象

headers里面添加token,给请求添加header数据。

    def initUserinfo(self):
        innerUserInfo = 'http://localhost:8088/momtcg-admin/v1/login/innerUserInfo?timestamp=1681135994738'
        headers = {
            'Content-Type': 'application/json;charset=UTF-8',
            'Host': 'localhost:8088',
            'token': self.__token__,
            'Origin': 'http://localhost:8088',
            'Referer': 'http://localhost:8088/',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.34'
        }
        res = self.session.get(innerUserInfo, headers=headers)
        print(res.text)
        #直接转为dict。
        resultData = res.json()

3 加载列表数据未分页,将有用字段保存到文件

给post请求添加headers,data。我的接口需要将data用json.dump()转换为json字符串后,后台接口才能接收,否则会报错。应该和接口写法有关,没有深究。

    def findContractPlan(self):
        findContractPlanList = 'http://localhost:8088/momtcg-admin/v1/contractSpecialPurchasePlan/findContractPlanList'
        data = {
            "regionalCompanyId": "",
            "projectId": "",
            "planStatus": "",
            "projectByStage": "",
            "contractName": "",
            "pageFlag": 1,
            "pageNumber": 1,
            "pageSize": 10
        }
        headers = {
            'Content-Type': 'application/json;charset=UTF-8',
            'Host': 'localhost:8088',
            'token': self.__token__,
            'Origin': 'http://localhost:8088',
            'Referer': 'http://localhost:8088/',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.34'
        }
        res = self.session.post(findContractPlanList, headers=headers, data=json.dumps(data))
        contractPlanResult = res.json()
        print(contractPlanResult.get('data').get('list'))
        with open('contractList.txt', 'w') as f:
            for item in contractPlanResult.get('data').get('list'):
                print(item.get('id'), item.get('regionalCompanyName'), item.get('projectName'),
                      item.get('contractCode'),
                      item.get('contractName'))
                print(item)
                f.write(str(item) + '\r')
        return res.json()

4 加载分页列表

获取列表总数,计算总页数后,循环加载数据并按需写入文件;

    def moreInfo(self):
        moreInfo = 'http://localhost:8088/momtcg-admin/v1/login/moreInfo'
        data = {
            "pageFlag": 1,
            "pageNumber": 1,
            "pageSize": 10,
            "resultType": 3,
            "msgTitle": ""
        }
        headers = {
            'Content-Type': 'application/json;charset=UTF-8',
            'Host': 'localhost:8088',
            'token': self.__token__,
            'Origin': 'http://localhost:8088',
            'Referer': 'http://localhost:8088/',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.34'
        }
        res = self.session.post(moreInfo, headers=headers, data=json.dumps(data))
        moreInfoResult = res.json()
        # 获取到数据总数
        total = moreInfoResult.get('data').get('total')
        pageSize = 10
        pageNumber = 1
        with open('moreInfo.txt', 'w') as f:
            while True:
                if pageSize * pageNumber > total:
                    break;
                data.update({'pageNumber': pageNumber})
                res = self.session.post(moreInfo, headers=headers, data=json.dumps(data))
                print(res.text)
                moreInfoResult = res.json()
                if len(moreInfoResult.get('data').get('records')) == 0:
                    break;
                else:
                    for item in moreInfoResult.get('data').get('records'):
                        print(item)
                        f.write(str(item) + '\r')
                pageNumber += 1

5 方法调用

if __name__ == '__main__':
    s = requests.Session()
    spider = MySpider(s)
    spider.login()
    spider.initUserinfo()
    spider.findContractPlan()
    spider.moreInfo()

文本保存本地后效果:
在这里插入图片描述

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

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

相关文章

muduo源码剖析--Buffer

Buffer类 Buffer类是自定义处理数据输入缓冲的类&#xff0c;底层是vector< char >&#xff0c;通过readIdx和writeIdx将缓冲区分为3个部分&#xff0c;第一部分是预留的8字节已经读出的缓冲区字节数、第二部分是还未读出的部分、第三部分是可写的部分。 Buffer类的设计…

JavaScript【三】JavaScript中的数组

文章目录&#x1f31f;前言&#x1f31f;数组&#x1f31f;声明&#xff1a;&#x1f31f; 隐式创建&#xff1a;&#x1f31f; 实例化构造函数&#xff1a;&#x1f31f; 注意&#xff1a;一个值为数组的长度。&#x1f31f; 访问&#xff1a;&#x1f31f; 遍历&#xff1a;&…

C++练级之初级:第三篇

C练级之初级&#xff1a;第三篇 1.探索C中函数重载的本质 &#x1f914;首先我们先解决一下为什么C支持函数重载&#xff0c;而C语言不支持&#xff1f; 这里就不得不提起编译链接了&#x1f601;&#xff1b; &#x1f449;这是编译链接篇 以这三个简单的文件为例&#xff1…

C51单片机串口通信(概念部分)

1.通信的基本概念 1.1&#xff1a;串行通信与并行通信 &#xff08;1&#xff09;.串行通信 串行通信是指用一根数据线将 一个字节的八个bit位连接&#xff0c;从低位开始依次传输。 优点&#xff1a;成本便宜&#xff0c;传输稳定 缺点&#xff1a;速度慢 并行通信是指将一…

重学Java设计模式-行为型模式-责任链模式

重学Java设计模式-行为型模式-责任链模式 内容摘自&#xff1a;https://bugstack.cn/md/develop/design-pattern/2020-06-18-重学 Java 设计模式《实战责任链模式》.html#重学-java-设计模式-实战责任链模式「模拟618电商大促期间-项目上线流程多级负责人审批场景」 责任链模…

stegano(图片隐写、摩斯密码)

附件是PDF&#xff0c;我们在选择内容时发现光标溢出了文本 说明这里还存在一些我们看不到的内容 直接CtrlA全选&#xff0c;CtrlC复制后新建一个纯文本文件 将复制的东西粘贴过去 粘贴后发现果然多出来了一些东西&#xff0c;提取出来 BABA BBB BA BBA ABA AB B AAB ABAA A…

3.2 三角分解法

思维导图&#xff1a; 3.2 矩阵的三角分解 3.2.1 什么是矩阵的三角分解&#xff1a; 矩阵的三角分解&#xff0c;也称为LU分解&#xff0c;是一种将一个矩阵分解为一个下三角矩阵和一个上三角矩阵的方法。该分解通常用于解线性方程组和计算矩阵的行列式和逆矩阵。 设A为n*n的…

【通世智库】宁晓红:医疗更完整的样子

2022年的10月&#xff0c;北京协和医院缓和医学中心成立了&#xff0c;这是巨大的好消息&#xff01;北京协和医院连续13年蝉联中国医院排行榜榜首&#xff0c;它率先成立了缓和医学中心&#xff0c;可见缓和医疗在医学领域的重要地位和不可估量的价值。【作者&#xff1a;宁晓…

软件安全之CRC检测

CRC介绍 在玩某些游戏&#xff0c;例如fps类游戏时&#xff0c;你想要修改某些特定的数值实现一些功能&#xff0c;这时你很有可能会被查封账号甚至禁封机器码。因为你更改了游戏中的数据&#xff0c;从而导致接收方收到”错误的数据“。为尽量提高接收方收到数据的正确率&…

可视化Echarts中title、tooltip、legend的常用属性设置

title中常用的设置 配置项--tooltip 配置项--legend title中常用的设置 title 标题组件&#xff0c;包含主标题和副标题。 以下是常用的对标题的设置 title:{//设置图表的标题text:"主标题",link:"baidu.com", //设置标题超链接target:"self&q…

2023最新谷粒商城笔记之支付服务篇(全文总共13万字,超详细)

支付服务 这里我们是使用的支付宝进行支付&#xff0c;所以需要调用支付宝的相关API&#xff0c;下面来了解一下怎样使用支付宝进行线上支付。 支付宝配置相关概念 支付宝开放平台传送门&#xff1a;支付宝开放平台 网站支付DEMO传送门&#xff1a;手机网站支付 DEMO &…

数字滤波器设计——IIR 滤波器

数字滤波器设计实践介绍 此示例说明如何使用 Signal Processing Toolbox 产品中的 designfilt 函数&#xff0c;根据频率响应设定设计 FIR 和 IIR 滤波器。该示例重点讲述低通滤波器&#xff0c;但大多数结果也适用于其他响应类型。 此示例主要介绍数字滤波器的设计&#xff…

D3.js实现线条的流动效果(从一端移动到另一端并且变色)

参考&#xff1a; SVG&#xff1a;理解stroke-dasharray和stroke-dashoffset属性 使用SVG CSS实现动态霓虹灯文字效果 纯CSS实现帅气的SVG路径描边动画效果 实现的效果为&#xff1a;路径左移到完全看不见的地方&#xff0c;然后一边右移&#xff0c;一边从黑色变为红色 <…

社科院与杜兰大学金融管理硕士项目—人生的每一条路都可以看作是正确的路

成年人的世界里没有什么是容易的。生活中经常听到人说&#xff1a;早知道现在过得这么辛苦&#xff0c;当年真应该好好读书&#xff1b;早知道这个行业这么难出头&#xff0c;当年真不应该踏入这一行&#xff1b;早知道爱人这么不靠谱&#xff0c;当年不跟他结婚就好了……有时…

系统集成项目管理工程师软考知识点(每天更新)

第一章指路&#xff1a;系统集成项目管理工程师软考知识点&#xff08;第一章已完结&#xff09;_程序猿幼苗的博客-CSDN博客 第二章指路&#xff1a;系统集成项目管理工程师软考知识点&#xff08;第二章已完结&#xff09;_程序猿幼苗的博客-CSDN博客 本专栏将会更新完整~ …

【DRF开发手册】使用 Django Rest Framework 的 @action 定义自定义方法

本文节选自笔者博客&#xff1a; https://www.blog.zeeland.cn/archives/so3f209hfeac &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是Zeeland&#xff0c;全栈领域优质创作者。&#x1f4dd; CSDN主页&#xff1a;Zeeland&#x1f525;&#x1f4e3; 我的博客&…

C++ Primer Plus(第6版) 全书重点学习笔记

目录 第10章 对象和类 10.1 过程性编程和面向对象编程 10.2 抽象和类 10.2.1 类简介 10.2.2 实现类成员函数 10.3 类的构造函数和析构函数 10.3.1 声明和定义构造函数 10.3.2 使用构造函数 10.3.3 默认构造函数 10.3.4 析构函数 10.4 this指针 10.5 对象数组 10.6 …

[长安杯 2021学生组]baigei

Index 前言介绍漏洞 利用思路利用过程一.编写交互函数二.填充Tcache Bin三.释放Tcache Bin四.获取Libc地址五.Tcache Bin Attack六.完整EXP&#xff1a; 前言 最近有点迷茫&#xff0c;开始放松自己了。 心态还不是很对&#xff0c;需要继续调整。 介绍 本题是一题经典的堆题…

Java学习笔记:内部类,静态内部类,匿名内部类

​这是本人学习的总结&#xff0c;主要学习资料如下 疯狂Java讲义第三版&#xff0c;李刚编&#xff0c;电子工业出版社出版 目录 1、内部类1.1、内部类简介1.2、内部类与外部类的关系和区别&#xff1a;1.3、内部类的语法 2、 非静态内部类3、静态内部类4、匿名内部类 1、内部…

“链引擎”入驻案例 | 每天超过35万条存证上链,长安链支撑链上价值流动

引言 长安链“链引擎”计划&#xff08;Powered by Chainmaker&#xff09;(简称&#xff1a;PBC计划)是由长安链生态联盟发起的一项应用赋能计划&#xff0c;旨在以长安链技术体系为核心支撑&#xff0c;汇聚产业各方力量&#xff0c;为应用方提供技术、品牌、生态等支持&…