摘 要:為有效地收集、整理和利用高校數(shù)字文化資源,文章設(shè)計(jì)并實(shí)現(xiàn)了一個(gè)基于Python 3.9和Django 4.2架構(gòu)的高校微信公眾號(hào)資源管理平臺(tái)。平臺(tái)以高校相關(guān)的微信公眾號(hào)為主要內(nèi)容來源,利用網(wǎng)絡(luò)爬蟲、MySQL數(shù)據(jù)庫(kù),實(shí)現(xiàn)相關(guān)的數(shù)字文化資源的收集、存儲(chǔ),并利用深度學(xué)習(xí)框架的自然語(yǔ)言處理工具庫(kù)對(duì)資源進(jìn)行實(shí)體抽取形成多維度標(biāo)簽,實(shí)現(xiàn)對(duì)資源內(nèi)容的深度揭示與關(guān)聯(lián)化檢索。
關(guān)鍵詞:數(shù)字文化;Python;Django;ERNIE-UIE
中圖分類號(hào):TP311.1;G258.6 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):2096-4706(2024)20-0072-07
Design and Implementation of a University Resource Management Platform for WeChat Official Accounts Platform
LIN Li
(Minjiang University Library, Fuzhou 350108, China)
Abstract: This paper designs and implements a university resource management platform for WeChat official accounts platform based on Python 3.9 and Django 4.2, aiming at effectively collecting, sorting out and utilizing university digital cultural resources. The platform takes WeChat official accounts platforms related to colleges and universities as the main content sources, uses Web crawler and MySQL database to collect and store related digital cultural resources, and uses the natural language processing tool library of Deep Learning framework to extract entities from resources to form multi-dimensional tags, thus realizing in-depth disclosure and related retrieval of resource contents.
Keywords: digital culture; Python; Django; ERNIE-UIE
0 引 言
2022年5月中央辦公廳、國(guó)務(wù)院辦公廳印發(fā)《關(guān)于推進(jìn)實(shí)施國(guó)家文化數(shù)字化戰(zhàn)略的意見》,部署建設(shè)中華文化數(shù)據(jù)庫(kù)和文化數(shù)據(jù)服務(wù)平臺(tái)等重點(diǎn)任務(wù),將數(shù)字文化建設(shè)提升為國(guó)家戰(zhàn)略[1]。隨著數(shù)字化浪潮的深入發(fā)展,高校已成為數(shù)字文化資源的重要匯聚地。這些資源包括校史檔案、學(xué)術(shù)講座、校園活動(dòng)等豐富內(nèi)容,它們主要通過微信公眾號(hào)、視頻號(hào)等新媒體平臺(tái)進(jìn)行傳播[2]。然而,由于運(yùn)營(yíng)主體分散,缺乏統(tǒng)一的管理機(jī)制,這些資源的關(guān)聯(lián)性檢索與高效利用受到了一定的限制[3]。為此,本文設(shè)計(jì)并實(shí)現(xiàn)了一個(gè)基于Python 3.9和Django 4.2架構(gòu)的高校微信公眾號(hào)資源管理平臺(tái),旨在解決這一問題。
1 平臺(tái)設(shè)計(jì)
1.1 系統(tǒng)需求分析
高校微信公眾號(hào)資源管理平臺(tái)用于整合與高校相關(guān)的微信公眾號(hào)所發(fā)布的數(shù)字資源。一方面,與高校相關(guān)的微信公眾號(hào)運(yùn)營(yíng)主體分散,有的屬于學(xué)校相關(guān)職能機(jī)構(gòu)如教務(wù)處、科研處等,有的屬于學(xué)校各院系,有的屬于學(xué)生社團(tuán),有的屬于教工個(gè)人,還有的屬于校友,導(dǎo)致資源的共享性較差[4];另一方面,由于微信公眾號(hào)平臺(tái)在資源管理上主要以內(nèi)容展示為主,對(duì)于內(nèi)容主題檢索,特別是跨公眾號(hào)的內(nèi)容主題檢索支持有限,無(wú)法實(shí)現(xiàn)高校微信公眾號(hào)資源的統(tǒng)一檢索利用。因此平臺(tái)需實(shí)現(xiàn)以下功能:
1)將與高校相關(guān)的微信公眾號(hào)上的數(shù)字文化資源進(jìn)行統(tǒng)一聚合,對(duì)相關(guān)公眾號(hào)所發(fā)布資源進(jìn)行自動(dòng)化收集。
2)對(duì)收集的數(shù)字資源進(jìn)行統(tǒng)一存儲(chǔ)和元數(shù)據(jù)抽取,實(shí)現(xiàn)文本資源的數(shù)據(jù)化處理,生成資源的多維度標(biāo)簽。
3)支持基于分析數(shù)據(jù)的多維度檢索和圖譜化展示。
平臺(tái)功能結(jié)構(gòu)如圖1所示。
1.2 技術(shù)選型
平臺(tái)選擇Python作為開發(fā)語(yǔ)言,Django作為后臺(tái)框架。Python擁有強(qiáng)大而廣泛的第三方庫(kù)和框架支持,能夠滿足各種Web開發(fā)需求。開發(fā)者可以利用現(xiàn)成的工具和庫(kù),提高開發(fā)效率,減少重復(fù)勞動(dòng),使得Web應(yīng)用的構(gòu)建更加迅速和靈活[5]。選擇Django 4.2作為Web框架,Django是一個(gè)高度集成的Web框架,提供了大量的內(nèi)置組件和工具,包括ORM(對(duì)象關(guān)系映射)、模板引擎、表單處理等。此外,選擇MySQL 8.0作為關(guān)系型數(shù)據(jù)庫(kù),它具有良好的存儲(chǔ)和查詢性能[6]。選擇百度開源的ERNIE-UIE大模型,該模型實(shí)現(xiàn)了實(shí)體抽取、關(guān)系抽取、事件抽取、情感分析等任務(wù)的統(tǒng)一建模,并使得不同任務(wù)間具備良好的遷移和泛化能力,可以支持對(duì)不限定行業(yè)領(lǐng)域和抽取目標(biāo)的關(guān)鍵信息抽取[7]。選擇NetworkX作為圖譜庫(kù),它可以將知識(shí)點(diǎn)可視化為知識(shí)圖譜。
1.3 平臺(tái)架構(gòu)
平臺(tái)采用B/S架構(gòu)、模塊化設(shè)計(jì),如圖2所示,主要包括以下模塊:
1)數(shù)字資源的采集和處理模塊。負(fù)責(zé)自動(dòng)從微信公眾號(hào)、視頻號(hào)上爬取數(shù)字文化資源,并抽取出資源的元數(shù)據(jù)。
2)數(shù)據(jù)存儲(chǔ)模塊。負(fù)責(zé)將爬取到的資源元數(shù)據(jù)存儲(chǔ)到MySQL數(shù)據(jù)庫(kù)中。
3)數(shù)據(jù)分析模塊。負(fù)責(zé)通過爬取的URL數(shù)據(jù)來提取資源中的文本信息,經(jīng)過清洗、分析,生成資源多維度實(shí)體信息,并存入MySQL數(shù)據(jù)庫(kù)中。
4)數(shù)據(jù)利用模塊。負(fù)責(zé)將以提取到的資源多維度實(shí)體信息作為資源的標(biāo)簽,方便資源的回溯檢索。同時(shí),以實(shí)體信息為參數(shù)生成資源的知識(shí)圖譜。
1.4 數(shù)據(jù)庫(kù)設(shè)計(jì)
按平臺(tái)功能需求數(shù)據(jù)庫(kù)共設(shè)計(jì)了三張表,如表1至表3所示,分別用于存儲(chǔ)公眾號(hào)運(yùn)營(yíng)主體類別信息、公眾號(hào)主體信息、公眾號(hào)所發(fā)表文章信息。
2 平臺(tái)功能實(shí)現(xiàn)
2.1 數(shù)字資源的采集和處理
首先將收集的微信公眾號(hào)按運(yùn)營(yíng)主體進(jìn)行分類登記,分兩步實(shí)現(xiàn):一是通過表單預(yù)先設(shè)置運(yùn)營(yíng)主體信息并存入數(shù)據(jù)表中;二是在進(jìn)行公眾號(hào)主體信息登記時(shí),通過下拉表單強(qiáng)制要求公眾號(hào)進(jìn)行分類登記,如圖3所示,以豐富后期爬取資源的標(biāo)簽信息。以上功能通過django的forms(表單類)實(shí)現(xiàn)。
核心代碼如下:
from django import forms
from .models import *
class wxidform(forms.Form):
nickname=forms.CharFieNb6GeduUBmMRMDMEHnrQrQ==ld(max_length=30,label='請(qǐng)完整填寫公眾號(hào)中文名稱')
wx_attribution_choices=forms.ModelChoiceField(queryset=wx_attribution.objects.all().values_list('wx_attribution', flat=True),
label='請(qǐng)選擇微信公眾號(hào)類型', empty_label="請(qǐng)選擇" ,)
微信公眾號(hào)沒有提供API接口,且如果通過第三方檢索的方式爬取資源時(shí),資源的URL不是永久可訪問。平臺(tái)選擇通過注冊(cè)的公眾號(hào)在創(chuàng)作圖文消息時(shí)獲取各公眾號(hào)文章長(zhǎng)鏈接的途徑來實(shí)現(xiàn),主要利用Chrome中開發(fā)者工具抓包獲取相關(guān)接口信息,最終實(shí)現(xiàn)對(duì)相關(guān)公眾號(hào)資源的爬取,如圖4所示。
爬取分三步實(shí)現(xiàn):
1)利用selenium.webdriver模擬登錄微信公眾號(hào),獲取登錄之后的cookies信息[8]。
2)利用cookies爬取微信公眾號(hào)token、fakeid、nickname等數(shù)據(jù)。
3)利用已有的token、fakeid、nickname進(jìn)一步爬取該公眾號(hào)下的文章元數(shù)據(jù)。
該模塊功能主要通過Django的views實(shí)現(xiàn),核心代碼如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time,json,random,requests,re
from wxarticle.models import *
from django.db.models import Max
from datetime import datetime
from django.utils import timezone
#獲取cookies
def wechat_login(account_name,password):
driver=webdriver.Chrome()
driver.get("https://mp.weixin.qq.com/")
time.sleep(2) driver.find_element(By.XPATH,'//*[@id="header"]/div[2]/div/div/div[2]/a').click()
driver.find_element(By.NAME,"account").send_keys(account_name)
driver.find_element(By.NAME,"password").send_keys(password)
driver.find_element(By.CLASS_NAME,"frm_checkbox_label").click()
time.sleep(1)
driver.find_element(By.CLASS_NAME,"btn_login").click()
time.sleep(20)
cookie_items=driver.get_cookies()
post={}
for cookie_item in cookie_items:
post[cookie_item['name']]=cookie_item['value']
cookie_str=json.dumps(post)
with open('wxcookie.txt', 'w+', encoding='utf-8') as f:
f.write(cookie_str)
driver.quit()
#爬取微信公眾號(hào)token,fakeid,nickname等數(shù)據(jù)
def wxh_get_fakeid(query):
url='https://mp.weixin.qq.com'
header={"HOST": "mp.weixin.qq.com",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/\
537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/ 537.36",
"Accept - Encoding": "gzip, deflate, br ,utf-8",}
with open('wxcookie.txt', 'r', encoding='utf-8') as f:
cookie=f.read()
f.close()
cookies=json.loads(cookie)
session=requests.Session()
session.keep_alive=False
time.sleep(1)
response=session.get(url=url, cookies=cookies, verify=False)
token=re.findall(r'token=(\d+)', str(response.url))[0]
time.sleep(1)
search_url='https://mp.weixin.qq.com/cgi-bin/searchbiz'
query_params={'action': 'search_biz', 'token': token, 'lang': 'zh_CN', 'f': 'json', 'ajax': '1', 'query': query, 'begin': '0', 'count': '5' }
search_response=session.get(search_url,cookies=cookies,headers=header,params=query_params)
lists=search_response.json()['list'][0]
fakeid=lists['fakeid']
nickname=lists['nickname']
alias=lists['alias']
signature=lists['signature']
round_head_img=lists['round_head_img']
return token,fakeid,nickname,alias,signature,round_head_img
#爬取該微信公眾號(hào)文章信息提取元數(shù)據(jù)并寫入數(shù)據(jù)表
def wxh_get_content(nickname,fakeid,header,cookies):
appmsg_url='https://mp.weixin.qq.com/cgi-bin/appmsg'
session=requests.Session()
session.keep_alive=False
time.sleep(1)
response=session.get('https://mp.weixin.qq.com', cookies=cookies, verify=False)
token=re.findall(r'token=(\d+)', str(response.url))[0]
query_id_data={'token': token, 'lang': 'zh_CN', 'f': 'json', 'ajax': '1', 'action': 'list_ex', 'begin': '0', 'count': '5', 'query': '', 'fakeid': fakeid, 'type': '9'}
appmsg_response=session.get(appmsg_url, cookies=cookies, headers=header, params=query_id_data)
max_num=appmsg_response.json()['app_msg_cnt']
num=int(int(max_num) / 5)
begin=0
while num + 1 > 0:
query_id_data={'token': token, 'lang': 'zh_CN', 'f': 'json', 'ajax': '1', 'action': 'list_ex', 'begin': '{}'.format(str(begin)), 'count': '5', 'query': '', 'fakeid': fakeid, 'type': '9'}
query_fakeid_response=session.get(appmsg_url, cookies=cookies, headers=header, params=query_id_data)
fakeid_list=query_fakeid_response.json()['app_msg_list']
print(fakeid_list)
max_createtime=wx_article_url.objects.filter(nickname=nickname).aggregate(Max('createtime'))
for item in fakeid_list:
createtime=item['create_time']
content_createtime=time.strftime('%Y-%m-%d %X', time.localtime(createtime))
datetime_content_createtime=datetime.strptime(content_createtime, "%Y-%m-%d %H:%M:%S")
datetime_content_createtime=timezone.make_aware(datetime_content_createtime, timezone.utc)
if datetime_content_createtime > max_createtime['createtime__max']:
content_title=item['title'].encode('utf-8')
content_link=item['link']
content_coverlink=item['cover']
wx_article_url.objects.create(nickname=nickname,createtime=content_createtime,title=content_title,url=content_link)
num -= 1
begin=int(begin)
begin += 5
2.2 數(shù)據(jù)存儲(chǔ)
在數(shù)據(jù)存儲(chǔ)部分,平臺(tái)使用Django框架里ORM系統(tǒng)來管理數(shù)據(jù)庫(kù)操作,確保獲取的數(shù)據(jù)被安全、有效地存儲(chǔ)在MySQL 8.0數(shù)據(jù)庫(kù)中。Django提供了強(qiáng)大的數(shù)據(jù)庫(kù)抽象層,使得開發(fā)者可以在不關(guān)心底層數(shù)據(jù)庫(kù)實(shí)現(xiàn)細(xì)節(jié)的情況下進(jìn)行高效的數(shù)據(jù)操作。數(shù)據(jù)存儲(chǔ)功能屬于Django的MVT(模型-視圖-模板)的M(模型)部分,在Models.py中完成模型定義。接著通過django的管理工具manage.py完成在MySQL 8.0數(shù)據(jù)庫(kù)中創(chuàng)建表。另外,在數(shù)據(jù)抓取部分(即上面的代碼),每次獲取到新的文章數(shù)據(jù)時(shí),都會(huì)檢查這篇文章的創(chuàng)建時(shí)間是否晚于數(shù)據(jù)庫(kù)中已有數(shù)據(jù)的最晚創(chuàng)建時(shí)間。如果是,就將這篇新文章的數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)中。
2.3 數(shù)據(jù)分析
微信公眾號(hào)缺乏資源的細(xì)粒度標(biāo)簽,無(wú)法滿足用戶多維度的檢索需求。隨著AI技術(shù)的不斷發(fā)展和成熟,深度學(xué)習(xí)框架中的自然語(yǔ)言處理技術(shù)為我們提供了一種有效的解決方案——文本自動(dòng)化實(shí)體抽取任務(wù)。平臺(tái)選擇了百度開源的ERNIE-UIE大模型。它是一個(gè)基于知識(shí)增強(qiáng)的統(tǒng)一信息抽取框架,不僅結(jié)合了百度在深度學(xué)習(xí)和自然語(yǔ)言處理領(lǐng)域多年的積累,而且具備處理多種類型信息抽取任務(wù)的能力。通過引入ERNIE-UIE大模型,平臺(tái)能夠自動(dòng)化地從微信公眾號(hào)的海量文本中抽取出各類實(shí)體,如人名、地名、機(jī)構(gòu)名等,并為其打上細(xì)粒度的標(biāo)簽。這些標(biāo)簽不僅豐富了資源的元數(shù)據(jù),還為用戶提供了更加精準(zhǔn)、多維度的檢索條件。核心代碼如下:
from bs4 import BeautifulSoup
from paddlenlp import Taskflow
import networkx as nx
import matplotlib.pyplot as plt
def wx_article_analyse(url):
schema_entity=['時(shí)間', '人名', '地名', '事件', '組織', '課題', '獎(jiǎng)項(xiàng)', '會(huì)議']
response=requests.get(url)
html_content=response.text
soup=BeautifulSoup(html_content, 'html.parser')
text_content=soup.get_text()
# 實(shí)體抽取
ie_entity=Taskflow('information_extraction', schema=schema_entity, model='uie-base')
entity=ie_entity(text_content)[0]
# 關(guān)系抽取
schema_relation={'事件': ['時(shí)間', '人名', '組織'], '課題':['時(shí)間', '人名', '組織'], '獎(jiǎng)項(xiàng)':['時(shí)間', '人名', '組織'], '會(huì)議':['時(shí)間', '人名', '組織']}
ie_relation=Taskflow('information_extraction', schema=schema_relation, model='uie-base')
relation=ie_relation(text_content)[0]
return entity,relation
2.4 數(shù)據(jù)利用
數(shù)據(jù)利用主要體現(xiàn)如下:
1)通過將與高校相關(guān)的微信公眾號(hào)上的數(shù)字文化資源進(jìn)行統(tǒng)一聚合,并對(duì)其進(jìn)行抽取和分析得到的實(shí)體信息數(shù)據(jù),構(gòu)建資源的標(biāo)簽以實(shí)現(xiàn)八個(gè)維度的資源回溯檢索功能,核心代碼如下:
from django.http import JsonResponse
from .models import wx_article_url, wx_id
def search_articles_by_dimension(request, dimension, value):
# 根據(jù)傳入的維度和值進(jìn)行過濾
articles=wx_article_url.objects.filter(**{f'entity_{dimension}__contains': value}).distinct()
# 獲取微信公眾號(hào)歸屬等信息,需要關(guān)聯(lián)wx_id模型
article_list=[]
for article in articles:
try:
wx_info=wx_id.objects.get(fakeid=article.fakeid)
article_list.append({'nickname': wx_info.nickname,
'wx_attribution': wx_info.wx_attribution,
'title': article.title,
'url': article.url,})
except wx_id.DoesNotExist:
continue
return JsonResponse(article_list, safe=False)
數(shù)據(jù)抽取和分析結(jié)果樣本見表4。
2)通過分析得到的實(shí)體關(guān)系信息數(shù)據(jù)構(gòu)建知識(shí)圖譜[9]。核心代碼如下:
import networkx as nx
import matplotlib.pyplot as plt
def wx_article_plt(ID,data):
G=nx.DiGraph()
for category, items in data.items():
for item in items:
text=item['text']
start=item['start']
end=item['end']
probability=item['probability']
relations=item.get('relations', {})
G.add_node(text, label=text, start=start, end=end, probability=probability)
for relation_type, relation_items in relations.items():
for relation_item in relation_items:
relation_text=relation_item['text']
G.add_edge(text, relation_text, relation=relation_type)
pos=nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, node_size=1000, node_color='lightblue')
nx.draw_networkx_edges(G, pos, alpha=0.5)
nx.draw_networkx_labels(G, pos, font_size=16, font_family='sans-serif')
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
plt.axis('off')
plt.savefig('./pltfig/'+str(ID)+ '.png')
3)實(shí)現(xiàn)對(duì)所聚合資源的跨公眾號(hào)統(tǒng)一檢索和圖譜展示[10],如圖5所示。
3 結(jié) 論
平臺(tái)不但實(shí)現(xiàn)了基于微信公眾號(hào)的高校相關(guān)數(shù)字文化資源的統(tǒng)一保存,而且突破了微信公眾平臺(tái)上傳統(tǒng)的只能根據(jù)關(guān)鍵詞進(jìn)行搜索的檢索方式,實(shí)現(xiàn)從時(shí)間、人名、地名、事件、組織、課題、獎(jiǎng)項(xiàng)和會(huì)議這八個(gè)維度回溯檢索。用戶可以根據(jù)自己的需求,選擇相應(yīng)的維度和條件,快速定位到自己感興趣的資源。除了回溯檢索外,平臺(tái)還利用抽取的實(shí)體關(guān)系數(shù)據(jù),構(gòu)建了一個(gè)知識(shí)圖譜。通過這個(gè)圖譜,用戶可以發(fā)現(xiàn)不同資源之間的關(guān)聯(lián)和聯(lián)系,促進(jìn)資源的有效傳播和利用。同時(shí),這也為微信公眾號(hào)帶來了更多的互動(dòng)和活躍度,提升了其整體的用戶體驗(yàn)和價(jià)值。
參考文獻(xiàn):
[1] 新華網(wǎng).中共中央辦公廳 國(guó)務(wù)院辦公廳印發(fā)《關(guān)于推進(jìn)實(shí)施國(guó)家文化數(shù)字化戰(zhàn)略的意見》 [EB/OL].(2022-05-22).http://www.news.cn/2022-05/22/c_1128674022.htm.
[2] 馬麗丁娜,朱麗麗.數(shù)字文化10年研究:技術(shù)、日常生活與在地實(shí)踐 [J].傳媒觀察,2023(3):80-90.
[3] 任立.數(shù)字人文時(shí)代文化遺產(chǎn)融入高校德育教育體系探究 [J].黑河學(xué)院學(xué)報(bào),2024,15(1):173-176+184.
[4] 張玉清,趙江南,趙威.平臺(tái)、內(nèi)容與運(yùn)維:高校共青團(tuán)微信公眾號(hào)影響力提升策略的實(shí)證探析 [J].東南大學(xué)學(xué)報(bào):哲學(xué)社會(huì)科學(xué)版,2023,25(S2):72-77.
[5] 田文濤.Python技術(shù)在計(jì)算機(jī)軟件中的應(yīng)用 [J].集成電路應(yīng)用,2024,41(2):344-346.
[6] 李朝陽(yáng),周維貴,張小鋒,等.一種麒麟系統(tǒng)下基于Django的網(wǎng)絡(luò)性能管理系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn) [J].計(jì)算機(jī)應(yīng)用與軟件,2024,41(3):130-133.
[7] 飛槳.UIE模型簡(jiǎn)介 [EB/OL].(2022-11-28)[2024-03-02].https://aistudio.baidu.com/modelsdetail/22?modelId=22.
[8] 朱燁行,趙寶瑩,張明杰,等.基于Scrapy框架的微博用戶信息采集系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn) [J].現(xiàn)代信息科技,2023,7(24):41-44+48.
[9] 蔡文樂,秦立靜.基于Python爬蟲的招聘數(shù)據(jù)可視化分析 [J].物聯(lián)網(wǎng)技術(shù),2024,14(1):102-105.
[10] 許夢(mèng)雅.基于Echarts技術(shù)的企業(yè)數(shù)據(jù)可視化的設(shè)計(jì)與開發(fā) [J].現(xiàn)代信息科技,2022,6(6):90-92+96.
作者簡(jiǎn)介:林立(1978—),男,漢族,福建福州人,副研究館員,本科,研究方向:圖書館自動(dòng)化與數(shù)字化。