IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python爬虫系列之下载在线文档Excel(石墨) -> 正文阅读

[Python知识库]python爬虫系列之下载在线文档Excel(石墨)

一、简介

本文讲述使用python下载石墨在线文档中的Excel数据,下方有完整代码,方便食用。

  1. 思路

文档导出流程如下

Created with Rapha?l 2.3.0 点击导出 文档准备数据 数据准备完成? 出现下载excel文件的down_url yes no

使用抓包工具获取下载过程触发的接口,使用requests进行调用,即可完成下载。主要接口有三个,如下:获取文件名字接口、创建导出任务接口、查询任务进度接口。
这三个接口之间的关系:

  1. 提供在线文档地址
  2. 通过在线文档地址获取excel文件名
  3. 通过excel名字创建导出任务
  4. 通过创建任务的id,查询任务进度
  5. 任务进度100%时,会返回文件down_url

二、实现步骤

1. 数据准备

  • 提供石墨文档中excel文档地址唯一标识字段,以便进行下载,获取excel文档id
    document_id = Wr3DVRmBzVUdQkJQ
    石墨文档地址

  • cookie值获取,通过接口工具抓到的接口,获取cookie信息,首先需要进行登陆。这里我用的抓包工具为 fiddler
    cookie_value = ********
    cookie

2. 获取excel文件名接口

excel_name
获取文件名字接口,其中入参_为时间戳,调用该接口代码如下:

    def get_excel_name(self):
        """
        # 获取excel文件名
        :return:
        """
        timestamp = int(time() * 1000)
        excel_name_url = self.document_url + f'?_={timestamp}&collaboratorCount=true'
        res = requests.get(url=excel_name_url, headers=self.headers)
        if res.json()['name']:
            print("文件名获取成功")
        return res.json()['name']

3.创建导出任务

创建导出任务,一个必填字段name为excel文件名。通过get_excel_name()获取,file字段为document_id= Wr3DVRmBzVUdQkJQ后缀中获取。
创建导出任务接口如下图
在这里插入图片描述


    def export_excel_task(self):
        document_name = self.get_excel_name()
        bfb = urllib.parse.quote(str(document_name))  # 转为 url 编码
        document_id = str(self.document_url).split('/')[-1]
        export_url = self.document_url + f'/export?type=xlsx&file={document_id}&returnJson=1&name={bfb}&isAsync=1&timezoneOffset=-8'
        res = requests.get(url=export_url, headers=self.headers)

        data_dict = res.json()
        if data_dict['status'] == 0:
            print("导出任务id获取成功")
            return data_dict['data']['taskId']
        return "导出任务创建失败"

4. 查询进度进度,拿到文件下载地址

查询任务进度接口,在点击导出excel时会出现该接口信息,频繁调用该接口,当progress进度为100时,该接口返回值会出现file_url信息。progress


    def query_progess(self):
        taskId = self.export_excel_task()
        progress_url = self.document_url + f'/export/progress?taskId={taskId}'
        start_time = time()
        file_url = ''

        # 循环调用查询进度接口,直到进度为100,出现下载url
        while True:
            sleep(3)
            res = requests.get(url=progress_url, headers = self.headers)
            data = res.json()['data']
            progress = data['progress']
            if progress == 100:
                file_url = data['downloadUrl']
                break
            elif time() - start_time > 30:
                print("数据准备超时,请排查")
                break
        if file_url:
            print("excel文件下载地址获取成功")
        return file_url

5. 下载文件

石墨文档中该file_url会进行重定向,调用后通过返回值可以拿到真实的url
然后requests调用重定向后的url,就可以拿到文件流,写到excel文件中即可完成下载。

    def download_file(self, file_name):
        file_url = self.query_progess()
        if file_url:
            # self.headers['content-type'] = 'application/octet-stream'
            res = requests.get(url=file_url)
            sleep(2)
            real_url = res.url
            real_res = requests.get(url=real_url)
            with open(file_name, 'wb') as f:
                f.write(real_res.content)
            print('下载成功,文件名: ' + file_name)
        else:
            print("下载文件地址获取失败, 下载excel文件不成功")

三、完整代码

因文档中不能包含shimo地址,这里用截图放出来,代码中用到{shimo}的地方注意替换。

在这里插入图片描述

# -*- coding: UTF-8 -*-
"""
@Project :small-tools 
@File    :shimo.py
@Author  :silen
@Time    :2022/5/27 22:06
@Description : 
"""

import urllib.parse
from datetime import datetime
from time import time, sleep
import requests


class ShiMo():

    def __init__(self, document_id, cookie_value):
        # excel文档地址
        self.document_url = {shimo_url} + 'lizard-api/files/' + document_id

        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53',
            'Cookie': cookie_value,
            'Accept': 'application/nd.shimo.v2+json',
            'Accept-Encoding': 'gzip, deflate, br',
            'Referer': {shimo_url} + f'sheets/{document_id}',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
            'Host': {shimo_url},


        }

    def get_excel_name(self):
        """
        # 获取excel文件名
        :return:
        """
        timestamp = int(time() * 1000)
        excel_name_url = self.document_url + f'?_={timestamp}&collaboratorCount=true'
        res = requests.get(url=excel_name_url, headers=self.headers)
        if res.json()['name']:
            print("文件名获取成功")
        return res.json()['name']

    def export_excel_task(self):
        document_name = self.get_excel_name()
        bfb = urllib.parse.quote(str(document_name))  # 转为 url 编码
        document_id = str(self.document_url).split('/')[-1]
        export_url = self.document_url + f'/export?type=xlsx&file={document_id}&returnJson=1&name={bfb}&isAsync=1&timezoneOffset=-8'
        res = requests.get(url=export_url, headers=self.headers)

        data_dict = res.json()
        if data_dict['status'] == 0:
            print("导出任务id获取成功")
            return data_dict['data']['taskId']
        return "导出任务创建失败"

    def query_progess(self):
        taskId = self.export_excel_task()
        progress_url = self.document_url + f'/export/progress?taskId={taskId}'
        start_time = time()
        file_url = ''

        # 循环调用查询进度接口,直到进度为100,出现下载url
        while True:
            sleep(3)
            res = requests.get(url=progress_url, headers = self.headers)
            data = res.json()['data']
            progress = data['progress']
            if progress == 100:
                file_url = data['downloadUrl']
                break
            elif time() - start_time > 30:
                print("数据准备超时,请排查")
                break
        if file_url:
            print("excel文件下载地址获取成功")
        return file_url

    def download_file(self, file_name):
        file_url = self.query_progess()
        if file_url:
            # self.headers['content-type'] = 'application/octet-stream'
            res = requests.get(url=file_url)
            sleep(2)
            real_url = res.url
            real_res = requests.get(url=real_url)
            with open(file_name, 'wb') as f:
                f.write(real_res.content)
            print('下载成功,文件名: ' + file_name)
        else:
            print("下载文件地址获取失败, 下载excel文件不成功")

if __name__ == '__main__':
    cookie_value = '***'
    document_id = 'Wr3DVRmBzVUdQkJQ'
    shimo = ShiMo(document_id, cookie_value)
    # 文档名称
    name = shimo.get_excel_name()
    current_datetime = datetime.strftime(datetime.now(), '%Y_%m_%d_%H_%M_%S')
    file_name = f'{current_datetime + name}.xlsx'
    shimo.download_file(file_name)

四、效果演示

运行脚本截图:
result

成功下载的文档如下所示
在这里插入图片描述

如果我的文章对你有帮助,点个关注呗

如有疑问欢迎留言!

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-06-06 17:18:20  更:2022-06-06 17:18:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 15:52:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计