巨潮资讯分析

巨潮资讯分析

(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 = '(.*?)'
    title = re.findall(p_title, data)
    # 获取网页网址
    p_href = ' + 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:

        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=[]

                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]

                    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
                                    except:
                                        continue
                pdf.close()

                print('****time to processing PDF file is ')
            else:
                path =os.path.join(OUT_DIR,file_name)

    return name_find,value_find,page_find
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:

        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():

                        data_list = data.strip().split()
                        for j in range(len(data_list)):
                                    if inside_keyword in data_list[j]:

                                        print('提取'+f'{inside_keyword}'+'中')
                                        if len(data_list[j])<7:
                                            print(data_list[j],data_list[j+1])

                                            try:
                                                parase_out_writer.writerows([[file_name, data_list[j],data_list[j + 1]]])
                                            except:
                                                pass
                                            parase_out.flush()

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.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['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')

date = df['year']
data=df['number1']
plt.bar(date,data,width=0.5,alpha=0.5)
plt.title("主营业务收入和营业收入",fontproperties=font_set)

柱状图的绘制

巨潮资讯分析

总结

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

Original: https://blog.csdn.net/h123456789999999/article/details/122504416
Author: 红糖番薯
Title: 巨潮资讯分析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/699384/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球