鱼C论坛

 找回密码
 立即注册
查看: 1828|回复: 4

[已解决]关于爬虫的问题,大佬捞捞我

[复制链接]
发表于 2021-1-11 22:52:35 | 显示全部楼层 |阅读模式

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

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

x
我想爬取深交所官网上市公司的年报,只要年度报告,但是爬取出来了很多季度报告和报告摘要,求大佬指导,这个代码应该怎么修改才能只爬出年度报告。
import os
import math
import json
import requests
from copy import deepcopy


URL = 'http://www.szse.cn/api/disc/announcement/annList'

HEADER = {
    'Host': 'www.szse.cn',
    'Origin': 'http://www.szse.cn',
    'Referer': 'http://www.szse.cn/disclosure/listed/fixed/index.html',
    'User-Agent': "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
    'Content-Type': 'application/json',
    'Connection': 'keep-alive',
    'X-Request-Type': 'ajax',
    'X-Requested-With': 'XMLHttpRequest',
}

PAGE_SIZE = 30

PAYLOAD = {
    'channelCode': ["fixed_disc"],
    'pageNum': 1,
    'pageSize': PAGE_SIZE,
    'seDate': ["", ""],
    'stock': ["000001"],
}

PDF_URL_PREFIX = 'http://disc.static.szse.cn/download'


def get_pdf_url(code, begin_date, end_date):
    pdf_urls = []
    payload = deepcopy(PAYLOAD)
    payload['stock'] = [code]
    payload['seDate'] = [begin_date, end_date]
    res = requests.post(URL, data=json.dumps(payload), headers=HEADER).json()
    for i in res['data']:
        file_name = '_'.join([i['title'], ''.join(i['publishTime'].split()[0].split('-'))])
        pdf_url = PDF_URL_PREFIX + i['attachPath']
        pdf_urls.append((file_name, pdf_url))
    page_count = math.ceil(res['announceCount'] / PAGE_SIZE)
    for j in range(page_count - 1):
        payload['pageNum'] = j + 2
        res = requests.post(URL, data=json.dumps(payload), headers=HEADER).json()
        for i in res['data']:
            file_name = '_'.join([i['title'], ''.join(i['publishTime'].split()[0].split('-'))])
            pdf_url = PDF_URL_PREFIX + i['attachPath']
            pdf_urls.append((file_name, pdf_url))
    return pdf_urls


def save_pdf(code, path='./', begin_date='', end_date=''):
    pdf_urls = get_pdf_url(code, begin_date, end_date)
    file_path = os.path.join(path, code)
    if not os.path.isdir(file_path):
        os.makedirs(file_path)
    for file_name, url in pdf_urls:
        extension = url.split('.')[-1]
        file_full_name = os.path.join(file_path, '.'.join([file_name, extension])).replace('*', '')
        rs = requests.get(url, stream=True)
        with open(file_full_name, "wb") as fp:
            for chunk in rs.iter_content(chunk_size=10240):
                if chunk:
                    fp.write(chunk)


if __name__ == '__main__':
    l = ['300500 ', '300499 ']
    for i in l:
        save_pdf(i, begin_date='2005-12-27', end_date='2019-12-27')
        time.sleep(random.uniform(1, 2))
