【新人推荐】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调用Orator ORM进行数据库操作

《Python调用OratorORM进行数据库操作》OratorORM是一个功能丰富且灵活的PythonORM库,旨在简化数据库操作,它支持多种数据库并提供了简洁且直观的API,下面我们就... 目录Orator ORM 主要特点安装使用示例总结Orator ORM 是一个功能丰富且灵活的 python O

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import

Python Jupyter Notebook导包报错问题及解决

《PythonJupyterNotebook导包报错问题及解决》在conda环境中安装包后,JupyterNotebook导入时出现ImportError,可能是由于包版本不对应或版本太高,解决方... 目录问题解决方法重新安装Jupyter NoteBook 更改Kernel总结问题在conda上安装了

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

Python安装时常见报错以及解决方案

《Python安装时常见报错以及解决方案》:本文主要介绍在安装Python、配置环境变量、使用pip以及运行Python脚本时常见的错误及其解决方案,文中介绍的非常详细,需要的朋友可以参考下... 目录一、安装 python 时常见报错及解决方案(一)安装包下载失败(二)权限不足二、配置环境变量时常见报错及

Python中顺序结构和循环结构示例代码

《Python中顺序结构和循环结构示例代码》:本文主要介绍Python中的条件语句和循环语句,条件语句用于根据条件执行不同的代码块,循环语句用于重复执行一段代码,文章还详细说明了range函数的使... 目录一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(