# 一.爬取pdf下载地址
import time
import pandas as pd
import csv
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
from urllib.parse import urljoin # 用于拼接 URL
browser = webdriver.Edge()
browser.get('https://www.szse.cn/disclosure/listed/fixed/index.html')
# 报告类型选择
# 选择年度报告类型
time.sleep(10)
element = browser.find_element(By.CSS_SELECTOR, "#select_gonggao .glyphicon").click()
time.sleep(10)
element = browser.find_element(By.LINK_TEXT, "年度报告").click()
time.sleep(5)
firm = [
['000068', '华控赛格'],
['000710', '贝瑞基因'],
['000779', '甘咨询'],
['002178', '延华智能'],
['002776', 'ST柏龙'],
['002883', '中设股份'],
['002949', '华阳国际'],
['002967', '广电计量'],
['003008', '开普检测'],
['003013', '地铁设计'],
]
# 自动控制浏览器选择所取的公司
# 手动一个一个获取
for i in range(len(firm)):
name = firm[i][1]
code = firm[i][0]
f = open('inner_HTML_%s.html' % name, 'w', encoding='utf-8')
element = browser.find_element(By.ID, "input_code").click()
time.sleep(5)
element = browser.find_element(By.ID, 'input_code').send_keys('%s' % code)
time.sleep(5)
element = browser.find_element(By.ID, "input_code").send_keys(Keys.ENTER)
element = browser.find_element(By.ID, 'disclosure-table')
time.sleep(5)
innerHTML = element.get_attribute('innerHTML')
f.write(innerHTML)
time.sleep(5)
f.close()
element = browser.find_element(By.CSS_SELECTOR, ".selected-item:nth-child(2) > .icon-remove").click()
time.sleep(5)
browser.quit()
time.sleep(10)
# 将获取的公司年报地址存入csv文件中
for i in range(len(firm)):
name = firm[i][1]
f = open('inner_HTML_%s.html' % name, encoding='utf-8')
t = f.read()
soup = BeautifulSoup(t, 'html.parser')
# print(type(t))
comments = soup.find_all('div', {'class': 'text-title-box'})
data_list = []
for item in comments:
content = item.find('span', {'class': 'pull-left title-text ellipsis'})
# print(content.text)
if content.text[-5:] != f"年年度报告":
continue
print(content.text)
# 找到报告的下载地址和名称
link = item.find("a", {"attachformat": "pdf"})
url = urljoin("https://www.szse.cn", link.get("href"))
name = link.find("span", {"class": "title-text"}).get("title")
# 将报告名和下载地址追加到 CSV 文件中
with open(f"{firm[i][1]}.csv", "a", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow([name, url])
f.close()
# 二.下载年度报告pdf
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
for i in range(len(firm)):
name = firm[i][1]
df = pd.read_csv(f'{name}.csv')
urls = df.iloc[:, 1].tolist()
for j in range(len(urls)):
ann_url = urls[j]
# 创建 WebDriver 对象
driver = webdriver.Chrome()
# 打开深交所网站并进入目标页面
driver.get(ann_url)
# 等待下载按钮可单击
download_btn = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "a#annouceDownloadBtn[href*='info/download']")))
# 点击 "公告下载"
download_btn.click()
# 等待下载并关闭浏览器
time.sleep(10)
driver.quit()
# 三.在pdf中获取数据
import PyPDF2
import pandas as pd
import os
firm = [
['000068', '华控赛格'],
['000710', '贝瑞基因'],
['000779', '甘咨询'],
['002178', '延华智能'],
['002776', 'ST柏龙'],
['002883', '中设股份'],
['002949', '华阳国际'],
['002967', '广电计量'],
['003008', '开普检测'],
['003013', '地铁设计'],
]
# 打开PDF文件
for i in range(10):
name = firm[i][1]
for j in range(2012, 2023):
file_path = f'{name}:{j}年年度报告.PDF'
print(file_path)
if os.path.exists(file_path):
with open(file_path, 'rb') as pdf_file:
# 创建文件阅读器
pdf_reader = PyPDF2.PdfFileReader(pdf_file)
# 获取PDF中文本内容(一般情况下,表格一般在最后一页)
# page_text = pdf_reader.getPage(pdf_reader.getNumPages() - 1).extractText()
for page_num in range(pdf_reader.getNumPages() - 5, 0, -1):
try:
page_text = pdf_reader.getPage(page_num).extractText()
# 成功提取到文本,跳出循环
break
except:
print(f'第{page_num}页文本提取失败,尝试上一页')
continue
# 把文本内容分割成行
lines = page_text.split('\n')
# 提取表格数据
data = []
for line in lines:
# 通过判断年份来确定新的一行开始
if line.strip().isdigit():
year = line.strip()
continue
# 判断行是否包含股票代码,以此判断是否属于表格数据
# if 'SH' in line or 'SZ' in line or '营业收入' or line or '基本每股收益' in line:
if 'SH' in line or 'SZ' in line or '营业收入' in line or '基本每股收益' in line:
# 分割行中的数据,并在末尾添加年份
row_data = line.split()
year = j
year = year if year else j
row_data.append(year)
data.append(row_data)
# 创建DataFrame,并设置列名
df = pd.DataFrame(data, columns=['股票代码', '股票简称', '办公地址', '公司网址', '营业收入', '基本每股收益', '年份'])
# df = pd.DataFrame(data)
# 将DataFrame数据写入CSV文件
df.to_csv('公司.csv', index=False, encoding='utf-8')
else:
print(f'{file_path} 不存在,跳过')
continue
# 可视化
# 1.各个公司分开
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"HYPengPengCheW.ttf", size=14)
plt.rcParams["font.family"] = "sans-serif"
plt.rcParams["axes.unicode_minus"] = False
df = pd.read_csv('公司.csv', usecols=['年份', '营业收入', '基本每股收益'])
plt.figure()
plt.plot(df['年份'], df['营业收入'], 'o-', label='营业收入', linewidth=2)
plt.xticks(rotation=45, fontproperties=font)
plt.xlabel('年份', fontproperties=font)
plt.ylabel('营业收入', fontproperties=font)
plt.title('地铁设计近十年营业收入变化趋势图', fontproperties=font)
plt.legend(prop=font)
plt.show()
plt.figure()
plt.plot(df['年份'], df['基本每股收益'], 'x-', label='基本每股收益', linewidth=2)
plt.xticks(rotation=45)
plt.xlabel('年份', fontproperties=font)
plt.ylabel('基本每股收益', fontproperties=font)
plt.title('地铁设计近十年基本每股收益变化趋势图', fontproperties=font)
plt.legend(prop=font)
plt.show()
2.各个公司同一年对比
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"HYPengPengCheW.ttf", size=14)
plt.rcParams["font.family"] = "sans-serif"
plt.rcParams["axes.unicode_minus"] = False
df = pd.read_csv('公司.csv', usecols=['年份', '股票简称', '股票代码', '办公地址', '公司网址', '营业收入', '基本每股收益'])
# 1. 按年份制图
grouped = df.groupby(['年份'])
for name, group in grouped:
plt.figure(figsize=(12, 6))
plt.suptitle(f"{name}年营业收入和基本每股收益柱状图", fontproperties=font)
plt.subplot(211)
plt.bar(group['股票简称'], group['营业收入'], width=0.3, label='营业收入')
plt.xticks(rotation=45, fontproperties=font)
plt.xlabel('股票简称(股票代码)', fontproperties=font)
plt.ylabel('营业收入', fontproperties=font)
plt.legend(prop=font)
plt.subplot(212)
plt.bar(group['股票简称'], group['基本每股收益'], width=0.3, label='基本每股收益')
plt.xticks(rotation=45, fontproperties=font)
plt.xlabel('股票简称(股票代码)', fontproperties=font)
plt.ylabel('基本每股收益', fontproperties=font)
plt.legend(prop=font)
plt.show()
# 3.所有公司所以年份绘制在同一张图-折线
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"HYPengPengCheW.ttf", size=14)
plt.rcParams["font.family"] = "sans-serif"
plt.rcParams["axes.unicode_minus"] = False
data = pd.read_csv('公司.csv')
# 转换为string类型
data['营业收入'] = data['营业收入'].astype(str)
# 使用.str方法去除','
data['营业收入'] = data['营业收入'].str.replace(',', '')
# 转换为string类型
data['基本每股收益'] = data['基本每股收益'].astype(str)
# 使用.str方法去除','
data['基本每股收益'] = data['基本每股收益'].str.replace(',', '')
#按年份从小到大排序
data = data.sort_values('年份')
#获取全部的股票信息
stocks = data['股票简称'].unique()
#按年份从小到大排序
data = data.sort_values('年份')
#获取全部的股票信息
stocks = data['股票简称'].unique()
fig, ax1 = plt.subplots(figsize=(12, 6))
# 绘制每个公司的营业收入
for stock in stocks:
stock_data = data[data['股票简称'] == stock]
# 将字符串中的逗号替换为空格,并将列类型转换为浮点数
stock_data['营业收入'] = stock_data['营业收入'].str.replace(',', '')
stock_data['营业收入'] = stock_data['营业收入'].str.replace(' ', '').astype(float)
ax1.plot(stock_data['年份'], stock_data['营业收入'], label=stock)
# 添加y轴标签、图例和标题
ax1.set_xlabel('年份', fontproperties=font)
ax1.set_ylabel('营业收入', color='tab:red', fontproperties=font)
ax1.tick_params(axis='y', labelcolor='tab:red')
ax1.legend(loc='upper left', bbox_to_anchor=(1.02, 1), borderaxespad=0, prop=font)
ax1.set_title('营业收入随时间的变化趋势图', fontproperties=font)
# 显示图形
plt.show()
# 绘制每个公司的营业收入
for stock in stocks:
stock_data = data[data['股票简称'] == stock]
# 将字符串中的逗号替换为空格,并将列类型转换为浮点数
stock_data['基本每股收益'] = stock_data['基本每股收益'].str.replace(',', '')
stock_data['基本每股收益'] = stock_data['基本每股收益'].str.replace(' ', '').astype(float)
ax1.plot(stock_data['年份'], stock_data['基本每股收益'], label=stock)
# 添加y轴标签、图例和标题
ax1.set_xlabel('年份', fontproperties=font)
ax1.set_ylabel('基本每股收益', color='tab:red', fontproperties=font)
ax1.tick_params(axis='y', labelcolor='tab:red')
ax1.legend(loc='upper left', bbox_to_anchor=(1.02, 1), borderaxespad=0, prop=font)
ax1.set_title('基本每股收益随时间的变化趋势图', fontproperties=font)
# 显示图形
plt.show()
# 4. 所有公司所有年份绘制在一张图上-柱形图
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"HYPengPengCheW.ttf", size=14)
plt.rcParams["font.family"] = "sans-serif"
plt.rcParams["axes.unicode_minus"] = False
df = pd.read_csv('公司.csv') # 读取文件
# 转换为string类型
df['营业收入'] = df['营业收入'].astype(str)
# 使用.str方法去除','
df['营业收入'] = df['营业收入'].str.replace(',', '')
# 将字符串中的逗号替换为空格,并将列类型转换为浮点数
df['营业收入'] = df['营业收入'].str.replace(',', '')
df['营业收入'] = df['营业收入'].str.replace(' ', '').astype(float)
df['基本每股收益'] = df['基本每股收益'].astype(float)
# 获取不同年份的营业收入情况
year_revenue = df.pivot_table(index='年份', columns='股票简称', values='营业收入')
year_revenue.plot(kind='bar')
plt.title('营业收入对比图', fontproperties=font)
plt.xlabel('年份', fontproperties=font)
plt.ylabel('营业收入', fontproperties=font)
plt.legend(prop=font)
plt.show()
# 获取不同年份的基本每股收益情况
year_eps = df.pivot_table(index='年份', columns='股票简称', values='基本每股收益')
year_eps.plot(kind='bar')
plt.title('基本每股收益对比图', fontproperties=font)
plt.xlabel('年份', fontproperties=font)
plt.ylabel('基本每股收益', fontproperties=font)
plt.legend(prop=font)
plt.show()
专业技术服务业在国内发展几十年,发展速度一直比较缓慢,且服条企业众多,竞争比较激烈,没有形成具备绝对优势的龙头企业。目前看来,软件和信息技术服务业竞争较为充分而智慧城市的发展空间较大。数字产业化将持续引领软件、信息技术服务业的发展。营业收入分析,从图来看,这十家公司营业收入整体呈现增长趋势,除*ST柏龙公司在 2021及 2022 年营业收入有大幅度的下降。另外,甘咨询和贝瑞基因两家公司近些年营业收入比较稳定,而其他公司的同比变化幅度较大;
每股收益分析,十家公司比较来看,近几年新上市的公司,如中设股份、地铁设计、开普检测的每股收益情况较好。而华控赛格、*ST柏龙、延华智能这三家公司的每股收益连续几年呈现负值,说明公司盈利能力还需要提高。
通过这一个学期的学习,我对Python有了更深入全面的了解。虽然之前有接触过Python,但更多停留在语法和API的层面,没有真正理解其内部的工作机制。这门课程让我对Python的运行原理有了系统的认知,老师耐心细致的讲解让我受益匪浅。
尤其是期末的项目报告,让我有机会将所学知识综合应用,虽然一开始手忙脚乱,不停地询问同学和参考前辈的作品,但最终还是制作出了一个初步的成果。在此过程中,我不仅加深了对Python的理解,也学会了如何通过图文并茂的方式展现复杂的代码和概念。我很高兴通过这门课程进一步掌握Python,同时也给我继续学习的动力和信心。
Python的世界广袤无垠,我只是初窥门径,但这精彩的学习之旅已经开始。老师悉心的教导和同学们的切磋将是我进步的阶梯,我会继续努力,在这条学习之路上不断前行。这门课程是我编程生涯的重要一步,我将持之以恒,精益求精。
总之,这是一个学期我收获颇丰,不仅在知识与技能上有所提高,更在学习态度与思维模式上有所成长。我衷心感谢老师和同学们在这个学期对我的帮助,你们是我成长的重要推手,也是我继续努力的动力源泉。这段学习体验将成为我宝贵的财富,在未来的人生旅途中不断启迪和激励我。