案例2:东方财富股吧文本分析----code模块封装命令行运行版

案例2:东方财富股吧文本分析----code模块封装命令行运行版

  • 0. 先导语
  • 1.东方财富股吧文本信息爬取
    • 1.1 模块getGuBaNews.py的内容
    • 1.2 东方财富股吧文本信息爬取主运行文件run_main_getnews.py内容
    • 1.3 命令行运行
  • 2.东方财富股吧文本信息分析
    • 2.1 模块gubaNewsAnalyse.py的内容
    • 2.2 东方财富股吧文本信息分析主运行文件run_main_gubaNews.py内容
    • 2.3 命令行运行

0. 先导语

Python代码模块化是指将大型的代码分割成小的、可重用的代码块,这些代码块被称为模块。模块可以通过import语句导入到其他代码中,从而提供了一种有效的组织和重用代码的方法。Python代码模块化有以下几个好处:

  • 1. 提高代码的可读性和可维护性:模块化将代码分解为更小、更容易理解的组件,可以更容易地理解每个模块所做的工作,使得代码更加清晰易懂,提高代码的可读性。可以更容易地找到和修复问题。有助于代码的可维护性。

  • 2. 降低代码的复杂度:模块化使得代码更加模块化、组合和重用,从而降低了代码的复杂度,避免了代码过于臃肿和混乱。可以更容易地管理代码,并且可以更容易地添加、修改或删除功能。

  • 3. 加快开发效率:模块化使得代码可以被多个人共同开发和维护,从而加快了开发效率。

  • 4. 提高代码的可重用性:模块化使得代码可以被多个程序和项目共同使用,如果需要多次使用相同的代码,只需要将代码保存在一个模块中,然后在需要的地方导入即可。从而提高了代码的可重用性,减少了重复开发的工作。

  • 5. 便于测试和调试:模块化将代码分解为更小的组件,可以更容易地编写单元测试,使得测试和调试变得更加容易,以确保每个模块都按照预期工作。从而提高了程序的稳定性和可靠性。

总的来说,代码模块化是一个非常重要的编程技巧,能够使得代码更加清晰易懂、可维护性更高、开发效率更高、可重用性更高,也更容易测试和调试。

1.东方财富股吧文本信息爬取

1.1 模块getGuBaNews.py的内容

getGuBaNews.py下载地址

python">import requests
from bs4 import BeautifulSoup
import pandas as pd
import time

headers={
    "User-Agent":"你自己的User-Agent",
    "Cookie":"你自己的Cookie"
    }

# 获取单页股吧新闻
def get_guba_news_onePage(url):
    response=requests.get(url=url,headers=headers)
    html_content = response.text
    soup = BeautifulSoup(html_content, "html.parser")
    guba_news = soup.find('div', {'id': 'articlelistnew'})
    read_num = []
    for read in guba_news.find_all('span', {'class': 'l1 a1'})[1:]:
        if '万' in read.text:
            read_num.append(int(float(read.text.replace('万', '')) * 10000))
        else:
             read_num.append(int(read.text))
    comment_num = []
    for comment in guba_news.find_all('span', {'class': 'l2 a2'})[1:]:
        if '万' in comment.text:
            comment_num.append(int(float(comment.text.replace('万', '')) * 10000))
        else:
             comment_num.append(int(comment.text))
    title_content = list(map(lambda x:x.text,guba_news.find_all('span', {'class': 'l3 a3'})[1:]))
    author_name = list(map(lambda x:x.text,guba_news.find_all('span', {'class': 'l4 a4'})[1:]))
    update_time = list(map(lambda x:'2023-'+x.text,guba_news.find_all('span', {'class': 'l5 a5'})[1:]))
    guba_news = pd.DataFrame({
        'read_num': read_num,
        'comment_num': comment_num,
        'title_content':title_content,
        'author_name':author_name,
        'update_time':update_time 
    })
    return guba_news

