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

news/2024/7/19 12:30:33 标签: 爬虫, python, flask

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

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

python">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’}

python">    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作为参数。

python">    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示例:

python">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。输出:

python"><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数据。

python">    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字符串后,后台接口才能接收,否则会报错。应该和接口写法有关,没有深究。

python">    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 加载分页列表

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

python">    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 方法调用

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

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


http://www.niftyadmin.cn/n/222964.html

相关文章

webGL-类型化数组

什么是类型化数组&#xff1f; 类型化数组是一个种特殊数据类型的数组&#xff0c;可在内存中存储和操作二进制数据。 类型化数组与常规数组&#xff08;Array&#xff09;的区别、性能对比。 连续的内存&#xff1a;类型化数组是一个连续的内存&#xff0c;这使得在内存中操…

暄桐好作业之《临王蒙〈具区林屋图〉》

告诉大家一个好消息“暄桐好作业”栏目上新啦~除了与大家分享正在进行的课程好作业&#xff0c;还会向大家展示来自暄桐学长学姐们的优秀国画作品。希望正在上课的暄桐同学们能够从学长学姐的分享以及暄桐教室专业助教的点评中&#xff0c;从中获益并获得力量&#xff0c;继续努…

CollapsingMergeTree

CollapsingMergeTree就是⼀种通过以增代删的思路&#xff0c;⽀持⾏级数据修改和删除的表引擎。它通过定义⼀个sign标记位字段&#xff0c;记录数据⾏ 的状态。 如果sign标记为1&#xff0c;则表示这是⼀⾏有效的数据&#xff1b; 如果sign标记为-1&#xff0c;则表示这⾏数据…

spring boot3.0新特性Http客户端远程调用

1、安装依赖 <!-- For reactive support --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency>2、项目结构 3、新建配置类WebConfig package com.exa…

Java开发 - SpringCache初体验

前言 早些时候,博主介绍过Redis的使用:Java开发 - Redis初体验,Redie是基于缓存的一项技术,对于Redis,博主此处不再赘述,不了解的可以去看这篇文章,但Redis缓存并不是顶峰,本文要讲的内容就是Redis的辅助工具:SpringCache——的使用。有了SpringCache,Redis便可如虎…

银行数字化转型导师坚鹏:商业银行零售业务数字化风控

商业银行零售业务数字化风控课程背景&#xff1a; 数字化背景下&#xff0c;很多银行存在以下问题&#xff1a; 不清楚商业银行数字化风控发展现状&#xff1f; 不清楚对公业务数字化风控工作如何开展&#xff1f; 不知道零售业务数字化风控工作如何开展&#xff1f; 课程特…

ARM架构与X86操作系统的区别有什么不同呢?

在了解两个不同架构系统之前&#xff0c;首先了解什么是ARM架构&#xff0c;什么是X86架构呢&#xff1f; ARM架构&#xff1a;在很久之前被称为进阶精简指令集机器&#xff0c;是一个32位精简指令集处理器架构&#xff0c;因为在很多嵌入式系统设计当中被广泛使用&#xff0c;…

LINUX系统SSH连接安装Matlab、添加环境变量、后台运行Matlab脚本

安装Matlab 使用MobaXterm软件SSH连接远程服务器&#xff0c;输入IP、用户名和端口号&#xff1a; 输入密码进入&#xff08;密码不显示&#xff09; 网上找一个Matlab安装包&#xff08;iso镜像&#xff09;上传进服务器端&#xff0c;或者直接使用wget指令在服务器端下载镜…