鱼C论坛

 找回密码
 立即注册
查看: 2255|回复: 2

[已解决]在B站上取得抓取巨潮资讯的年报公告的代码 但自己运行报错 求助~~

[复制链接]
发表于 2022-8-10 23:31:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

1、报错说明
见图片

Traceback (most recent call last):
  File "C:\Users\10166\PycharmProjects\巨潮资讯爬取\1.py", line 87, in <module>
    export_excel(stock_list)
  File "C:\Users\10166\PycharmProjects\巨潮资讯爬取\1.py", line 75, in export_excel
    file_path = pd.ExcelWriter('code_list.xlsx')
  File "C:\Users\10166\PycharmProjects\巨潮资讯爬取\venv\lib\site-packages\pandas\io\excel\_openpyxl.py", line 53, in __init__
    super().__init__(
  File "C:\Users\10166\PycharmProjects\巨潮资讯爬取\venv\lib\site-packages\pandas\io\excel\_base.py", line 1106, in __init__
    self.handles = get_handle(
  File "C:\Users\10166\PycharmProjects\巨潮资讯爬取\venv\lib\site-packages\pandas\io\common.py", line 795, in get_handle
    handle = open(handle, ioargs.mode)
PermissionError: [Errno 13] Permission denied: 'code_list.xlsx'

2、B站的抓取教程
https://www.bilibili.com/video/B ... 40c4afe42611bfb5ead

3、具体代码
如下:




# 使用说明:仅需要更改 Part1_Part1 中的前三项参数即可(同时需要保证 Part1_Step2 中所用到的工具包都已安装)


# Part1:准备工作

## Step1:自定义参数

### 1、定义股票代码列表 和 爬取结果输出地址(最好指定一个空的文件夹)———必选项
Codelist_path = r"D:\Users\yxj\Desktop\代码.xls"
Output_path = r"D:\Users\yxj\Desktop\年报"

### 2、定义要爬取的报表类型(若同时爬取多项中间用;连接)———必选项
# 公司年度报告:category_ndbg_szsh
# 公司治理报告:category_gszl_szsh
Category_A = 'category_gszl_szsh;category_ndbg_szsh;'

### 3、定义要爬取的时间段———必选项
SeDate_A = '2018-01-01~2021-09-26'

### 4、定义爬取指定报告的关键词(若不指定则保持为空即可)———可选项
Search_key = ''

## Step2:导入工具包
# 导入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


## Step3:获取巨潮资讯的数据源格式信息

# 从以下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)

# 检查数据格式案例 2个公司
stock_list[:2]


## Step4:用pandas把股票代码导出到Excel备用(可选)

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)


## Step5:从Excel文件读取待爬取的股票清单并生成列表code_list

# 定义一个读取xls文件数据并转为列表的类
class excel_read:
    def __init__(self, excel_path=Codelist_path, 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())


# Part3:正式工作

## Step1:定义爬取函数

### 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}下载完毕')


## Step2:自定义保存路径及确定待爬企业数量

# 设置存储年报的文件夹,把路径改成自己的
saving_path = Output_path

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

## Step3:设定参数进行遍历爬取

# 从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 = Search_key
    #     定义category
    category = Category_A
    #     定义seDate
    seDate = SeDate_A

    #     定义pageNum(需要通过观测,确保pageNum能够涵盖每一次遍历请求的结果页数,此处定为2页即可)
    for pageNum in range(1, 3):
        try:
            get_and_download_pdf_flie(pageNum, stock, searchkey, category, seDate, )
        except:
            #             超出页数后会报错,需要跳过异常以便于继续遍历执行
            pass
最佳答案
2022-8-10 23:40:28
本帖最后由 临时号 于 2022-8-10 23:43 编辑

1.如果你的excel文件是打开的,你要关闭excel文件,重新运行
2.换一个目录

报错截图

报错截图

巨潮公告抓取代码.zip

3.53 KB, 下载次数: 0

售价: 1 鱼币  [记录]  [购买]

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-8-10 23:40:28 | 显示全部楼层    本楼为最佳答案   
本帖最后由 临时号 于 2022-8-10 23:43 编辑

1.如果你的excel文件是打开的,你要关闭excel文件,重新运行
2.换一个目录
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-11 11:25:29 | 显示全部楼层
临时号 发表于 2022-8-10 23:40
1.如果你的excel文件是打开的,你要关闭excel文件,重新运行
2.换一个目录

谢谢大佬,反馈如下:
1、我的表格的确是打开的,已关闭
2、更改到我电脑本地的目录
3、点运行,成功导出拉!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-17 04:50

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表