def get_guba_news_batch(stockID,start_page,end_page):
    save_file = './data/guba_news_'+stockID+f'_pages{start_page}-{end_page}'+'.csv'
    for page_num in range(start_page,end_page+1):
        time.sleep(1)
        url = "https://guba.eastmoney.com/list,{}_{}.html".format(stockID,page_num)
        if page_num==start_page:
            guba_news = get_guba_news_onePage(url)
            guba_news.to_csv(save_file, index=False)
            print(f'第{page_num}页数据已保存。')
        else:
            guba_news = pd.concat([pd.read_csv(save_file), get_guba_news_onePage(url)], axis=0)
            guba_news.to_csv(save_file, index=False)
            print(f'第{page_num}页数据已保存。')

1.2 东方财富股吧文本信息爬取主运行文件run_main_getnews.py内容

run_main_getnews.py下载地址

python">import getGuBaNews
import warnings
warnings.filterwarnings('ignore')
import sys

stockID = sys.argv[1]
start_page = int(sys.argv[2])
end_page = int(sys.argv[3])
getGuBaNews.get_guba_news_batch(stockID,start_page,end_page)

1.3 命令行运行

在这里插入图片描述
在文件getGuBaNews.py和run_main_getnews.py的同级目录下shift_右键打开PowerShell 窗口,然后输入下面的命令运行:

python">python run_main_getnews.py 601318 1 30

601318 1 30分别表示run_main_getnews.py中需要输入的三个参数:

  • stockID = sys.argv[1]
  • start_page = int(sys.argv[2])
  • end_page = int(sys.argv[3])

多个参数之间用空格分开

2.东方财富股吧文本信息分析

2.1 模块gubaNewsAnalyse.py的内容

gubaNewsAnalyse.py下载地址

python">import pandas as pd
import re
import matplotlib.pyplot as plt
import seaborn as sns
import jieba
from wordcloud import WordCloud
from snownlp import SnowNLP, sentiment#情感分析库
import networkx as nx
#中文字符设定
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False

def loadData(file):
    guba_news = pd.read_csv(file)
    guba_news['update_time'] = pd.to_datetime(guba_news['update_time'], format='%Y-%m-%d %H:%M:%S')
    return guba_news

def hotTopicAnalyse(df,top_num=10):
    # 按照阅读数排序
    guba_news = df.sort_values(by='read_num', ascending=False)

    # 获取前20条数据
    top = guba_news.head(top_num)
    print('热门话题排行榜:')
    print(top)

    # 绘制阅读数和评论数的关系图
    plt.figure(figsize=(8, 6))
    sns.scatterplot(x=guba_news['read_num'], y=guba_news['comment_num'])
    plt.title('阅读数与评论数的关系')
    plt.xlabel('阅读数')
    plt.ylabel('评论数')
    plt.show()

    # 分词
    text = ' '.join(guba_news['title_content'].tolist())
    words = list(jieba.cut(text))

    # 去除停用词
    stopwords = [' ','[',']',',', '。', '!', '?', '的', '了', '在', '是', '我', '你', '他', '她', '它', '我们', '你们', '他们', '她们', '它们','今天','明天','中国','平安','都','资讯','2023']
#     stopwords = pd.read_csv("data/stopwords.txt",index_col=False,quoting=3,sep="\t",names=['stopword'],encoding='utf-8')  #quoting=3全部引用
    words = [w for w in words if w not in stopwords and len(w)>=2]
    word_count = {}
    for word in words:
        if word in word_count:
            word = re.escape(word)
            word_count[word] += guba_news[guba_news['title_content'].str.contains(word)]['read_num'].sum()
        else:
            word = re.escape(word)
            word_count[word] = guba_news[guba_news['title_content'].str.contains(word)]['read_num'].sum()

    # 绘制主题词词云图
    wordcloud = WordCloud(width=800,height=600,background_color="white",font_path="msyh.ttc")
    wordcloud.generate_from_frequencies(word_count)
    plt.imshow(wordcloud, interpolation="bilinear")
    plt.axis("off")
    plt.show()
    return word_count


