巨潮资讯分析

巨潮资讯分析


(1) 爬取巨潮资讯万科A网站下载pdf
(2)从pdf中筛选指定字段
(3)利用python进行可视化分析


前言

博主最近接的一个单子的需求需要是爬取巨潮资讯中指定公司的年度报告pdf并且下载下来再对pdf筛选指定字段再进行可视化分析


鉴于预算问题可视化分析就使用了最基本的几个图表例如散点图
折线图 以及柱状图

一、先对巨潮资讯网页进行分析

爬虫和反爬虫的斗争都是无时无刻的这个网页的反爬机制我做的时候就遇见了两个
1.网页在翻页的时候url是没有变化的
观察图片上方
在这里插入图片描述
观察这两张图片的url是没有变化的
通过这么分析我们可以使用两种方法一种是利用post请求进行获取网页源代码
第二种就是利用python的selenium库进行分析

2.网页每刷新一次不是立刻就能刷新出数据来的
今天博主使用的就是第二种方法 方法过多就不一一讲解了

(1)、功能准备

1.引入库

代码如下(示例):

import re
import time
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By

使用selenium的话需要在电脑上自行安装对应浏览器的驱动除了系统自带的库都需要使用pip install 进行安装

2.代码如下

代码如下(示例):

list = []
def page_turn():
    url = 'http://www.cninfo.com.cn/new/disclosure/stock?orgId=gssz0000002&stockCode=000002#latestAnnouncement'
    browser.get(url)
    time.sleep(1)
    browser.find_element(By.XPATH,'//*[@id="main"]/div[3]/div/div[2]/div/div/div[2]/div[1]/div[1]/form/div[2]/div/span/button').click()
    browser.find_element(By.CLASS_NAME, 'cate-checkbox-txt').click()
    browser.find_element(By.XPATH,'//*[@id="main"]/div[3]/div/div[2]/div/div/div[2]/div[1]/div[4]/div/div/button[2]').click()
    time.sleep(1)
    data = browser.page_source
    print("执行翻页操作")
    return data

    # if page_next =
def search(data):
    # 获取网页源代码
    # 获取网页标题
    p_title = '<span class="r-title">(.*?)</span>'
    title = re.findall(p_title, data)
    # 获取网页网址
    p_href = '<div class="cell"><a target="_blank" href="(.*?)" data-id='
    href = re.findall(p_href, data)
    for index in range(len(href)):
        # 网址清理
        href[index] = 'http://www.cninfo.com.cn' + href[index]
        href[index] = re.sub('amp;', '', href[index])
        # pdf文件下载
        res = requests.get(url=href[index])
        path = "问询函//" + title[index] + ".pdf"
        # print(path)
        print(href[index])
        list.append(href[index])
        try:
            for i in list:
                browser.get(i)
                browser.find_element(By.XPATH,'//*[@id="noticeDetail"]/div/div[1]/div[3]/div[1]/button').click()
            print("第" + str(index + 1) + "号文件爬取成功!")
        except:
            print("不是pdf版本")
def main():
        url = 'http://www.cninfo.com.cn/new/disclosure/stock?orgId=gssz0000002&stockCode=000002#latestAnnouncement'
        browser.get(url)
        time.sleep(1)
        browser.find_element(By.XPATH,'//*[@id="main"]/div[3]/div/div[2]/div/div/div[2]/div[1]/div[1]/form/div[2]/div/span/button').click()
        browser.find_element(By.CLASS_NAME,'cate-checkbox-txt').click()

        time.sleep(1)
        data = browser.page_source
        return data
if __name__ == "__main__":
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--headless')
    #设置下载路径
    prefs = {'profile.default_content_settings.popups': 0 ,'download.default_directory':r'c:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf'}
    chrome_options.add_experimental_option('prefs',prefs)
    browser = webdriver.Chrome(options=chrome_options)
    main()
    search(main())
    page_turn()
    search(page_turn())

该处使用的是利用selenium进行pdf下载


二、对指定字段进行筛选写入csv中

引入库

import pdfplumber
import os
import csv

代码如下

