从《半日》到‘半生’:用Python爬虫+数据分析,可视化一个男孩‘半天’里的世界变迁

📅 2026/7/14 13:10:36 👁️ 阅读次数 📝 编程学习
从《半日》到‘半生’:用Python爬虫+数据分析,可视化一个男孩‘半天’里的世界变迁

从《半日》到‘半生’:用Python爬虫+数据分析,可视化一个男孩‘半天’里的世界变迁

文学作品中时间的流逝往往承载着深刻的隐喻。纳吉布·马哈福兹的短篇小说《半日》通过一个男孩入学半天的经历,展现了从田园牧歌到现代都市的剧烈变迁。这种时间压缩的艺术表现,恰好为技术爱好者提供了绝佳的数据分析素材。本文将带你用Python构建完整的文本分析流水线,从多版本译文爬取到情感波动可视化,量化文学中的"时间相对论"。

1. 数据采集:构建跨语言文本语料库

文学分析的首要挑战是获取足够质量的文本数据。《半日》作为诺贝尔文学奖得主的代表作,存在多个译本和解析版本。我们可以通过定向爬虫构建专属语料库:

import requests from bs4 import BeautifulSoup import pandas as pd def crawl_kekenet(url): headers = {'User-Agent': 'Mozilla/5.0'} response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') content = soup.find('div', {'class': 'qh_en'}).get_text(separator="\n") return content.strip() urls = [ 'http://www.kekenet.com/daxue/201612/48265.shtml', 'http://www.kekenet.com/daxue/201612/48267.shtml' ] corpus = [crawl_kekenet(url) for url in urls] df = pd.DataFrame({'text': corpus, 'source': urls})

表:常见文学文本数据源对比

数据源类型示例特点适用场景
教学网站解析可可英语带分段注释词法分析
电子书平台Kindle版本格式规范全文统计
学术论文JSTOR文献深度解读观点挖掘
读者评论Goodreads情感丰富受众分析

提示:文学类网站反爬机制较强,建议设置time.sleep(3)等延迟策略,并检查robots.txt协议

2. 文本预处理:从原始文字到结构化数据

获得原始文本后,需要将其转化为适合分析的结构化格式。中文文本需特别注意分词准确性:

import jieba from collections import Counter def preprocess_text(text): # 去除特殊字符 text = re.sub(r'[^\w\s]', '', text) # 加载自定义词典 jieba.load_userdict('custom_dict.txt') # 关键词提取 words = [word for word in jieba.cut(text) if len(word) > 1] return Counter(words) # 环境变迁关键词组 keywords = ['花园', '高楼', '汽车', '街道', '田野'] word_freq = preprocess_text(df['text'].str.cat(sep='\n'))

处理后的数据可生成词云直观展示:

from wordcloud import WordCloud import matplotlib.pyplot as plt wc = WordCloud(font_path='SimHei.ttf', width=800, height=400) wc.generate_from_frequencies(word_freq) plt.imshow(wc) plt.axis("off") plt.show()

关键预处理步骤:

  • 统一编码格式(UTF-8优先)
  • 处理特殊标点和换行符
  • 中英文停用词过滤
  • 词性标注和命名实体识别

3. 时空变迁的可视化呈现

小说最震撼的转折是放学后街道景观的巨变。我们可以用时间线图表量化这种变化:

import plotly.express as px # 构建时间线数据 timeline_data = [ {'time': '入学前', 'element': '花园', 'count': 12}, {'time': '入学前', 'element': '田野', 'count': 8}, {'time': '放学后', 'element': '高楼', 'count': 15}, {'time': '放学后', 'element': '汽车', 'count': 9} ] fig = px.bar(pd.DataFrame(timeline_data), x='time', y='count', color='element', title='《半日》前后环境元素对比') fig.show()

更精细的情绪分析可以揭示主人公心理变化:

from snownlp import SnowNLP sentiments = [SnowNLP(para).sentiments for para in text.split('\n') if para] plt.plot(range(len(sentiments)), sentiments) plt.xlabel('文本段落') plt.ylabel('情绪值')

表:关键场景数据分析结果

场景段落关键词密度情绪均值词汇多样性
上学路上0.420.68中等
校园生活0.370.54较高
街道巨变0.610.31较低

4. 深度分析:文学符号的计算解读

超越基础词频统计,我们可以运用更复杂的NLP技术揭示文本深层结构:

主题建模展示:

from sklearn.feature_extraction.text import CountVectorizer from sklearn.decomposition import LatentDirichletAllocation vectorizer = CountVectorizer(tokenizer=jieba.cut) dtm = vectorizer.fit_transform(df['text']) lda = LatentDirichletAllocation(n_components=3) lda.fit(dtm) for idx, topic in enumerate(lda.components_): print(f"主题{idx+1}:") print([vectorizer.get_feature_names_out()[i] for i in topic.argsort()[-5:]])

人物关系网络构建:

import networkx as nx relations = { '男孩': ['父亲', '母亲', '同学'], '父亲': ['男孩', '学校'], '街道': ['花园', '高楼'] } G = nx.Graph() for node, edges in relations.items(): for edge in edges: G.add_edge(node, edge) nx.draw(G, with_labels=True)

这类分析能揭示传统阅读难以发现的文本模式,比如:

  • 空间意象的对称分布
  • 情感曲线的突变点
  • 不同译本的语言特征差异

在完成分析后,可以考虑将结果打包为交互式HTML报告:

from jinja2 import Template template = Template(''' <!DOCTYPE html> <html> <head> <title>{{ title }}</title> <script src="https://cdn.plot.ly/plotly-latest.min.js"></script> </head> <body> <div id="chart">{{ plot_div }}</div> </body> </html> ''') html = template.render(title='《半日》分析报告', plot_div=fig.to_html(full_html=False)) with open('report.html', 'w') as f: f.write(html)

文学分析项目的独特之处在于需要平衡技术严谨性和艺术敏感性。在调试分词效果时,我发现对"红帽子"这样的复合词,机械切分会导致意象丢失,这促使我完善了自定义词典。而情绪分析曲线上的剧烈波动,恰好对应着小说中的关键转折段落,这种技术结果与文学批评的相互印证,正是数字人文最迷人的地方。