【新人推荐】Python爬取巨潮资讯网指定PDF

2023-11-03 14:50

本文主要是介绍【新人推荐】Python爬取巨潮资讯网指定PDF,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、项目分析
    • 1. 前期准备
    • 2. 代码整体思路
  • 二、快速上手
    • 1. data.xlsx文件整理
    • 2.初始股票信息填充
    • 3.指定股票筛选
    • 4.获取指定股票页面数
    • 5.获取指定股票PDF的url
    • 6.下载指定的PDF
  • 总结


前言

由于会计、金融等毕业论文数据需要爬取数据,这里教大家怎么批量简单爬取巨潮咨询网指定的PDF。该例子为获取对应股票对应年份带有“董事会”与“决议会议”的PDF。


一、项目分析

1. 前期准备

  1. 得到由stata整合国泰安下载的“data.xlsx”,如下所示:
    data.xlsx
  2. 该代码例子为获取对应股票对应年份带有“董事会”与“决议会议”的PDF。

2. 代码整体思路

  1. data.xlsx文件整理
  2. 初始股票信息填充
  3. 指定股票筛选
  4. 获取指定股票页面数
  5. 获取指定股票PDF的url
  6. 下载指定PDF

二、快速上手

1. data.xlsx文件整理

代码如下:

import requests
from bs4 import BeautifulSoup
import pandas as pd
import os
from urllib.parse import urljoin
import json
import math
import xlwt
import xlrd
import time# 读取Excel文件
df = pd.read_excel("D:\\MyCoding\\pachong_JuChao\\data.xlsx")# 将code由int型转为string型,填充0,补齐6位
df["code"] = df["code"].apply(lambda x: str(x).zfill(6))# 使用groupby将相同的id分组,并将year列合并为一个years列
df["years"] = df.groupby("code")["year"].transform(lambda x: ",".join(x.astype(str)))# 删除原来的year列
df = df.drop("year", axis=1)# 去重
df = df.drop_duplicates()# 重新排列列的顺序,如果需要的话
df = df[["code", "shortname", "years"]]# 保存到新的Excel文件
df.to_excel("D:\\MyCoding\\pachong_JuChao\\1_data_initial.xlsx", index=False)# 由于一些公司中途改名,可能存在相同code,但是shortname不一致的情况,这个情景没有判断。
# 在1_统计年份.py中有函数解决

2.初始股票信息填充

代码如下:

import requests
from bs4 import BeautifulSoup
import pandas as pd
import os
from urllib.parse import urljoin
import json
import math
import xlwt
import xlrd
import time# 获取股票信息
url = "http://www.cninfo.com.cn/new/data/szse_stock.json"
ret = requests.get(url=url)
ret = ret.content
stock_list = json.loads(ret)["stockList"]# 只保留A股
stock_list_new = []
for stock in stock_list:if stock["category"] == "A股":stock_list_new.append(stock)# 添加column和plate信息,后续需要用到
i = 0
for stock in stock_list_new:if stock["code"][0] == "0" or stock["code"][0] == "3":stock_list_new[i]["column"] = "szse"stock_list_new[i]["plate"] = "sz"else:stock_list_new[i]["column"] = "sse"stock_list_new[i]["plate"] = "sh"i = i + 1# 保存到data_all.xlsx文件中
# 创建一个DataFrame
df = pd.DataFrame(stock_list_new)# 将DataFrame写入Excel文件
output_file = "D:\\MyCoding\\pachong_JuChao\\2_data_all.xlsx"
df.to_excel(output_file, index=False)# 需要注意,此时的code是文本类型,这样子才会是000001,而不是1

3.指定股票筛选

代码如下:

import requests
from bs4 import BeautifulSoup
import pandas as pd
import os
from urllib.parse import urljoin
import json
import math
import xlwt
import xlrd
import time# 读取两个Excel文件
data_all = pd.read_excel("D:\\MyCoding\\pachong_JuChao\\2_data_all.xlsx")
data_initial = pd.read_excel("D:\\MyCoding\\pachong_JuChao\\1_data_initial.xlsx")# 将data_initial中的years数据合并到data_all
data_all = data_all.merge(data_initial[["code", "years"]], on="code", how="left")# 删除在data_all中没有出现在data_initial中的行
data_all = data_all.dropna(subset=["years"])# 将code由int型转为string型,填充0,补齐6位
data_all["code"] = data_all["code"].apply(lambda x: str(x).zfill(6))# 保存到新的Excel文件
data_all.to_excel("D:\\MyCoding\\pachong_JuChao\\3_data_merged.xlsx", index=False)

