【python爬虫】从东方财富网批量下载年报pdf

大数据分析的前置数据处理部分。

参考了网上的一些爬虫进行了修改,主要是增加了批量下载的功能,通过读取excel来实现批量。

需要在目录文件夹中的excel表中存放需要查询的公司代码及名称,如下图格式。

具体的实现代码:

# 导入pandas工具库
import pandas as pd
#实现系统功能
import os
#读取excel
import xlrd
#写入excel
import xlwt
#解析json
import json
#获取网页内容
import requests
#数学函数
import math
#正则表达
import re
#下载网络文件到本地
from urllib.request import urlretrieve

# 从以下url中提取所需要的上市企业数据源信息
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"]
len(stock_list)
# 检查数据格式案例
stock_list[:2]


//这一段是参考代码中的,在此处应该没用,懒得删,怕出bug
def export_excel(export):
   #将字典列表转换为DataFrame
   pf = pd.DataFrame(export)
   #指定字段顺序
   order = ['orgId','category','code','pinyin','zwjc']
   pf = pf[order]
   #将列名替换为中文
   columns_map = {
      'orgId':'orgId(原始ID)',
      'category':'category(股市类型)',
      'code':'code(代码)',
      'pinyin':'pinyin(拼音)',
      'zwjc':'zwjc()'
   }
   pf.rename(columns = columns_map,inplace = True)
   #指定生成的Excel表格名称
   file_path = pd.ExcelWriter('code_list.xlsx')
   #替换空单元格
   pf.fillna(' ',inplace = True)
   #输出
   pf.to_excel(file_path,encoding = 'utf-8',index = False)
   #保存表格
   file_path.save()

if __name__ == '__main__':
    #将分析完成的列表导出为excel表格
    export_excel(stock_list)

# 提取stock_list中的code与orgId,遍历生成独立字典
code_dic = {(it['code']):it['orgId'] for it in stock_list}
print(code_dic)
len(code_dic)
//一直到这里


# 定义一个读取xls文件数据并转为列表的类
class excel_read:
    #     定义一个读取函数,其中excel_path为待爬取企业清单的路径,需自定义路径
    def __init__(self, excel_path=r"E:\python\***.xls", encoding='utf-8', index=0):
        #       获取文本对象
        self.data = xlrd.open_workbook(excel_path)
        #       根据index获取某个sheet
        self.table = self.data.sheets()[index]
        #       获取当前sheet页面的总行数,把每一行数据作为list放到 list
        self.rows = self.table.nrows

    def get_data(self):
        result = []
        for i in range(self.rows):
            #           获取每一行的数据
            col = self.table.row_values(i)
            print(col)
            result.append(col)
        print(result)
        return result


# 运用函数生成待爬取企业的code_list
code_list = []
code_list.extend(excel_read().get_data())



# 1、对单个页面进行请求,并返回数据信息——通过data自定义特定企业
def get_and_download_pdf_flie(pageNum, stock, searchkey='', category='', seDate=''):
    url = 'http://www.cninfo.com.cn/new/hisAnnouncement/query'
    pageNum = int(pageNum)
    #   定义表单数据
    data = {'pageNum': pageNum,
            'pageSize': 30,
            'column': 'szse',
            'tabName': 'fulltext',
            'plate': '',
            'stock': stock,
            'searchkey': searchkey,
            'secid': '',
            'category': category,
            'trade': '',
            'seDate': seDate,
            'sortName': '',
            'sortType': '',
            'isHLtitle': 'true'}

    #   定义请求头
    headers = {'Accept': '*/*',
               'Accept-Encoding': 'gzip, deflate',
               'Accept-Language': 'zh-CN,zh;q=0.9',
               'Connection': 'keep-alive',
               'Content-Length': '181',
               'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
               'Host': 'www.cninfo.com.cn',
               'Origin': 'http://www.cninfo.com.cn',
               'Referer': 'http://www.cninfo.com.cn/new/commonUrl/pageOfSearch?url=disclosure/list/search',
               'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',
               'X-Requested-With': 'XMLHttpRequest'}

    #   提交请求
    r = requests.post(url, data=data, headers=headers)

    #   获取单页年报的数据,数据格式为json,解析并获取json中的年报信息
    result = r.json()['announcements']

    # 2.对数据信息进行提取
    for i in result:
        #         避免下载一些年报摘要等不需要的文件
        if re.search('摘要', i['announcementTitle']):
            pass
        else:
            title = i['announcementTitle']

            #             获取公告文件名,并在下载前将公告文件名中带*号的去掉,因为文件命名规则不能带*号,否则程序会中断
            secName = i['secName']
            secName = secName.replace('*', '')

            #             获取公司股票代码
            secCode = i['secCode']

            #             获取adjunctUrl,并组合生成pdf文件下载地址(分析得知巨潮资讯数据库pdf下载地址格式:http://static.cninfo.com.cn/+adjunctUrl)
            adjunctUrl = i['adjunctUrl']
            down_url = 'http://static.cninfo.com.cn/' + adjunctUrl

            #            定义下载之后需要保存到本地的文件名
            filename = f'{secCode}{secName}{title}.pdf'

            #             定义文件存放地址
            filepath = saving_path + '\\' + filename

            #             提交下载请求
            r = requests.get(down_url)

            #             用response.content来写入文件信息
            with open(filepath, 'wb') as f:
                f.write(r.content)

            #             设置进度条
            print(f'{secCode}{secName}{title}下载完毕')

# 设置存储年报的文件夹,把路径改成自己的
saving_path = r'E:\python\'

# 根据code_list计算待爬企业数量
Num = len(code_list)
print(Num)


# 从code_list中根据待爬企业数量遍历提取code与orgId
for i in range(0, Num):
    code = code_list[i][0]
    orgId = code_dic[code]
    #     定义stock
    stock = '{},{}'.format(code, orgId)
    print(stock)
    #     定义searchkey
    searchkey = ''
    #     定义category
    category = 'category_ndbg_szsh'
    #     定义seDate
    seDate = '2021-01-01~2023-11-15'

    #     定义pageNum(需要通过观测,确保pageNum能够涵盖每一次遍历请求的结果页数,此处定为2页即可)
    for pageNum in range(1, 3):
        try:
            get_and_download_pdf_flie(pageNum, stock, searchkey, category, seDate, )
        except:
            #             超出页数后会报错,需要跳过异常以便于继续遍历执行
            pass

 最终导出如下,也可根据自己的需求下载不同季度年份的报告。

后续将更新pdf文字提取和直接提取网页内数据的博客,尽量把这个项目完整地放上来吧,毕竟当时在网上查了很久删删改改,从0基础到成功地爬取数据,真的很不容易。 

  • 12
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值