Web Spider NEX XX国际货币经纪 - PDF下载 提取关键词(二)

news2024/11/22 1:18:01

Web Spider NEX XX国际货币经纪 - PDF下载 & 解析


首先声明: 此次案例只为学习交流使用,切勿用于其他非法用途

文章目录

  • Web Spider NEX XX国际货币经纪 - PDF下载 & 解析
  • 前言
  • 一、任务说明
    • 1.PDF下载
    • 2.PDF解析提取关键词数据
  • 二、Pip模块安装
  • 三、网站分析
  • 四、核心代码注释
    • 1.创建2019年1月1日-至今的时间字符串,存入列表中
    • 2.pdf下载
    • 3.pdf读取解析
  • 五、运行结果
  • 六、示例代码
  • 总结


前言

目标网站:https://www.cfets-nex.com.cn/
在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、任务说明

1.PDF下载

提示:下载2019年1月1日-至今的"银行间货币市场"PDF文件
下图网址:https://www.cfets-nex.com.cn/Market/marketOverview/dailyReview
在这里插入图片描述
在这里插入图片描述

2.PDF解析提取关键词数据

提取关键词数据说明

  • 提取下图标红框处位置的内容,如果不存在则赋值"None";
  • 红框处1:以"今日资金面"开头,句号(。)结束;
  • 红框处2:以"资金面情绪指数"开头,换行(\n)结束;
  • 以上为主要的提取部分,有些开头的关键词不同,需要另外写点匹配规则,参考案例;

提示:如果有更好的提取方式可以在评论处留言或者私信我,让我们在IT社区平台共同进步,感谢!
在这里插入图片描述

二、Pip模块安装

镜像地址

  • 清华:https://pypi.tuna.tsinghua.edu.cn/simple
  • 阿里云:http://mirrors.aliyun.com/pypi/simple/
  • 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
  • 华中理工大学:http://pypi.hustunique.com/
  • 山东理工大学:http://pypi.sdutlinux.org/
  • 豆瓣:http://pypi.douban.com/simple/

案例使用到的模块以及对应版本

  • pandas==1.1.3
  • PyPDF2==2.12.1
  • requests==2.27.0

pip指定模块安装:pip install 模块名 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip指定requirements.txt文件安装:pip install -i https://pypi.doubanio.com/simple/ -r requirements.txt

三、网站分析

1、打开链接,可以发现一个规律,每天收盘日评的网站链接是由相应的日期字符串组成;
链接后面的时间字符串为:2022/12/15
在这里插入图片描述
链接后面的时间字符串为:2022/12/16
在这里插入图片描述2、按F12进入开发者模式,可以直接看到PDF的链接,直接请求网站就完事了;在这里插入图片描述
标签a的href:/Cms_Data/Contents/Site2019/Folders/Daily/~contents/XBVJCVJ4Q8QG9A9L/MM.pdf
根据经验前缀需要加上:https://www.cfets-nex.com.cn
组合后可以直接打开PDF:https://www.cfets-nex.com.cn/Cms_Data/Contents/Site2019/Folders/Daily/~contents/XBVJCVJ4Q8QG9A9L/MM.pdf
在这里插入图片描述

四、核心代码注释

1.创建2019年1月1日-至今的时间字符串,存入列表中

import datetime
start_string = '2019-01-01'
def create_date_list():
    start_date = datetime.datetime.strptime(start_string , "%Y-%m-%d")  # 将指定的字符串转为时间格式
    now_date = (datetime.datetime.now()).strftime("%Y-%m-%d")  # 获取当前的时间
    date_string_list = list()
    i = 0
    while True:
        date_i = (start_date + datetime.timedelta(days=i)).strftime('%Y-%m-%d')
        date_string = str(date_i).replace('-', '/')
        print("创建时间字符串 - 存储成功:", date_string)
        date_string_list.append(date_string)
        if date_i < now_date:
            i += 1
        else:
            break
    return date_string_list

2.pdf下载