最佳答案
2021-1-12 04:09:28
本帖最后由 YunGuo 于 2021-1-12 04:14 编辑
  1. import requests
  2. import json
  3. import os


  4. def save_pdf(title, ts, download_url, folder_name):
  5.     """
  6.     下载
  7.     :param title: pdf文件标题
  8.     :param ts: 报告发表时间
  9.     :param download_url: 报告下载地址
  10.     :param folder_name: 文件夹名
  11.     :return:
  12.     """
  13.     print('正在下载:', title)
  14.     if not os.path.isdir(f'./{folder_name}'):
  15.         os.makedirs(f'./{folder_name}')
  16.     res = requests.get(download_url, stream=True)
  17.     with open(f'./{folder_name}/{title}_{ts}.pdf', 'wb') as f:
  18.         for chunk in res.iter_content(chunk_size=10240):
  19.             if chunk:
  20.                 f.write(chunk)


  21. def get_item(page):
  22.     """
  23.     请求数据
  24.     :param page: 页码
  25.     :return:
  26.     """
  27.     url = 'http://www.szse.cn/api/disc/announcement/annList'
  28.     headers = {
  29.         "Content-Type": "application/json",
  30.         "Host": "www.szse.cn",
  31.         "Origin": "http://www.szse.cn",
  32.         "Referer": "http://www.szse.cn/disclosure/listed/fixed/index.html",
  33.         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36",
  34.     }
  35.     data = {
  36.         # 参数按需求改
  37.         # 010301:年度报告  010303:半年度报告  010305:一季度报告  010307:三季度报告
  38.         "bigCategoryId": ["010301"],  # 设置报告类型
  39.         "channelCode": ["fixed_disc"],  # 固定不变
  40.         "pageNum": page,  # 设置页码
  41.         "pageSize": 30,  # 设置一页报告数量
  42.         "seDate": ["", ""]   # 设置时间:格式  ["2017-01-01", "2021-01-01"]
  43.     }
  44.     res = requests.post(url, headers=headers, data=json.dumps(data))
  45.     datas = res.json().get('data')
  46.     # 将报告类型id作为文件夹名
  47.     folder_name = ''.join(data.get('bigCategoryId'))
  48.     for info in datas:
  49.         title = info.get('title').replace('*', '')
  50.         ts = info.get('publishTime').split(' ')[0]
  51.         download_url = 'http://disc.static.szse.cn/download' + info.get('attachPath')
  52.         save_pdf(title, ts, download_url, folder_name)


  53. if __name__ == '__main__':
  54.     # 需要下载的页数
  55.     page_num = 10
  56.     for i in range(1, page_num+1):
  57.         print(f'第{i}页'.center(50, '='))
  58.         get_item(i)
  59.         print('=' * 50)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-1-12 04:09:28 | 显示全部楼层    本楼为最佳答案   
本帖最后由 YunGuo 于 2021-1-12 04:14 编辑
  1. import requests
  2. import json
  3. import os


  4. def save_pdf(title, ts, download_url, folder_name):
  5.     """
  6.     下载
  7.     :param title: pdf文件标题
  8.     :param ts: 报告发表时间
  9.     :param download_url: 报告下载地址
  10.     :param folder_name: 文件夹名
  11.     :return:
  12.     """
  13.     print('正在下载:', title)
  14.     if not os.path.isdir(f'./{folder_name}'):
  15.         os.makedirs(f'./{folder_name}')
  16.     res = requests.get(download_url, stream=True)
  17.     with open(f'./{folder_name}/{title}_{ts}.pdf', 'wb') as f:
  18.         for chunk in res.iter_content(chunk_size=10240):
  19.             if chunk:
  20.                 f.write(chunk)


  21. def get_item(page):
  22.     """
  23.     请求数据
  24.     :param page: 页码
  25.     :return:
  26.     """
  27.     url = 'http://www.szse.cn/api/disc/announcement/annList'
  28.     headers = {
  29.         "Content-Type": "application/json",
  30.         "Host": "www.szse.cn",
  31.         "Origin": "http://www.szse.cn",
  32.         "Referer": "http://www.szse.cn/disclosure/listed/fixed/index.html",
  33.         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36",
  34.     }
  35.     data = {
  36.         # 参数按需求改
  37.         # 010301:年度报告  010303:半年度报告  010305:一季度报告  010307:三季度报告
  38.         "bigCategoryId": ["010301"],  # 设置报告类型
  39.         "channelCode": ["fixed_disc"],  # 固定不变
  40.         "pageNum": page,  # 设置页码
  41.         "pageSize": 30,  # 设置一页报告数量
  42.         "seDate": ["", ""]   # 设置时间:格式  ["2017-01-01", "2021-01-01"]
  43.     }
  44.     res = requests.post(url, headers=headers, data=json.dumps(data))
  45.     datas = res.json().get('data')
  46.     # 将报告类型id作为文件夹名
  47.     folder_name = ''.join(data.get('bigCategoryId'))
  48.     for info in datas:
  49.         title = info.get('title').replace('*', '')
  50.         ts = info.get('publishTime').split(' ')[0]
  51.         download_url = 'http://disc.static.szse.cn/download' + info.get('attachPath')
  52.         save_pdf(title, ts, download_url, folder_name)


  53. if __name__ == '__main__':
  54.     # 需要下载的页数
  55.     page_num = 10
  56.     for i in range(1, page_num+1):
  57.         print(f'第{i}页'.center(50, '='))
  58.         get_item(i)
  59.         print('=' * 50)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-12 10:54:20 | 显示全部楼层