def investSentimentAnalyse(df, sentiment_thres=0.5):
    titles = df['title_content'].tolist()
    sentiments = []
    for title in titles:
        s = SnowNLP(title)
        sentiments.append(s.sentiments)

    # 统计情感分布
    positive_num = len(
        [sentiment for sentiment in sentiments if sentiment > sentiment_thres])
    negative_num = len(
        [sentiment for sentiment in sentiments if sentiment < sentiment_thres])
    neutral_num = len([
        sentiment for sentiment in sentiments if sentiment == sentiment_thres
    ])

    # 输出结果
    print(f'积极评论数:{positive_num},占比:{positive_num/len(sentiments):.2%}')
    print(f'消极评论数:{negative_num},占比:{negative_num/len(sentiments):.2%}')
    print(f'中性评论数:{neutral_num},占比:{neutral_num/len(sentiments):.2%}')


def postTimeAnalyse(df):
    # 统计每个小时的帖子数量
    post_count_by_hour = df.groupby(df['update_time'].dt.hour)['title_content'].count()

    # 统计每个小时的评论数量
    comment_count_by_hour = df.groupby(df['update_time'].dt.hour)['comment_num'].sum()

    # 统计每天的帖子数量
    post_count_by_day = df.groupby(df['update_time'].dt.date)['title_content'].count()

    # 统计每天的评论数量
    comment_count_by_day = df.groupby(df['update_time'].dt.date)['comment_num'].sum()

    # 可视化绘制图表
    fig, ax = plt.subplots(2, 2, figsize=(10, 6))
    post_count_by_hour.plot(ax=ax[0, 0], title='帖子数量按小时统计')
    comment_count_by_hour.plot(ax=ax[0, 1], title='评论数量按小时统计')
    post_count_by_day.plot(ax=ax[1, 0], title='帖子数量按天统计')
    comment_count_by_day.plot(ax=ax[1, 1], title='评论数量按天统计')
    plt.tight_layout()
    plt.show()
    
def topicRelationAnalyse(df,top_num=10):
    # 将主题进行分词
    df['seg_title'] = df['title_content'].apply(lambda x: ' '.join(jieba.cut(x)))

    text = ' '.join(df['title_content'].tolist())
    words = list(jieba.cut(text))
    # 去除停用词
    stopwords = [' ','[',']',',', '。', '!', '?', '的', '了', '在', '是', '我', '你', '他', '她', '它', '我们', '你们', '他们', '她们', '它们','今天','明天','中国','平安','都','资讯','2023']
    words = [w for w in words if w not in stopwords and len(w)>=2]

    word_count={}
    for word in words:
        if word in word_count:
            word_count[word]+= df[df['title_content'].str.contains(word)]['read_num'].sum()
        else:
            word_count[word] = df[df['title_content'].str.contains(word)]['read_num'].sum()
        
    # 取出出现次数最多的前top_num个词汇
    sorted_word_count = sorted(word_count.items(), key=lambda x: x[1], reverse=True)
    top_words = [x[0] for x in sorted_word_count[:top_num]]
    print(f"出现次数最多的前{top_num}个词汇:")
    print(top_words)
    df['seg_title'] = df['title_content'].apply(lambda x: ' '.join(jieba.cut(x)))


    # 构建图
    G = nx.Graph()
    for text in df['seg_title']:
        words = set(text.split())
        for word1 in words:
            if word1 in top_words:
                for word2 in words:
                    if word1 != word2 and word2 in top_words:
                        if G.has_edge(word1, word2):
                            G[word1][word2]['weight'] += 1
                        else:
                            G.add_edge(word1, word2, weight=1)

    # 绘制图
    plt.figure(figsize=(10, 10))
    pos = nx.spring_layout(G, k=0.5)
    nx.draw_networkx_nodes(G, pos, node_size=2000, node_color='lightblue')
    nx.draw_networkx_edges(G, pos, width=[G[u][v]['weight']*0.1 for u, v in G.edges()])
    nx.draw_networkx_labels(G, pos, font_size=20, font_family='Microsoft YaHei')
    plt.axis('off')
    plt.show()