import requests
headers = {
	'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
}
def pdf_download():
    file_path = "result.pdf"
    pdf_url = 'https://xxxx.pdf'
    response = requests.get(url=pdf_url, headers=headers, timeout=5)
    with open(file_path, 'wb') as fis:
        for chunk in response.iter_content(chunk_size=1000):
            fis.write(chunk)
            fis.flush()
        print(f'下载完成:{file_path}')
    return True

3.pdf读取解析

import PyPDF2
pdffile = open(file=file_path, mode='rb')  # 读取pdf文件;
pdfreader = PyPDF2.PdfFileReader(pdffile)
pdf_content = ''
for i in range(pdfreader.numPages):  # 获取pdf的总页数;
    page_content = pdfreader.getPage(i)  # 获取第i页的对象;
    pdf_content += page_content.extractText()  # 提取第i页的对象内容,字符串类型;
parse(pdf_content) # 自定义一个解析内容的方法,根据自己的需求提取相应的内容;

五、运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

六、示例代码

import os
import re
import time
import PyPDF2
import datetime
import requests
import pandas as pd
from requests import exceptions as request_exceptions


class SHICEconomy(object):
    def __init__(self):
        self.headers = {
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/95.0.4638.69 Safari/537.36'
        }
        self.start_string = '2019-01-01'
        self.resource_path = 'resource'
        self.result_file_path = 'result.csv'

    def create_date_list(self):
        start_date = datetime.datetime.strptime(self.start_string, "%Y-%m-%d")  # 将指定的字符串转为时间格式
        now_date = (datetime.datetime.now()).strftime("%Y-%m-%d")  # 获取当前的时间
        date_string_list = list()
        i = 0
        while True:
            date_i = (start_date + datetime.timedelta(days=i)).strftime('%Y-%m-%d')
            date_string = str(date_i).replace('-', '/')
            print("创建时间字符串 - 存储成功:", date_string)
            date_string_list.append(date_string)
            if date_i < now_date:
                i += 1
            else:
                break
        return date_string_list

    def request_server(self, url):
        request_count = 0
        request_total = 3
        result = {'status': False}
        while request_count < request_total:
            try:
                response = requests.get(url=url, headers=self.headers, timeout=5)
                result = {'status': True, 'response': response}
                break
            except request_exceptions.ConnectTimeout:
                print(f'{url} - 请求失败 ConnectTimeout!\n', end='')
            except request_exceptions.RequestException:
                print(f'{url} - 请求失败 RequestException!\n', end='')
            request_count += 1
            time.sleep(1)
        return result

    def pdf_download(self, file_path, pdf_url):
        """ pdf下载 """
        download_result = {'status': False}
        request_result = self.request_server(url=pdf_url)
        if request_result['status'] is False:
            return download_result
        response = request_result['response']
        with open(file_path, 'wb') as fis:
            for chunk in response.iter_content(chunk_size=1000):
                fis.write(chunk)
                fis.flush()
            print(f'下载完成:{file_path}')
        download_result = {'status': True}
        return download_result

    def read_finished_download_path(self):
        finished_download_pdf_list = list()
        for path in os.listdir(self.resource_path):
            file_path = f'{self.resource_path}/{path}'
            finished_download_pdf_list.append(file_path)
        return finished_download_pdf_list

    def pdf_download_controller(self, date_string_list=[]):
        """ pdf下载控制 """
        finished_download_pdf_list = self.read_finished_download_path()  # 获取已经下载的pdf地址
        for date_string in date_string_list:
            file_path = f"{self.resource_path}/{date_string.replace('/', '-')}.pdf"  # 拼接下载文件路径
            if file_path in finished_download_pdf_list:
                print(f"已下载:{file_path}")
                continue
            url = f'https://www.cfets-nex.com.cn/Market/marketOverview/dailyReview?Date={date_string}'
            request_result = self.request_server(url=url)
            if request_result['status'] is False:  # pdf请求状态
                print(f"请求失败:{url}")
                continue
            html_text = request_result['response'].text
            pdf_re = re.search(pattern="银行间货币市场.*?href='(.*?)'", string=html_text, flags=re.S)  # 匹配pdf下载地址
            pdf_prefix = 'https://www.cfets-nex.com.cn'
            if pdf_re is None:
                print(f"当天无数据(或还未发布数据):{url}")
                continue
            else:
                pdf_suffix = pdf_re.group(1)
            pdf_url = pdf_prefix + pdf_suffix
            download_result = self.pdf_download(file_path, pdf_url)  # 下载pdf
            if download_result['status'] is False:  # pdf下载状态
                print(f"下载失败:{url}")
                continue
            finished_download_pdf_list.append(file_path)  # 存储下载成功之后的文件地址
        return finished_download_pdf_list

    def pdf_parse(self, pdf_path_list):
        for file_path in pdf_path_list:
            column1_content = file_path.split('/')[-1].split('.pdf')[0]
            try:
                pdffile = open(file=file_path, mode='rb')  # 读取pdf文件
                pdfreader = PyPDF2.PdfFileReader(pdffile)
            except Exception:
                content = f"{column1_content},None,None\n"
                self.csv_save(content)
                print(f"{file_path} - PDF读取异常")
                continue
            pdf_content = ''
            for i in range(pdfreader.numPages):  # 获取pdf的总页数
                page_content = pdfreader.getPage(i)  # 获取第i页的对象
                pdf_content += page_content.extractText()  # 提取第i页的对象内容
            column2_1_re = re.search(pattern='今.{0,1}资金面(.*?)。', string=pdf_content, flags=re.S)
            column2_2_re = re.search(pattern='早盘资金面(.*?)。', string=pdf_content, flags=re.S)
            if column2_1_re:
                column2_content = f'{column2_1_re.group()}'.replace('\n', '').replace(',', ',')
            elif column2_2_re:
                column2_content = f'{column2_2_re.group()}'.replace('\n', '').replace(',', ',')
            else:
                column2_content = 'None'
            column3_1_re = re.search(pattern='资金面情绪指数(.*?)\n', string=pdf_content, flags=re.S)
            column3_2_re = re.search(pattern='今日全天的资金面指数(.*?)\n', string=pdf_content, flags=re.S)
            column3_3_re = re.search(pattern='今日资金.{0,1}情绪指数(.*?)\n', string=pdf_content, flags=re.S)
            column3_4_re = re.search(pattern='情绪指数(.*?)\n', string=pdf_content, flags=re.S)
            if column3_1_re:
                column3_content = f'资金面情绪指数{column3_1_re.group(1)}'.replace('\n', '').replace(',', ',')
            elif column3_2_re:
                column3_content = f'今日全天的资金面指数{column3_2_re.group(1)}'.replace('\n', '').replace(',', ',')
            elif column3_3_re:
                column3_content = f'{column3_3_re.group()}'.replace('\n', '').replace(',', ',')
            elif column3_4_re:
                column3_content = f'{column3_4_re.group()}'.replace('\n', '').replace(',', ',')
            else:
                column3_content = 'None'
            content = f"{column1_content},{column2_content},{column3_content}\n"
            self.csv_save(content)
            print("写入成功:", column1_content, column2_content, column3_content)
        return True

    def create_file(self):
        if os.path.exists(self.resource_path) is False:
            os.mkdir(self.resource_path)
        with open(file=self.result_file_path, mode='w', encoding='utf-8') as fis:
            fis.write('日期,今日资金面,资金面情绪指数\n')

    def csv_save(self, content):
        with open(file=self.result_file_path, mode='a+', encoding='utf-8') as fis:
            fis.write(content)

    def csv_save_as_xlsx(self):
        """ 读取csv文件将结果写入xlsx """
        filename_prefix = os.path.splitext(self.result_file_path)[0]  # 切割文件路径以及后缀
        df = pd.read_csv(self.result_file_path, encoding='utf-8', dtype='object')
        df.to_excel(f"{filename_prefix}.xlsx", index=False)
        print("csv 转 xlsx 成功!")

    def runs(self):
        self.create_file()
        date_string_list = self.create_date_list()
        pdf_path_list = self.pdf_download_controller(date_string_list)
        self.pdf_parse(pdf_path_list)
        self.csv_save_as_xlsx()