谢谢大佬,我想问一下如果我只想下载300开头的公司我应该怎么修改呢?是只改url就行了吗?然后我下载的文件名可以修改吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-12 10:55:58 | 显示全部楼层


谢谢大佬,我想问一下如果我只想下载300开头的公司我应该怎么修改呢?是只改url就行了吗?然后我下载的文件名可以修改吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-12 15:18:41 | 显示全部楼层
masterbo 发表于 2021-1-12 10:55
谢谢大佬,我想问一下如果我只想下载300开头的公司我应该怎么修改呢?是只改url就行了吗?然后我下载的 ...

你想怎样设置文件名?可以看代码中的注释。
另外,下载300开头的公司不用改url,获取到数据后加个判断就行了。
  1. import requests
  2. import json
  3. import os


  4. def save_pdf(title, ts, download_url, folder_name, code):
  5.     """
  6.     下载
  7.     :param title: pdf文件标题
  8.     :param ts: 报告发表时间
  9.     :param download_url: 报告下载地址
  10.     :param folder_name: 文件夹名
  11.     :param code: 公司代码
  12.     :return:
  13.     """
  14.     print('正在下载:', title)
  15.     if not os.path.isdir(f'./{folder_name}'):
  16.         os.makedirs(f'./{folder_name}')
  17.     res = requests.get(download_url, stream=True)
  18.     # 这里设置pdf文件名格式是:公司代码(code) + pdf文件标题(title) + 发表时间(ts)
  19.     # 如果觉得名字太长,只需要标题作为文件名,删掉下面的code和ts就行
  20.     with open(f'./{folder_name}/[{code}]{title}_{ts}.pdf', 'wb') as f:
  21.         for chunk in res.iter_content(chunk_size=10240):
  22.             if chunk:
  23.                 f.write(chunk)


  24. def get_item(page, code_head):
  25.     """
  26.     请求数据
  27.     :param page: 页码
  28.     :param code_head: 公司代码前三位数
  29.     :return:
  30.     """
  31.     url = 'http://www.szse.cn/api/disc/announcement/annList'
  32.     headers = {
  33.         "Content-Type": "application/json",
  34.         "Host": "www.szse.cn",
  35.         "Origin": "http://www.szse.cn",
  36.         "Referer": "http://www.szse.cn/disclosure/listed/fixed/index.html",
  37.         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36",
  38.     }
  39.     data = {
  40.         # 参数按需求改
  41.         # 010301:年度报告  010303:半年度报告  010305:一季度报告  010307:三季度报告
  42.         "bigCategoryId": ["010301"],  # 设置报告类型
  43.         "channelCode": ["fixed_disc"],  # 固定不变
  44.         "pageNum": page,  # 设置页码
  45.         "pageSize": 30,  # 设置一页报告数量
  46.         "seDate": ["", ""]   # 设置时间:格式  ["2017-01-01", "2021-01-01"]
  47.     }
  48.     res = requests.post(url, headers=headers, data=json.dumps(data))
  49.     datas = res.json().get('data')
  50.     # 将报告类型id作为最外层文件夹名,以公司代码开头数字作为内文件名,方便分类
  51.     # 如果要使用固定文件夹名,自行修改folder_name的值,两层格式: XXX/XXX 一层格式: XXX
  52.     folder_name = f"{''.join(data.get('bigCategoryId'))}/{str(code_head)}"
  53.     for info in datas:
  54.         code = ''.join(info.get('secCode'))
  55.         if code[:3] == str(code_head):
  56.             title = info.get('title').replace('*', '')
  57.             ts = info.get('publishTime').split(' ')[0]
  58.             download_url = 'http://disc.static.szse.cn/download' + info.get('attachPath')
  59.             save_pdf(title, ts, download_url, folder_name, code)


  60. if __name__ == '__main__':
  61.     # 需要下载的页数
  62.     page_num = 1
  63.     # 指定公司代码以XXX开头
  64.     code_head = 300
  65.     for i in range(1, page_num+1):
  66.         print(f'第{i}页'.center(50, '='))
  67.         get_item(i, code_head)
  68.         print('=' * 50)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-29 01:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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