def userActionAnalyse(df,top_post_user_Num=10):
    
    # 统计每个作者的发帖数量、阅读数和评论数量
    author_post_count = df.groupby('author_name')['title_content'].count()
    read_count = df.groupby('author_name')['read_num'].sum()
    comment_count = df.groupby('author_name')['comment_num'].sum()

    # 合并数据
    df1 = pd.concat([author_post_count,read_count,comment_count], axis=1)
    df1.columns = ['发帖数', '阅读数','评论数']
    # 根据发帖数进行排序
    df1 = df1.sort_values(by='发帖数', ascending=False)
    df_topUser = df1[1:1+top_post_user_Num]

    # 分析每个作者的平均发帖和评论时间间隔

    filtered_author_df = df[df['author_name'].isin(list(df_topUser.index))]
    df_sorted = filtered_author_df.sort_values(['author_name', 'update_time'])
    df_sorted['time_interval'] = df_sorted.groupby('author_name')['update_time'].diff().dt.total_seconds()

    # 可视化作者发帖数量和评论数量
    fig, ax = plt.subplots(2, 2, figsize=(10, 10))

    df_topUser['发帖数'].plot(kind='bar', ax=ax[0, 0])
    ax[0, 0].set_title('作者发帖数')
    ax[0, 0].set_xlabel('作者')
    ax[0, 0].set_ylabel('发帖数')

    df_topUser['阅读数'].plot(kind='bar', ax=ax[0, 1])
    ax[0, 1].set_title('作者帖子阅读数')
    ax[0, 1].set_xlabel('作者')
    ax[0, 1].set_ylabel('阅读数')

    df_topUser['评论数'].plot(kind='bar', ax=ax[1, 0])
    ax[1, 0].set_title('作者帖子评论数')
    ax[1, 0].set_xlabel('作者')
    ax[1, 0].set_ylabel('评论数')

    # 可视化每个作者的平均发帖和评论时间间隔
    author_mean_time_interval = df_sorted.groupby('author_name')['time_interval'].mean().dropna()
    author_mean_time_interval.plot(kind='bar', ax=ax[1, 1])
    ax[1, 1].set_title('作者发帖的平均时间间隔')
    ax[1, 1].set_xlabel('作者')
    ax[1, 1].set_ylabel('时间间隔 (秒)')

    plt.tight_layout()
    plt.show()
    return df1

2.2 东方财富股吧文本信息分析主运行文件run_main_gubaNews.py内容

run_main_gubaNews.py下载地址

python">import warnings
warnings.filterwarnings('ignore')
import sys
import gubaNewsAnalyse as gna
file = sys.argv[1]
what_analyse = sys.argv[2]

df = gna.loadData(file)
what_analyse = what_analyse.split('#')

if '1' in what_analyse:
    print('正在进行热门话题分析>>>>>>>>>>>>>>>>>>')
    gna.hotTopicAnalyse(df)
if '2' in what_analyse:
    print('正在进行投资情绪分析>>>>>>>>>>>>>>>>>>')
    gna.investSentimentAnalyse(df)
if '3' in what_analyse:
    print('正在进行发帖时间分析>>>>>>>>>>>>>>>>>>')
    gna.postTimeAnalyse(df)
if '4' in what_analyse:
    print('正在进行热门主题关联分析>>>>>>>>>>>>>>>>>>')
    gna.topicRelationAnalyse(df)   
if '5' in what_analyse:
    print('正在进行用户行为分析>>>>>>>>>>>>>>>>>>')
    gna.userActionAnalyse(df)
    
print('已完成所有分析!')

2.3 命令行运行

在这里插入图片描述
多个参数之间用空格分开

在文件gubaNewsAnalyse.py和run_main_gubaNews.py的同级目录下shift+右键打开PowerShell 窗口,然后输入下面的命令运行:

python run_main_gubaNews.py './data/guba_news_601318_pages1-30.csv' 1#3