if __name__ == '__main__':
    SHICEconomy().runs()


总结

此次案例只为学习交流使用,若有侵犯网站利益的地方请及时联系我下架该博文;
在此我抛出两个问题,欢迎在评论区讨论或者私信我,感谢赐教!:
问题1:如何通过requests请求pdf链接拿到二进制内容后直接使用pdf解析模块进行解析;
问题2:如何以更好的方式提取pdf的关键词内容;

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

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

相关文章

【解决】Unity Player Log 自生成造成磁盘满占用率问题

开发平台&#xff1a;Unity 2020 编程平台&#xff1a;Visual Studio 2022 编程语言&#xff1a;CSharp   问题描述 Unity 工程完成打包与发布过程后&#xff0c;在运行时生成大量 Player Log 的日志文件导致其所在盘占用率满额问题。通常情况下&#xff0c;这类日志文件信息…

微信小程序开发—入门到跑路(三)

3、微信小程序第三天 1、学习目标 知识点名称知识点内容难度系数要求程度页面导航声明式导航、编程式导航、导航传参3星掌握页面事件下拉刷新、上拉触底、上拉触底案例、自定义编译模式3星掌握生命周期生命周期分类、应用生命周期、页面生命周期3星掌握wxs学习认识wxs及应用场…

百度工程师带你探秘C++内存管理(ptmalloc篇)