import pdfplumber
import os
import csv
def parase_pdf(table_keyword,inside_keyword,outside_keyword):
   #全局变量
    global pdffile_list
    global parase_out_writer
    global parase_out
    global OUT_DIR
    global file_names
    while True:
        #rLock2.acquire()
        if len(file_names):
            print('--------{}---------'.format(len(file_names)))
            file_name=file_names[0]
            file_names.remove(file_name)
            if file_name.endswith('.PDF') or file_name.endswith('.pdf'):
                path =os.path.join(OUT_DIR,file_name)
                print('get pdf address')

                try:
                    pdf = pdfplumber.open(path,password='')
                except:
                    print("*************open pdf error*******************")
                print("*************open pdf*******************")

                find_table=0
                find_pre_table=0
                find_keyword=0
                find_keyword_outside=0
                name_find=[]
                value_find=[]
                page_find=[]
                #for page in pdf.pages:
                    #print(page.extract_text())
                begin_index=int(len(pdf.pages)/2)
                for i in range(begin_index,len(pdf.pages)):
                    if find_table:
                        find_pre_table=1
                    else:
                        find_pre_table=0
                    find_table=0
                    page=pdf.pages[i]
                    #print(page.extract_text())
                    data=page.extract_text()
                    if len(table_keyword):
                        for keyword in table_keyword:
                            if keyword in data:
                                find_table=1
                            else:
                                find_table=0
                                break
                    else:
                        find_table=1

                    if find_table or find_pre_table:
                        data_list=data.strip().split()
                        for j in range(len(data_list)):
                            if len(inside_keyword):
                                for keyword in inside_keyword:
                                    if keyword in data_list[j]:
                                        find_keyword=1
                            else:
                                find_keyword=1

                            if find_keyword:
                                find_keyword=0
                                print('run here')
                                if len(outside_keyword):
                                    for keyword in outside_keyword:
                                        if keyword not in data_list[j]:
                                            find_keyword_outside=1
                                        else:
                                            find_keyword_outside=0
                                            break
                                else:
                                    find_keyword_outside=1

                                if find_keyword_outside:
                                    find_keyword_outside=0
                                    try:
                                        temp_value=data_list[j+1]
                                        temp_value=temp_value.replace(',','')
                                        temp_value=float(temp_value)
                                        name_find.append(data_list[j])
                                        value_find.append(temp_value)
                                        page_find.append(i)
                                        try:
                                            parase_out_writer.writerows([[file_name,data_list[j],str(temp_value),data_list[j+1],str(i)]])
                                        except:
                                            pass
                                        parase_out.flush()
                                        print("*****find******{} value is {} and {}".format(data_list[j],data_list[j+1],temp_value))
                                        print("*************find in page {}*******************".format(i))
                                        print("*************find in {}*******************".format(path))
                                        break        # only find one result
                                    except:
                                        continue
                pdf.close()
                # os.remove(path)    #  pdf.close 后删除文件 否则太多了
                print('****time to processing PDF file is ')
            else:
                path =os.path.join(OUT_DIR,file_name)
                # os.remove(path)
    return name_find,value_find,page_find    # 一定不要把return放到while里面,遇到return会立即结束 #str(time.strftime('%Y-%m-%d'))
OUT_DIR = r'公告pdf'
table_keyword=['利润表']
inside_keyword=['营业收入']
outside_keyword=['收到']
# ,'营业利润','资产负债率'
file_names=os.listdir(OUT_DIR)
parase_out_file_path=OUT_DIR+'/parase_out_file2.csv'
parase_out=open(parase_out_file_path, 'w', newline='', encoding='utf-8')
parase_out_writer = csv.writer(parase_out)
parase_pdf(table_keyword,inside_keyword,outside_keyword)
import pdfplumber
import os
import csv
inside_keyword = '资产负债率'
def parase_pdf(inside_keyword):

    global pdffile_list
    global parase_out_writer
    global parase_out
    global OUT_DIR
    global file_names
    while True:
        # rLock2.acquire()
        if len(file_names):
            print('--------{}---------'.format(len(file_names)))
            file_name = file_names[0]
            file_names.remove(file_name)
            if file_name.endswith('.PDF') or file_name.endswith('.pdf'):
                path = os.path.join(OUT_DIR, file_name)
                print('get pdf address')
                try:
                    pdf = pdfplumber.open(path,password='')
                except:
                    print("*************open pdf error*******************")
                print("*************open pdf*******************")
                for page in pdf.pages:
                    data = page.extract_text()
                    if inside_keyword in page.extract_text():
                        # print(page.extract_text())
                        data_list = data.strip().split()
                        for j in range(len(data_list)):
                                    if inside_keyword in data_list[j]:
                                        # print(data_list)
                                        print('提取'+f'{inside_keyword}'+'中')
                                        if len(data_list[j])<7:
                                            print(data_list[j],data_list[j+1])
                                            # print(len(data_list[j]))
                                            try:
                                                parase_out_writer.writerows([[file_name, data_list[j],data_list[j + 1]]])
                                            except:
                                                pass
                                            parase_out.flush()