4.获取指定股票页面数

代码如下

import requests
from bs4 import BeautifulSoup
import pandas as pd
import os
from urllib.parse import urljoin
import json
import math
import xlwt
import xlrd
import time# 从inputout.xls中过滤所有A股信息,保存到stock_list_new列表中
df1 = pd.read_excel("D:\\MyCoding\\pachong_JuChao\\3_data_merged.xlsx")
df1["code"] = df1["code"].apply(lambda x: str(x).zfill(6))
stock_list = df1.values.tolist()
stock_list_new = []
for stock in stock_list:if stock[2] == "A股":stock_list_new.append(stock) # 准备创建一个新的Excel,Excel中创建了一个叫“股票信息”的sheet
# sheet中的第一行列表如下所示
# code pinyin category orgId zwjc column plate years pages
w = xlwt.Workbook()
ws = w.add_sheet("股票信息")
title_list = ["code","pinyin","category","orgId","zwjc","column","plate","years","pages",
]
j = 0
for title in title_list:ws.write(0, j, title)j = j + 1# 获取股票公告页数
url = "http://www.cninfo.com.cn/new/hisAnnouncement/query"
i = 0
for stock in stock_list_new:data = {"stock": str(stock[0]) + "," + str(stock[3]),"tabName": "fulltext","pageSize": 30,"pageNum": 1,"column": stock[5],"plate": stock[6],"isHLtitle": "true",}# print(data)ret = requests.post(url=url, data=data)if ret.status_code == 200:ret = ret.contentret = str(ret, encoding="utf-8")total_ann = json.loads(ret)["totalAnnouncement"]# stock_list_new[i]["pages"] = math.ceil(total_ann / 30)stock = stock_list_new[i]stock.append(math.ceil(total_ann / 30))  # 这会将新元素添加到列表的末尾print(f"成功获取第{i}个股票页数!")i = i + 1content_list = [stock[0],stock[1],stock[2],stock[3],stock[4],stock[5],stock[6],stock[7],stock[8],]j = 0for content in content_list:ws.write(i, j, content)j = j + 1# 每得到10支股票信息变保持一次xls文件,防止意外中断时,xls文件未保存而丢失if i % 10 == 0:w.save("D:\\MyCoding\\pachong_JuChao\\4_data_pages.xlsx")print(f"成功保存第{i}个股票信息!")# 在每次请求后暂停运行,暂停1秒,防止被反爬虫机制检测出来,该机制虽然慢,但是不会被发现time.sleep(1)else:breakif i % 10 != 0:w.save("D:\\MyCoding\\pachong_JuChao\\4_data_pages.xlsx")print("成功保存所有股票信息!")

5.获取指定股票PDF的url

代码如下