作者 | daydreamer 前篇《探秘C内存管理&#xff08;理论篇&#xff09;》主要介绍了Linux C程序内存管理的理论基础&#xff0c;本文作为系列文章《探秘C内存管理》的第二篇&#xff0c;将会探讨经典内存管理器ptmalloc如何管理C程序的内存。借助剖析ptmalloc解决问题的着重点…

攻防世界-easyphp

题目 访问url进入靶场&#xff0c;阅读php代码 <?php highlight_file(__FILE__); $key1 0;//值赋值 $key2 0;$a $_GET[a];//get方法获取值 $b $_GET[b];if(isset($a) && intval($a) > 6000000 && strlen($a) < 3){ //a的值需要大于 6000000&…

Python:如何使用正则表达式快速处理字符串

文章目录前言一、正则表达式1、元字符详解2、等价方法&#xff08;速记&#xff09;二、常用的表达式1、常用的正则表达式2、先行断言和后行断言三、Python匹配函数1、Match函数2、Search函数3、Findall函数四、regex101网站推荐前言 1、正则表达式是对字符串操作的一种逻辑公…

Android Studio使用Mob实现短信验证功能遇到的问题解决

一、Mob短信验证 全球领先的数据智能科技平台-MobTech袤博解决 进行注册登入 登入成功后&#xff0c;点击开发者服务中的短信验证&#xff0c;进入开发者平台 填好信息创建成功后显示下图&#xff0c;可以看到对应信息如下&#xff08;注意记住AppKey和AppSecretKey&#xff…

怎样让Odoo 16自动根据销售订单创建采购订单或生产订单

我们在销售产品时通常只处理销售过程&#xff0c;但是&#xff0c;在根据消费者的要求交付给消费者之前&#xff0c;产品会必须有库存。这时候&#xff0c;货物要么从车间「生产」&#xff0c;要么从供应商「采购」。当销售订单确认但商品缺货时&#xff0c;我们偶尔不得不先获…

vite.config.ts--服务器、简化导入写法、element-plues按需导入的配置

vite.config.ts--服务器、简化导入写法、element-plues按需导入的配置说明一、服务器server二、简化导入写法三、element-plus按需导入完说明 本教程适用于vite创建的前端项目服务器server简化导入写法element-plus按需导入 一、服务器server import { defineConfig } from …

