本项目是全程运用Python实现的,分为三个代码实现三部分功能,本次讲解的是第一部分代码:从统计好的EXCEL表格中自动进行公司年报的下载地址的捕捉并下载年报PDF,想要代码和统计好的年报EXCEL文档的可以私聊我或者从最后的第三部分文章链接里的GitHub网站中下载哦 ❛‿˂̵✧
import pandas as pd import requests import time import os rawdata = pd.read_excel('年报链接_2022.xlsx', sheet_name=0)
这部分代码是实现模块的导入和年报链接EXCEL表格的打开,如果没有安装库的则需要安装一下对应的Python的库,我的pycharm的解释器是anaconda3,anaconda3里面本身就有很多自带的库,使用比较方便。
'年报链接_2022.xlsx'部分可以替换为你所需要的年份的年报链接的命名,但是前提是代码要和年报表格在一个文件夹里哦,否则就要写全年报表格的具体路径位置哦。
def get_data(iloc): firm = rawdata.at[iloc, '标题'].replace("*", "") # 去掉*ST的*号,文件命名不含特殊符号 code = str(rawdata.at[iloc, '公司代码']) if(len(code) < 6): while(6-len(code)): code = '0'+code print(code) year = rawdata.at[iloc, '年份'] pdf_url = rawdata.at[iloc, '年报链接'] company = rawdata.at[iloc, '公司简称'].replace("*", "") # 去掉*ST的*号,文件命名不含特殊符号 return firm, code, year, pdf_url, company
这段代码定义了一个名为get_data
的函数,该函数从名为rawdata
的数据框中提取特定行的数据,并返回多个字段。以下是该代码的详细解释:
-
定义一个名为def get_data(iloc):
get_data
的函数,该函数接受一个参数iloc
,代表要提取数据的行的索引。 -
从firm = rawdata.at[iloc, '标题'].replace("*", "")
rawdata
数据框中提取指定行的'标题'列的值,并使用replace("*", "")
方法去掉其中的星号(*)。结果赋值给变量firm
。 -
从code = str(rawdata.at[iloc, '公司代码'])
rawdata
数据框中提取指定行的'公司代码'列的值,并将其转换为字符串。结果赋值给变量code
。 -
检查变量if(len(code) < 6):
code
的长度是否小于6。 -
如果上述条件为真,则进入循环,直到while(6-len(code)):
code
的长度达到6位。 -
在变量code = '0'+code
code
的开头添加一个0,使其长度达到6位。 -
打印变量print(code)
code
的值。 -
从year = rawdata.at[iloc, '年份']
rawdata
数据框中提取指定行的'年份'列的值,并赋值给变量year
。 -
从pdf_url = rawdata.at[iloc, '年报链接']
rawdata
数据框中提取指定行的'年报链接'列的值,并赋值给变量pdf_url
。 -
从company = rawdata.at[iloc, '公司简称'].replace("*", "")
rawdata
数据框中提取指定行的'公司简称'列的值,并使用replace("*", "")
方法去掉其中的星号(*)。结果赋值给变量company
。 -
return firm, code, year, pdf_url, company:
返回上述提取的五个字段的值。
def get_filepath(code, company, year): file_path = 'C://Users\末路歧途\Desktop\LC 爬取\年报PDF版' file_name = "{}_{}_{}.pdf".format(code, company, year) file_full_name = os.path.join(file_path, file_name) return file_full_name
这个函数是将从EXCEL表格提取到的公司代码,公司名称和年份作为从年报下载链接下载出来的PDF的命名,file_path = 'C://Users\末路歧途\Desktop\LC 爬取\年报PDF版'为设置下载的位置,可自行修改为自己电脑上的位置。
-
定义一个名为def get_filepath(code, company, year):
get_filepath
的函数,该函数接受三个参数:code
(代码)、company
(公司)和year
(年份)。 -
定义一个变量file_path = 'C://Users\末路歧途\Desktop\LC 爬取\年报PDF版'
file_path
,表示文件存储的目录。这里指定了路径为C://Users\末路歧途\Desktop\LC 爬取\年报PDF版
。 -
使用字符串格式化方法,根据传入的参数file_name = "{}_{}_{}.pdf".format(code, company, year)
code
、company
和year
,生成一个文件名。例如,如果代码是“600848”,公司是“中国联通”,年份是2022,则文件名为“600848_中国联通_2022.pdf”。 -
使用file_full_name = os.path.join(file_path, file_name)
os.path.join()
方法将目录路径和文件名合并,得到文件的完整路径。例如,如果目录路径是C://Users\末路歧途\Desktop\LC 爬取\年报PDF版
,文件名是“600848_中国联通_2022.pdf”,则文件的完整路径为“C://Users\末路歧途\Desktop\LC 爬取\年报PDF版\600848_中国联通_2022.pdf”。 -
return file_full_name
:返回文件的完整路径。
def download_pdf(url, file_full_name): headers = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60"} res = requests.get(url, headers=headers) with open(file_full_name, "wb") as fp: for chunk in res.iter_content(chunk_size=1024): if chunk: fp.write(chunk)
-
定义一个名为def download_pdf(url, file_full_name):
download_pdf
的函数,该函数接受两个参数:url
(要下载的PDF文件的URL)和file_full_name
(要保存的文件路径和名称)。 -
定义一个字典headers = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60"}
headers
,用于设置HTTP请求的头部信息。这里特别设置了User-Agent
,它表示一个常见的浏览器用户代理,以模仿浏览器发送请求,避免被某些服务器拒绝。 -
使用res = requests.get(url, headers=headers)
requests
库的get
方法发送GET请求到给定的URL,并使用前面定义的headers
头部信息。返回的响应对象赋值给变量res
。 -
使用上下文管理器打开指定的文件路径(with open(file_full_name, "wb") as fp:
file_full_name
),以二进制写模式("wb")。文件对象赋值给变量fp
。 -
使用for chunk in res.iter_content(chunk_size=1024):
iter_content
方法按块读取响应内容,每块大小为1024字节。对于每个块,执行循环内的代码。 -
检查当前块是否非空。如果是非空块,则执行以下代码块。这主要用于处理最后一个块,因为最后一个块可能小于指定的块大小(在本例中为1024字节)。if chunk:
-
将当前块的内容写入到文件中。fp.write(chunk)
总结:这段代码定义了一个函数,用于从给定的URL下载PDF文件并将其保存到指定的本地文件路径。在下载过程中,它使用了特定的用户代理头部信息来模拟浏览器行为,并使用了分块写入的方式处理大文件,以提高效率和减少内存使用。
for iloc in range(rawdata.shape[0]): firm, code, year, pdf_url, company = get_data(iloc) print("开始下载{},股票代码{}的{}年报".format(company, code, year)) file_full_name = get_filepath(code, company, year) download_pdf(pdf_url, file_full_name) time.sleep(1) print("===========下载完成==========")
这段代码是一个循环,用于遍历rawdata
数据框中的所有行,并对于每一行调用前面定义的get_data
、get_filepath
和download_pdf
函数,以实现年报PDF文件的下载。以下是对该代码的详细解释:
-
使用for iloc in range(rawdata.shape[0]):
range
函数和rawdata.shape[0]
来创建一个迭代器,rawdata.shape[0]
返回rawdata
数据框的行数。iloc
变量将在每次循环中代表当前行的索引。 -
调用前面定义的firm, code, year, pdf_url, company = get_data(iloc)
get_data
函数,传入当前行的索引iloc
作为参数。函数返回五个值,分别赋值给变量firm
、code
、year
、pdf_url
和company
。 -
使用print("开始下载{},股票代码{}的{}年报".format(company, code, year))
print
函数输出一条消息,表明开始下载指定公司的年报。消息中包含了公司名称(company
)、股票代码(code
)和年份(year
),这些信息是通过format
方法从前面步骤中获取的。 -
调用file_full_name = get_filepath(code, company, year)
get_filepath
函数,传入股票代码(code
)、公司名称(company
)和年份(year
)作为参数。函数返回一个完整的文件路径,赋值给变量file_full_name
。 -
调用download_pdf(pdf_url, file_full_name)
download_pdf
函数,传入年报的PDF链接(pdf_url
)和完整的文件路径(file_full_name
)作为参数。该函数负责下载PDF文件并保存到本地。 -
调用time.sleep(1)
time
模块的sleep
函数,使程序暂停执行1秒。这是为了避免过于频繁地发送请求,可能导致的服务器拒绝服务或IP被封禁的风险。 -
使用print("===========下载完成==========")
print
函数输出一条消息,表明当前公司的年报下载已经完成。
整个循环将遍历rawdata
中的所有行,并依次下载每个公司的年报PDF文件。每次下载之间都会暂停1秒以减少对服务器的压力。同时,通过输出消息,用户可以实时了解下载进度。注意,为了使这段代码正常工作,需要确保rawdata
、get_data
、get_filepath
、download_pdf
以及requests
和time
模块都已经正确定义和导入。
总体代码如下代码:
import pandas as pd
import requests
import time
import os
rawdata = pd.read_excel('年报链接_2022.xlsx', sheet_name=0)
def get_data(iloc):
firm = rawdata.at[iloc, '标题'].replace("*", "") # 去掉*ST的*号,文件命名不含特殊符号
code = str(rawdata.at[iloc, '公司代码'])
if(len(code) < 6):
while(6-len(code)):
code = '0'+code
print(code)
year = rawdata.at[iloc, '年份']
pdf_url = rawdata.at[iloc, '年报链接']
company = rawdata.at[iloc, '公司简称'].replace("*", "") # 去掉*ST的*号,文件命名不含特殊符号
return firm, code, year, pdf_url, company
def get_filepath(code, company, year):
file_path = 'C://Users\末路歧途\Desktop\LC 爬取\年报PDF版'
file_name = "{}_{}_{}.pdf".format(code, company, year)
file_full_name = os.path.join(file_path, file_name)
return file_full_name
def download_pdf(url, file_full_name):
headers = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60"}
res = requests.get(url, headers=headers)
with open(file_full_name, "wb") as fp:
for chunk in res.iter_content(chunk_size=1024):
if chunk:
fp.write(chunk)
for iloc in range(rawdata.shape[0]):
firm, code, year, pdf_url, company = get_data(iloc)
print("开始下载{},股票代码{}的{}年报".format(company, code, year))
file_full_name = get_filepath(code, company, year)
download_pdf(pdf_url, file_full_name)
time.sleep(1)
print("===========下载完成==========")
第一部分代码实现了从统计好的EXCEL表格中自动进行公司年报的下载地址的捕捉并下载年报PDF,和后面的两部分是相呼应的。下面是另外两部分的博客链接,想看的友友们可以自行查看哦!