# print(dict(data_list))
OUT_DIR = r'公告pdf'
file_names=os.listdir(OUT_DIR)
parase_out_file_path=OUT_DIR+'/parase_out_file5.csv'
parase_out=open(parase_out_file_path, 'w', newline='', encoding='utf-8')
parase_out_writer = csv.writer(parase_out)
parase_pdf(inside_keyword)

总结

提示:这里对pdf内容提取进行总结:
因为博主要提取的资产负债率是百分比和营业收入和营业利润有区别所以将二者分开提取之后如果需要应用的 话将路径改为自己的文件路径

三、对csv里的数据进行可视化分析

(1)
我们从pdf里面提取的数据仍然是不规整的这时候怎么办呢
就得给它进行数据清洗和数据规整了
直接上代码

第一步

import pandas as pd
import re
df = pd.read_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file2.csv'),header=None,names=['id','earning','number1','number2']新增表头

第二步

df['year'] = df['name'].apply(lambda x: re.findall(r'\d{4}',x)[0])#新增年份列
df.to_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file2.csv',index=False)
df

在这里插入图片描述
这样看起来是不是舒服老多了博主目测强迫症一枚

df = pd.read_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file2.csv')
# df.to_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file2.csv',index=False)
df.sort_values("year",ascending=True,inplace=True)#根据年份进行排序
df.to_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file2.csv',index=False)
df1 = pd.read_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file3.csv')
df1.sort_values("year",ascending=True,inplace=True)#根据年份进行排序
df1.to_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file3.csv',index=False)
df1

在这里插入图片描述

df3 = pd.read_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file4.csv')
# df3.to_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file4.csv',index=False) 保存
df3['year'] = df3['name'].apply(lambda x: re.findall(r'\d{4}',x)[-1])#提取年份
df3.sort_values("year",ascending=True,inplace=True)#根据年份进行排序
df3.to_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file4.csv',index=False)
df3
df3.drop_duplicates('data',keep='first',inplace=True)
df3.to_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file4.csv',index=False)
df3 #去重 三个表格都是此原理

这些数据虽然不多但是感觉有点乱乱的需要排序去重还需要添加行和列
(2)
第二步我们需要开始进行图表的绘制
引入我们所需要的库

import matplotlib
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocator

因为每个数据都是一个原理所以博主就不一一举例了

折线图的绘制

df = pd.read_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file2.csv')
plt.figure(figsize=(16,6))
ax=plt.gca()
x_major_locator=MultipleLocator(1)#设置间隔
ax.xaxis.set_major_locator(x_major_locator)
plt.plot(df['year'],df['number1'],color='#A0522D',marker='o',label="营业收入",linewidth=2,linestyle="--")

在这里插入图片描述

散点图的绘制

引入我们需要的库

import matplotlib
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocator
df = pd.read_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file2.csv')
plt.figure(figsize=(16,6))
x=df['year']
y=df['number1']
ax=plt.gca()
x_major_locator=MultipleLocator(1)
ax.xaxis.set_major_locator(x_major_locator)
plt.scatter(x,y,alpha=0.5,marker='*',c='r',label="五角")

效果图
在这里插入图片描述

柱状图的绘制

引入库

import pandas as pd
import matplotlib.pyplot as plt
from numpy import arange
from matplotlib.font_manager import FontProperties
plt.style.use('fivethirtyeight')
df = pd.read_csv(r'C:\Users\13252\PycharmProjects\pythonProject\巨潮资讯\公告pdf\parase_out_file2.csv')
# df
date = df['year']
data=df['number1']
plt.bar(date,data,width=0.5,alpha=0.5)
plt.title("主营业务收入和营业收入",fontproperties=font_set)

柱状图的绘制
在这里插入图片描述

总结

每个图表的我只写出了一个csv数据绘制的图表其余的只需要照葫芦画瓢即可
萌新写代码可能有的地方没标注出来或者有的地方没写出来希望各位大神多多指出
有问题的可以私下找我私聊欢迎大家多多指正

  • 10
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红糖番薯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值