MFC界面控件BCGControlBar v33.3 - 编辑控件功能升级

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版和BCGSuite for MFC v33.3已正式发布了&#xff0c;该版本包含了增强的Ribbon自定义、新的…

[附源码]计算机毕业设计Python点餐系统(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

智能座舱进入多元化交互时代,本土芯片厂商如何领跑?

“智能座舱市场正在进入一个全新的发展阶段。”芯驰科技资深产品市场总监金辉在2022高工智能汽车年会上表示&#xff0c;智能座舱已经进入了多屏互动、多模交互、多人交互等多元化交互时代。 芯驰科技资深产品市场总监金辉 作为未来的“第三生活空间”以及主机厂差异化竞争的焦…

【问答篇】Java 线程篇 面试题(一)

每天进步一点~ (ps: 文章内容及图片出处来自本人公众号~) 01、问&#xff1a;请谈谈你对并发编程优缺点的认识与理解 ~ 答&#xff1a; 优点&#xff1a;充分利用多核CPU的计算能力&#xff0c;通过并发编程的形式将多核CPU的计算能力发挥到极致&#xff0c;性能得到提升。 …

【Java编程】MVC框架和经典三层结构

MVC框架和经典三层结构1.MVC框架 JSP&#xff0c;全称 Java Server Pages&#xff0c;中文名是 Java 服务器页面&#xff0c;其实是一种以 Java 为主的跨平台 Web 开发语言。JSP 文件由传统网页 HTML 文件插入 Java 程序段所形成&#xff0c;实现了 HTML 语法的 Java 扩张。在…

一篇文章了解 Apache Druid

前言 本文隶属于专栏《大数据技术体系》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见大数据技术体系 概述 Apache Druid 是一个实时分析型数据库&#xf…

图文结合带你搞懂MySQL日志之Error Log(错误日志)

GreatSQL社区原创内容未经授权不得随意使用&#xff0c;转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本&#xff0c;使用上与MySQL一致。作者&#xff1a;KAiTO文章来源&#xff1a;社区原创 往期回顾&#xff1a; 图文结合带你搞懂MySQL日志之Redo Log(重做日志)…

[附源码]计算机毕业设计Python的云网盘设计(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

极智AI | 谈谈昇腾CANN量化

欢迎关注我的公众号 [极智视界]&#xff0c;获取我的更多笔记分享 大家好&#xff0c;我是极智视界&#xff0c;本文介绍一下 谈谈昇腾CANN量化。 昇腾CANN的量化体现在AMCT工具&#xff0c;也即模型压缩工具&#xff0c;后面再来说AMCT&#xff0c;这篇先聊一下昇腾CANN的量…

SpringBoot学习小结之滑块验证码生成库tianai-captcha

文章目录前言一、后端springboot1.1 yml 配置1.2 跨域配置1.3 资源配置1.4 Controller二、前端jquery2.1 通用代码2.2 滑动验证码2.3 旋转验证码2.4 滑动还原验证码2.5 文字点选验证码三、源码探秘和总结3.1 前端代码3.2 后端代码3.3 总结参考前言 最近发现一个有趣的 Java 验…

Java根据ip地址获取归属地

最近&#xff0c;各大平台都新增了评论区显示发言者ip归属地的功能&#xff0c;例如哔哩哔哩&#xff0c;微博&#xff0c;知乎等等。 下面&#xff0c;我就来讲讲&#xff0c;Java 中是如何获取 IP 属地的&#xff0c;主要分为以下几步 通过 HttpServletRequest 对象&#xf…

JVM监控及诊断工具-GUI

1. 工具概述 使用上一章命令行工具或组合能帮您获取目标Java应用性能相关的基础信息&#xff0c;但它们存在下列局限: 1)无法获取方法级别的分析数据&#xff0c;如方法间的调用关系、各方法的调用次数和调用时间 等&#xff08;这对定位应用性能瓶颈至关重要&#xff09;。 2…