‘./data/guba_news_601318_pages1-30.csv’ 1#3分别表示run_main_gubaNews.py中需要输入的两个参数:

  • file = sys.argv[1] #数据文件路径及文件名
  • what_analyse = sys.argv[2] #需要执行的一种或多种文本分析

若仅执行其中一种文本分析(如2:投资情绪分析)则直接:

python run_main_gubaNews.py './data/guba_news_601318_pages1-30.csv' 2

若执行其中某几种文本分析(如2:投资情绪分析,3:发帖时间分析,5:用户行为分析)则用#连接各文本分析对应的数字代码即可:

python run_main_gubaNews.py './data/guba_news_601318_pages1-30.csv' 2#3#5

http://www.niftyadmin.cn/n/292702.html

相关文章

破事精英2◎爬向未来

胡强的2033未免有些过去可怕&#xff0c;海星果然又是反派。 只剩“脑子”的胡强 400百斤只剩“嘴”的庞小白 将自己身体分成一个个“方块”的苏克杰 苍蝇满天飞“衣服堆”的金若愚 “脑子”送到月球打两份工的沙乐乐 有机器人或者分身帮我们干活赚钱&#xff0c;我们去吃喝玩…

第四十九章 管理镜像 - 停止备份和异步成员的镜像

文章目录 第四十九章 管理镜像 - 停止备份和异步成员的镜像停止备份和异步成员的镜像管理数据库取消日志记录在备份或 DR 异步上管理取消日志在报告异步上管理取消日志 第四十九章 管理镜像 - 停止备份和异步成员的镜像 停止备份和异步成员的镜像 可以暂时停止在备份或异步成…

Baumer工业相机堡盟工业相机如何联合BGAPISDK和Halcon实现图像的Pow伽马变换算法增强(C#)

Baumer工业相机堡盟工业相机如何联合BGAPISDK和Halcon实现图像的Pow伽马变换算法增强&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机使用图像算法增加图像的技术背景Baumer工业相机通过BGAPI SDK联合Halcon使用Pow伽马变换增强算法1.引用合适的类文件2.BGAPI SDK在图…

pytorch——损失函数之nn.BCELoss二进制交叉熵和 nn.BCEWithLogitsLoss

文章目录 1、pytorch损失函数之nn.BCELoss()&#xff08;二进制交叉熵)1.1 是什么&#xff1f;1.2 怎么代码实现和代码使用&#xff1f;1.3 推导过程分析交叉熵作为损失函数的梯度情况&#xff1a;举一个sigmoid导致的梯度消失的MSE损失的例子 1.3 应用场景1.3.1 二分类1.3.2 多…

传奇人物《周兴和》书连载之67 不辱神圣的使命

不辱神圣的使命 这里&#xff0c;先前还是一个十分神秘的地方。 外人和车辆要想进入这片区域&#xff0c;那是绝对不允许的。这片区域隐于群山之中&#xff0c;且戒备森严&#xff0c;外人若想进入&#xff0c;那是要经过好几道政治审查和随身检查的。近年来&#xff0c;随着…

网络编程 | 多进程多线程并发服务器代码实现

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

JavaScript数组方法 find() ,使用详细(js的 find() 方法)

简介&#xff1a;find() 方法是 JavaScript 中用于在数组中查找特定条件的第一个元素&#xff0c;如果找到一个元素使得回调函数返回true&#xff0c;则该元素作为结果返回&#xff1b;如果没有找到这样的元素&#xff0c;则返回undefined&#xff0c;该函数不会修改原始数组。…

每天一道算法练习题--Day21 第一章 --算法专题 --- ----------位运算

我这里总结了几道位运算的题目分享给大家&#xff0c;分别是 136 和 137&#xff0c; 260 和 645&#xff0c; 总共加起来四道题。 四道题全部都是位运算的套路&#xff0c;如果你想练习位运算的话&#xff0c;不要错过哦&#xff5e;&#xff5e; 前菜 开始之前我们先了解下…