import requests
from bs4 import BeautifulSoup
import pandas as pd
import os
from urllib.parse import urljoin
import json
import math
import xlwt
import xlrd
import time
import redef get_announcements(stock):url = "http://www.cninfo.com.cn/new/hisAnnouncement/query"name = stock["code"]w = xlwt.Workbook()ws = w.add_sheet(name)title_list = ["secCode", "secName", "announcementTitle", "adjunctUrl", "columnId"]j = 0for title in title_list:ws.write(0, j, title)j += 1i = 1count = 1years = stock["years"].split(",")  # 提取年份信息,生成列表for page in range(1, int(stock["pages"]) + 1):data = {"stock": stock["code"] + "," + stock["orgId"],"tabName": "fulltext","pageSize": 30,"pageNum": page,"column": stock["column"],"plate": stock["plate"],"isHLtitle": "true",}hasValue = 0count = count + 1while True:try:ret = requests.post(url=url, data=data)ret.raise_for_status()  # 抛出异常以处理请求错误ret = ret.contentret = str(ret, encoding="utf-8")if not ret:print("响应内容为空")breakann_list = json.loads(ret)["announcements"]for ann in ann_list:title = ann["announcementTitle"]urlyear = ann["adjunctUrl"]"""if ("董事会" in titleand "决议公告" in titleand any("/" + year + "-" in urlyear for year in years)):"""keyword_pattern = re.compile(r"(董事会.*决议的公告|董事会.*会议决议)")if keyword_pattern.search(title) and any("/" + year + "-" in urlyear for year in years):content_list = [ann["secCode"],ann["secName"],ann["announcementTitle"],ann["adjunctUrl"],ann["columnId"],]hasValue = 1j = 0for content in content_list:ws.write(i, j, content)j += 1i += 1if hasValue == 1:# print(f"成功写入{name}!")w.save(f"D:\\MyCoding\\pachong_JuChao\\url\\{name}.xlsx")break  # 如果成功写入,跳出重试循环except requests.exceptions.RequestException as e:print(f"请求失败,正在重试 {name},错误信息: {e}")time.sleep(1)  # 等待一段时间后重试if count % 5 == 0:time.sleep(1)# 读入excel文件,获取股票信息
excel_file = "D:\\MyCoding\\pachong_JuChao\\4_data_pages.xlsx"
w = xlrd.open_workbook(excel_file)
ws = w.sheet_by_name("股票信息")
nor = ws.nrowsstock_list = []
for i in range(1, nor):dict = {}for j in range(ws.ncols):title = ws.cell_value(0, j)value = ws.cell_value(i, j)dict[title] = valuestock_list.append(dict)# 遍历股票信息并获取公告信息
for stock in stock_list:get_announcements(stock)

6.下载指定的PDF

代码如下

import requests
from bs4 import BeautifulSoup
import pandas as pd
import os
from urllib.parse import urljoin
import json
import math
import xlwt
import xlrd
import time
import os
import xlrd
from urllib.parse import quote
from urllib.request import urlretrieve
import time
import sys# 确保PDF文件夹存在
pdf_folder = "D:\\MyCoding\\pachong_JuChao\\PDF"
if not os.path.exists(pdf_folder):os.mkdir(pdf_folder)folder_path = "D:\\MyCoding\\pachong_JuChao\\url"  # 指定xls或xlsx文件所在的目录xls_files = [f for f in os.listdir(folder_path) if f.endswith(".xlsx") or f.endswith(".xls")
]for xls_file in xls_files:w = xlrd.open_workbook(os.path.join(folder_path, xls_file))ws = w.sheet_by_name(xls_file.replace(".xlsx", "").replace(".xls", ""))nor = ws.nrowsnol = ws.ncolsfile_count = 0  # 初始化计数器for i in range(1, nor):url = "http://static.cninfo.com.cn/" + ws.cell_value(i, 3)name = ws.cell_value(i, 0) + "-" + ws.cell_value(i, 3).split("/")[-1]pdf_path = os.path.join(pdf_folder, name)  # PDF文件保存的完整路径while True:  # 重试直到成功try:urlretrieve(url, filename=pdf_path)# print(f"Successfully downloaded {name}!")file_count += 1  # 每次成功下载文件后,计数器加1break  # 下载成功后退出循环except Exception as e:print(f"An error occurred while downloading {name}: ", e)time.sleep(1)  # 下载失败后暂停1秒继续尝试# 检查计数器if file_count == 20:time.sleep(1)  # 如果已经下载了20个文件,暂停1秒file_count = 0  # 重置计数器

总结

至此,所有的PDF都已下载到PDF目录下,请读者依据自己需要自行修改文件保存路径以及筛选条件

这篇关于【新人推荐】Python爬取巨潮资讯网指定PDF的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/338914

相关文章

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Python Websockets库的使用指南

《PythonWebsockets库的使用指南》pythonwebsockets库是一个用于创建WebSocket服务器和客户端的Python库,它提供了一种简单的方式来实现实时通信,支持异步和同步... 目录一、WebSocket 简介二、python 的 websockets 库安装三、完整代码示例1.

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

Python使用自带的base64库进行base64编码和解码

《Python使用自带的base64库进行base64编码和解码》在Python中,处理数据的编码和解码是数据传输和存储中非常普遍的需求,其中,Base64是一种常用的编码方案,本文我将详细介绍如何使... 目录引言使用python的base64库进行编码和解码编码函数解码函数Base64编码的应用场景注意

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis