Python爬取上交所年报下载并转成TXT

参考博客:
6小时爬完上交所和深交所的年报问询函
Python爬取上交所年报并下载

一、任务描述

从上交所的官网上爬取年报PDF文档,并且转成TXT。

二、解决思路

1、解析网页获取年报的文件链接,并下载PDF
2、读取第一步的PDF 数据,并直接转成 TXT 格式的文字

三、网页分析

1、 数据包位置
进入要下载年报的界面,点击查看源码
年报URL

2、结合日期获得不同的URL链接,但这一步得到的并不是PDF的下载链接,解析这个URL链接

3、结合第二步解析URL链接获得的网页内容,查找该日期对应的PDF下载链接

四、PDF转TXT

1、代码
这个直接搬运了第一篇参考博客的代码啦!

2、MAC系统GB编码的坑
PDF转TXT后得到的TXT为下图所示
TXT乱码
解决方案是知乎上的一个回答:
Python解析pdf得到的中文CID字库如何变成utf-8

五、核心代码

1、下载PDF

import json
import requests
import re
import datetime
import csv 
from urllib.request import urlopen
from urllib.request import Request
from urllib.request import quote
import requests
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal, LAParams
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed
from pdfminer.pdfparser import PDFParser, PDFDocument
f=open ('stkcd.csv',mode='w',encoding='gbk',newline='')
writer = csv.writer(f)
head=['stkcd']
writer.writerow(head)



#要下载的年报日期可以根据需要调整,开始日期和结束日期间隔最好不要超过30日#
begin = datetime.date(2019,12,1)
end = datetime.date(2019,12,30)
for i in range((end - begin).days+1):
    searchDate = str(begin + datetime.timedelta(days=i))
    response=requests.get(
        'http://query.sse.com.cn/infodisplay/queryLatestBulletinNew.do?&jsonCallBack=jsonpCallback43752&productId=&reportType2=DQGG&reportType=YEARLY&beginDate='+searchDate+'&endDate='+searchDate+'&pageHelp.pageSize=25&pageHelp.pageCount=50&pageHelp.pageNo=1&pageHelp.beginPage=1&pageHelp.cacheSize=1&pageHelp.endPage=5&_=1561094157400'
        ,
        headers={'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'  ,'Referer':'http://www.sse.com.cn/disclosure/listedinfo/regular/'}
    )#传送请求时把headers传入Request参数里,应付防盗链了;referer:将请求的的浏览器设置成本网站的

    json_str = response.text[19:-1]
    data = json.loads(json_str)# 把Json格式字符串解码转换成Python对象,得到dict格式  
    for report in data['result']:
        download_url = 'http://www.sse.com.cn/' + report['URL']
        if re.search('年度报告',report['title'],re.S):#使 . 匹配包括换行在内的所有字符
            if re.search('摘要',report['title'],re.S):###避免下载一些年报摘要等不需要的文件###
                pass                                 #do nothing
            else:
                filename = report['security_Code']+report['title'] +searchDate+ '.pdf'
                print(filename)
                writer.writerow([report['security_Code']])###将公司代码写进csv文件,便于计数,非必须步骤###
                if re.search('ST',report['title'],re.S):###下载前要将文件名中带*号的去掉,因为文件命名规则不能带*号,否则程序会中断###
                    filename=report['security_Code']+'-ST' +searchDate+ '.pdf'
                    download_url = 'http://static.sse.com.cn/' + report['URL']
                    resource = requests.get(download_url, stream=True)
                    with open(filename, 'wb') as fd:
                        for y in resource.iter_content(102400): #把PDF文档写入
                            fd.write(y)
                        print(filename, '完成下载')
                else:
                    download_url = 'http://static.sse.com.cn/' + report['URL']
                    resource = requests.get(download_url, stream=True)
                    with open(filename, 'wb') as fd:
                        for y in resource.iter_content(102400):
                            fd.write(y)
                        print(filename, '完成下载') 

2、PDF转TXT

# fp = open('600193-ST2019-12-17.pdf','rb')
praser_pdf = PDFParser(fp)
# 创建一个PDF文档
doc = PDFDocument()
# 连接分析器 与文档对象
praser_pdf.set_document(doc)
doc.set_parser(praser_pdf)
# 提供初始化密码doc.initialize("123456")
# 如果没有密码 就创建一个空的字符串
doc.initialize()
# 检测文档是否提供txt转换,不提供就忽略
if not doc.is_extractable:
    raise PDFTextExtractionNotAllowed
else:
    # 创建PDf资源管理器 来管理共享资源
    rsrcmgr = PDFResourceManager()
    # 创建一个PDF参数分析器
    laparams = LAParams()
    # 创建聚合器
    device = PDFPageAggregator(rsrcmgr, laparams=laparams)
    # 创建一个PDF页面解释器对象
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    # 循环遍历列表,每次处理一页的内容
    # doc.get_pages() 获取page列表
    for page in doc.get_pages():
        # 使用页面解释器来读取
        interpreter.process_page(page)
        # 使用聚合器获取内容
        layout = device.get_result()
        # 这里layout是一个LTPage对象 里面存放着 这个page解析出的各种对象 一般包括LTTextBox, LTFigure, LTImage, LTTextBoxHorizontal 等等 想要获取文本就获得对象的text属性,
        for out in layout:
            # 判断是否含有get_text()方法,图片之类的就没有
            # if ``hasattr(out,"get_text"):
            docname = "上交所列表.txt"
            with open(docname,'a') as f:
                if isinstance(out, LTTextBoxHorizontal):
                    results = out.get_text()
                    print(results)
                    f.write(results)
Python爬取深交所年报通常涉及网络抓取技术,使用像BeautifulSoup、Scrapy这样的库来解析HTML网页内容。以下是一个简化的步骤: 1. **安装必要的库**:首先需要安装requests库用于发送HTTP请求获取网页数据,以及如BeautifulSoup4用于解析HTML。 ```bash pip install requests bs4 ``` 2. **定位URL**:访问深证券交易所官网,找到年报下载链接或API文档,了解年报数据的具体获取地址。 3. **编写爬虫脚本**:使用Python编写代码,发起GET请求获取年报页面,并利用BeautifulSoup解析HTML结构,找到年报文件的链接或下载按钮的属性。 ```python import requests from bs4 import BeautifulSoup url = "https://www.szse.cn/disclosure/corpgov_annual_report/" response = requests.get(url) soup = BeautifulSoup(response.text, 'html.parser') # 查找年报下载链接并保存 annual_report_link = soup.select_one('a[rel="noopener noreferrer"]')['href'] ``` 4. **下载文件**:如果年报是直接下载链接,使用`response.urljoin(annual_report_link)`组合成完整的URL,并使用`requests`下载文件。 ```python download_url = response.urljoin(annual_report_link) with open('年报.zip', 'wb') as f: response = requests.get(download_url, stream=True) for chunk in response.iter_content(chunk_size=1024): if chunk: f.write(chunk) ``` 5. **处理可能的验证码或登录验证**:某些网站可能会有验证码或需要登录才能下载,这时需要模拟登录或使用Selenium等工具协助。 6. **存储或解析数据**:将下载年报文件解压后,可能还需要进一步处理XML或PDF格式的数据,可以使用pandas或者专门的PDF解析库如PyPDF2进行读取和分析。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值