东方财富股吧文本爬取及分析案例

0. 先导语

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

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

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

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

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

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

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

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

1.1 模块getGuBaNews.py的内容

getGuBaNews.py下载地址
getGuBaNews.py文件中的函数 get_guba_news_onePage用下面的代码替换,之前的代码是东方财富贴吧之前网页结构的爬取code,现在网页进行了更新,所以爬取路径略有改动。

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('tbody', {'class': 'listbody'})
#     read_num = list(map(lambda x:x.text,guba_news.find_all('span', {'class': 'l1 a1'})[1:]))
    read_num = []
    for read in guba_news.find_all('div', {'class': 'read'})[1:]:
        if '万' in read.text:
            read_num.append(int(float(read.text.replace('万', '')) * 10000))
        else:
             read_num.append(int(read.text))
#     comment_num = list(map(lambda x:x.text,guba_news.find_all('span', {'class': 'l2 a2'})[1:]))
    comment_num = []
    for comment in guba_news.find_all('div', {'class': 'reply'})[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('div', {'class': 'title'})[1:]))
    author_name = list(map(lambda x:x.text,guba_news.find_all('div', {'class': 'author'})[1:]))
    update_time = list(map(lambda x:'2023-'+x.text,guba_news.find_all('div', {'class': 'update'})[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下载地址

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 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下载地址

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下载地址

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
  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用: 东方财富吧是一个提供票相关讨论的平台,您可以通过Python进行爬取其发贴数据。根据引用中的描述,您可以使用Python爬取东方财富吧的帖子信息,包括吧名称、阅读量、评论数、标题、作者和发帖时间。具体的步骤如下: 1. 使用Python的网络爬虫库(例如BeautifulSoup或Scrapy)访问东方财富吧网站,并获取页面的HTML内容。 2. 使用HTML解析库(例如BeautifulSoup或lxml)解析HTML内容,提取出帖子信息,例如吧名称、阅读量、评论数、标题、作者和发帖时间。 3. 将提取的帖子信息存储到一个数据结构(例如列表或字典)中,方便后续的分析和处理。 引用中提到了探索更复杂的实际案例,并通过实际项目提升数据分析能力。因此,对于您的需求,您可以进一步扩展爬取的功能,例如分析帖子的情绪指数、研究帖子的亮点回顾等,以获得更深入的数据分析结果。 最后,引用中给出了一个跨年份取月份对应时间戳的问题的解决方法。虽然这段代码与您的问题关系不大,但它提供了一个示例,展示了如何使用Python对时间进行处理和计算。 希望以上信息对您有所帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [东方财富吧标题爬取分析](https://blog.csdn.net/kun666666/article/details/115222647)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Python数据分析入门:掌握基本工具与技巧.md](https://download.csdn.net/download/pleaseprintf/88229437)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值