# 0 簡(jiǎn)介
今天學(xué)長(zhǎng)向大家介紹適合作為畢設(shè)的項(xiàng)目:
畢設(shè)分享 基于Python實(shí)現(xiàn)的新聞搜索引擎(源碼+論文)
項(xiàng)目獲取:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-786752.html
https://gitee.com/sinonfin/algorithm-sharing文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-786752.html
基于Python實(shí)現(xiàn)的新聞搜索引擎
一、Scraper - 爬蟲
使用的庫(kù)有:
-
requests
-
BeautifulSoup4
爬蟲分為兩部分,網(wǎng)絡(luò)通信部分(scraper.py)與適配器(adapers/*.py)部分。
1.1 網(wǎng)絡(luò)通信部分
網(wǎng)絡(luò)部分也分為兩部分:
-
第一部分是初始化部分,使用適配器提供的鏈接,下載數(shù)據(jù)后發(fā)給適配器(適配器用這些鏈接捕獲哪些鏈接是下一步需要爬取的)
-
第二部分是爬取新聞的部分,適配器在前一步里得到了大量的新聞鏈接,通信部分便用這些鏈接進(jìn)行爬取。爬取之后,再將這些數(shù)據(jù)傳入適配器,然后得到返回值(包含新聞的ID、標(biāo)題、內(nèi)容、日期、來(lái)源)
全部爬完之后,將新聞數(shù)據(jù)以json格式存入到文件里,其中新聞的內(nèi)容是html
,不是純文本(保留了原網(wǎng)站的一些排版、外鏈圖片等信息)。
這一部分是多線程(默認(rèn)是10個(gè)線程)的,也就是說(shuō)適配器必須要是線程安全的。
1.2 適配器部分
適配器部分為通信部分提供鏈接(url)、報(bào)文頭(headers)、請(qǐng)求參數(shù)(params),需要實(shí)現(xiàn)7個(gè)函數(shù):
-
hasNextInit()
:判斷是否有下一個(gè)初始鏈接,有的話返回True -
nextInitParam()
:返回下一個(gè)初始鏈接的信息,包括op和上述的url、headers、params,其中op是你想加入的額外的信息 -
init(op, text)
:op表示上一個(gè)函數(shù)你所加入的額外的信息,text表示上一個(gè)函數(shù)請(qǐng)求的url所得到的html數(shù)據(jù) -
hasNext()
:判斷是否有下一個(gè)新聞鏈接,有的話返回True -
nextParam()
:返回下一個(gè)新聞鏈接的信息,包括op和上述的url、headers、params,其中op是你想加入的額外的信息 -
eval(op, text)
:op表示上一個(gè)函數(shù)你所加入的額外的信息,text表示上一個(gè)函數(shù)請(qǐng)求的url所得到的html數(shù)據(jù) -
‘encoding()’:返回所爬取網(wǎng)頁(yè)用的編碼格式(用于網(wǎng)絡(luò)部分解析html數(shù)據(jù))
請(qǐng)一定注意,這些函數(shù)都必須要線程安全。
二、Web - 網(wǎng)頁(yè)
2.1 前端
-
使用
Boostrap 3
寫的UI -
使用
JavaScript
(大部分是jQuery
)進(jìn)行各種UI更新操作,比如分頁(yè)、高亮、使用ajax
獲取各種服務(wù)器上的數(shù)據(jù),動(dòng)態(tài)更新網(wǎng)頁(yè)等 -
包含三種頁(yè)面:主頁(yè)(
/
)、搜索頁(yè)(/s??wd=中國(guó)&bg=2001-01-25&ed=2018-01-25
)、新聞詳細(xì)頁(yè)(/post?id=people_1
)
2.2 后端
我使用的數(shù)據(jù)庫(kù)是Django
默認(rèn)自帶的SQLite
,因此我只需要實(shí)現(xiàn)幾個(gè)models
就能實(shí)現(xiàn)數(shù)據(jù)的讀寫了。我一共寫了4個(gè)models(位于/web/postdb/models.py
):
-
WebInfo
:存儲(chǔ)每個(gè)適配器(adapter)的數(shù)據(jù)信息-
name
:適配器的名字(比如people
、xinhua
) -
count
:該適配器目前有多少數(shù)據(jù)從爬蟲部分的json文件里導(dǎo)入進(jìn)了數(shù)據(jù)庫(kù)(用于下一次從該json文件里更新數(shù)據(jù))
-
-
PostInfo
:存儲(chǔ)每篇新聞的數(shù)據(jù)信息-
NID
(Number ID):每篇新聞的純數(shù)字ID(從1開始),用于減少網(wǎng)絡(luò)通信時(shí)數(shù)據(jù)傳輸?shù)拇笮?/li> -
TID
(Text ID):每篇新聞的文本ID,是適配器名字_number
這樣命名,比如people_1
,用于在/post?id=people_1
里展示(而不是以純數(shù)字的方式,因?yàn)檫@樣難以區(qū)分) -
time
:新聞發(fā)表的時(shí)間,用datetime
類型存儲(chǔ) -
category
:新聞的分類(中文),比如“社會(huì)”、“時(shí)政”、“軍事”等 -
title
:新聞的標(biāo)題 -
content
:新聞的內(nèi)容(html) -
plain
:新聞的內(nèi)容(純文本) -
url
:新聞是從哪里爬取的?就是從該url爬取的 -
sourceLink
:新聞的來(lái)源鏈接(每篇新聞都有個(gè)來(lái)源,不一定就是url) -
sourceText
:新聞的來(lái)源文本(比如“新華網(wǎng)”、“人民網(wǎng)”)
-
-
IndexInfo
:存儲(chǔ)每個(gè)詞語(yǔ)對(duì)應(yīng)的新聞(倒排列表索引),同時(shí)存儲(chǔ)新聞的一些信息-
key
:詞語(yǔ) -
value
:該詞語(yǔ)所對(duì)應(yīng)的倒排列表(list),這個(gè)列表的每一個(gè)元素的格式為[在該新聞里的出現(xiàn)次數(shù), 該新聞的NID,該新聞的發(fā)表時(shí)間]
, 比如[1234, '3', datetime(2018, 1, 2)]
。該列表會(huì)轉(zhuǎn)化成json格式的字符串存儲(chǔ)在value
內(nèi)
-
-
PostRelation
:存儲(chǔ)每篇新聞相關(guān)聯(lián)的幾篇新聞(默認(rèn)是3篇),將其作為該新聞的推薦新聞-
NID
:新聞的NID
-
relation
:相關(guān)聯(lián)新聞的列表(list),這個(gè)列表的每一個(gè)元素的格式為{'title': 關(guān)聯(lián)新聞的標(biāo)題, 'TID': 關(guān)聯(lián)新聞的ITD}
。該列表會(huì)轉(zhuǎn)化成json格式的字符串存儲(chǔ)在relation
內(nèi)
-
2.3 新聞搜索算法
先介紹IndexInfo
數(shù)據(jù)庫(kù)的建立。
將每篇新聞的純文本進(jìn)行分詞(使用thulac
),同時(shí)統(tǒng)計(jì)每個(gè)詞出現(xiàn)的次數(shù)。然后根據(jù)格式存入IndexInfo
里的value
。
對(duì)于每一個(gè)搜索的字符串,我們將這個(gè)字符串也分詞。對(duì)于每個(gè)詞語(yǔ),我們從IndexInfo
里取出倒排列表,將每個(gè)新聞的出現(xiàn)次數(shù)累加。最后根據(jù)每條新聞的累加次數(shù),從大到小排個(gè)序,然后返回這些新聞的NID
。
2.4 推薦新聞算法
用一個(gè)最簡(jiǎn)單的辦法:將這篇新聞的標(biāo)題拿去新聞搜索算法
里進(jìn)行搜索,然后取出前幾條新聞即可。這是因?yàn)椋侣劦臉?biāo)題有高度的概括性(而且是人為的),在一定程度上可以代表整篇文章。
我們用該辦法預(yù)處理一下每篇新聞,然后存入PostRelation
數(shù)據(jù)庫(kù)里即可。
三、界面
首頁(yè)
搜索新聞
推薦展示
四、使用說(shuō)明
4.1 本機(jī)環(huán)境
-
Python 3.7.0
-
Django 2.1.1
-
requests 2.19.1
-
BeautifulSoup4 4.6.3
-
thulac
4.2 使用
首先使用scraper
文件夾下的爬蟲scraper.py
對(duì)“人民網(wǎng)”、“新華網(wǎng)”的新聞進(jìn)行爬取:
python scraper.py
之后會(huì)將爬取的數(shù)據(jù)存儲(chǔ)到people.json
和xinhua.json
中,然后在web
文件夾下,運(yùn)行:
python manage.py makemigrations
python manage.py migrate
初始化數(shù)據(jù)庫(kù),然后再執(zhí)行:
python manage.py updateDB
將爬取的數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫(kù)中(這可能會(huì)等很長(zhǎng)時(shí)間),之后再執(zhí)行:
python manage.py updateRelation
更新文章推薦的數(shù)據(jù)庫(kù),最后:
python manage.py runserver
啟動(dòng)服務(wù)器即可,你就可以通過(guò)127.0.0.1:8000
進(jìn)行訪問(wèn)網(wǎng)站了。
目前的效率是,17000篇新聞的話,在i5-7200U的機(jī)子上查詢新聞只要0.1s左右。(反正Django自帶的sqlite有多快我這個(gè)就有多快)
項(xiàng)目分享
項(xiàng)目獲?。?/strong>
https://gitee.com/sinonfin/algorithm-sharing
到了這里,關(guān)于計(jì)算機(jī)畢業(yè)分享(含算法) 基于Python實(shí)現(xiàn)的新聞搜索引擎(源碼+論文)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!