日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

唐诗分析项目设计文档

發(fā)布時間:2024/3/24 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 唐诗分析项目设计文档 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 一. 唐詩項目介紹
    • 1.1項目背景
    • 1.2項目需求
    • 1.3項目設(shè)計
    • 1.4項目工具選擇
  • 二.唐詩數(shù)據(jù)爬取模塊
    • 2.1技術(shù)選型環(huán)節(jié)
      • 2.1.1爬蟲技術(shù)
      • 2.1.2分詞技術(shù)
    • 2.2項目依賴環(huán)節(jié)
    • 2.3預(yù)研環(huán)節(jié)
      • 2.3.1解析列表頁Demo
      • 2.3.2分詞Demo
    • 2.4具體開發(fā)環(huán)節(jié)
      • 2.4.1數(shù)據(jù)庫的設(shè)計
      • 2.4.2爬取,解析數(shù)據(jù)
      • 2.4.3數(shù)據(jù)寫入到數(shù)據(jù)庫中
      • 2.4.4驗證并優(yōu)化---多線程
    • 2.5總結(jié)問題
  • 三.詩詞可視化分析模塊
    • 3.1技術(shù)選型
      • 3.1.1 echarts可視化
      • 3.1.2 jquery的發(fā)起ajax請求
      • 3.1.3 FastJson格式
    • 3.2導(dǎo)入依賴
    • 3.3代碼開發(fā)
      • 3.3.1 JDBC建立數(shù)據(jù)庫連接
      • 3.3.2 整理詩的數(shù)量
      • 3.3.3 整理分詞
    • 3.4驗證效果

一. 唐詩項目介紹

1.1項目背景

爬蟲技術(shù)一直處于風(fēng)口浪尖,爬了不該爬的會引來一身官司,爬想爬取的數(shù)據(jù)又不會輕而易舉獲得,但是又想來玩玩爬蟲技術(shù),怎么辦呢?首選古詩文網(wǎng),因為據(jù)了解它是沒有設(shè)置任何反爬蟲機制的,數(shù)據(jù)都是公開合法的,這里我就選擇了唐詩三百首來進行爬蟲,你們不好奇哪位唐代詩人寫的詩最多嗎?你們不好奇詩人們最喜歡用什么詞去作詩嗎?如果你對唐詩也感興趣,那就跟我一起開啟這個奇妙的詩詞探險吧。

1.2項目需求

一.用柱狀圖來展示詩人們的姓名和詩詞數(shù)量,并按詩詞數(shù)量降序排序。
二.用詞云來展示詞的使用頻度,使用最頻繁的詞應(yīng)該一眼看出。

1.3項目設(shè)計

一.通過爬蟲機制把唐詩的數(shù)據(jù)爬取出來,對它進行解析,將每首詩的數(shù)據(jù)寫入到數(shù)據(jù)庫中。
二.通過發(fā)起請求來對數(shù)據(jù)進行分析篩選,最后渲染成可視化效果。

1.4項目工具選擇

這是一個Web項目,Java選擇用IDEA這個編譯器,選擇用maven來引進一些需要用到的第三方庫,通過tomcat這個Web應(yīng)用服務(wù)器來執(zhí)行。

二.唐詩數(shù)據(jù)爬取模塊

2.1技術(shù)選型環(huán)節(jié)

2.1.1爬蟲技術(shù)

我了解到的爬蟲技術(shù)棧有 HtmlUnit,HttpClient,這里我選擇了HtmlUnit這個框架。

  • 原因:HttpClient是用來模擬HTTP請求的,用的是socket通信,通過get方法來提交請求,只能獲取html靜態(tài)頁面的源碼,如果頁面中有js部分,則不能獲取到j(luò)s執(zhí)行后的源碼。
    HtmlUnit是一款無界面的瀏覽器程序庫,它模擬用戶去操作瀏覽器,允許調(diào)用頁面,填寫表單,點擊鏈接等,還可以執(zhí)行js,有很多的API用起來也非常方便。

2.1.2分詞技術(shù)

使用ansj_seg庫對古詩的標題和正文進行分詞,為詞云做準備。這個中文分詞器正確率高,不容易出做,分詞速度也快,效果也比較高。

2.2項目依賴環(huán)節(jié)

解析請求html頁面

<dependency><groupId>net.sourceforge.htmlunit</groupId><artifactId>htmlunit</artifactId><version>2.36.0</version></dependency>

分詞

<dependency><groupId>org.ansj</groupId><artifactId>ansj_seg</artifactId><version>5.1.6</version></dependency>

2.3預(yù)研環(huán)節(jié)

通過編寫一些Demo來熟悉這些技術(shù)的使用,看看它展示的效果是否滿意。

2.3.1解析列表頁Demo

WebClient client = new WebClient(BrowserVersion.CHROME);client.getOptions().setJavaScriptEnabled(false);client.getOptions().setCssEnabled(false);String baseurl = "https://so.gushiwen.org";String pathurl = "/gushi/tangshi.aspx";List<String> detailUrlList = new ArrayList<>();//所有古詩的詳情頁的url//列表頁的解析{String url = baseurl + pathurl;HtmlPage page = client.getPage(url);//獲取詩詞頁面List<HtmlElement> divs = page.getBody().getElementsByAttribute("div", "class", "typecont");for (HtmlElement div : divs) {List<HtmlElement> as = div.getElementsByTagName("a");for (HtmlElement a : as) {String detailUrl = a.getAttribute("href");detailUrlList.add(baseurl + detailUrl);}}}

2.3.2分詞Demo

public static void main(String[] args) {String sentence="中華人民共和國成立了!中國人民從此站起來了";List<Term> termlist=NlpAnalysis.parse(sentence).getTerms();for(Term term:termlist){System.out.println(term.getNatureStr()+":"+term.getRealName());}}

2.4具體開發(fā)環(huán)節(jié)

2.4.1數(shù)據(jù)庫的設(shè)計

數(shù)據(jù)庫要存取:自增主鍵id,標題,朝代,作者,正文,分詞,sha-256。

  • SHA-256是為了防止下載重復(fù)詩詞,所以用每首詩的標題和正文去計算SHA-256值。
CREATE TABLE `tangpoetry` (`id` int(11) NOT NULL AUTO_INCREMENT,`sha256` char(64) NOT NULL,`dynasty` varchar(10) NOT NULL,`title` varchar(100) NOT NULL,`author` varchar(10) NOT NULL,`content` text NOT NULL,`words` text NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `sha256` (`sha256`) ) ENGINE=InnoDB AUTO_INCREMENT=703 DEFAULT CHARSET=utf8mb4

2.4.2爬取,解析數(shù)據(jù)

  • 獲取列表頁解析出每首詩的url
  • 解析詳情頁得出要往數(shù)據(jù)庫中寫入的數(shù)據(jù)(標題,朝代,作者,正文,計算SHA-256,計算分詞(切記分詞要去除特殊字符,比如符號,null等)需要將分詞拼接成字符串格式,方便存儲)

2.4.3數(shù)據(jù)寫入到數(shù)據(jù)庫中

  • 通過JDBC建立數(shù)據(jù)庫連接,將標題,朝代等信息插入到數(shù)據(jù)庫的表中。

2.4.4驗證并優(yōu)化—多線程

*通過sql語句查看320首詩詞數(shù)據(jù)是否成功寫入到數(shù)據(jù)庫中。如果信息無誤,則插入成功。

  • 單線程版本效率低,每次都是主線程去完成各項任務(wù),在解析詳情頁的時候每次都是主線程,而總共有320首詩,就要挨個去解析320次,非常耗時。
  • 引入多線程版本:讓主線程去獲取列表頁,解析列表頁,得出每首詩的url,開啟多個線程,去完成列表頁解析工作,并將數(shù)據(jù)寫入到數(shù)據(jù)庫中。
    問題:1.webclient不是線程安全的,每個線程都得自己建一個webclient對象
    2.connection不是線程安全的,需要通過傳
    datasource這個參數(shù)去建立連接。
    3.MessageDigest這個計算SHA-256的也不是線程安全的。
    多線程每次都要創(chuàng)建320個子線程去執(zhí)行任務(wù),執(zhí)行完再銷毀,顯然有點浪費資源。
  • 線程池版本:這里用的是Executors.newFixedThreadPool(30)這個固定數(shù)目的線程池,把多線程要處理的那些任務(wù)去交給線程池里面的線程去完成,這里我設(shè)置的是30個核心線程。
    BUG: JVM結(jié)束是指所有非后臺線程執(zhí)行結(jié)束后才關(guān)閉,而線程池一直在主線程中,根本不可能自己關(guān)閉,它會不斷地去執(zhí)行任務(wù),重復(fù)的死循環(huán),永不停止。
    解決辦法: 只要等所有子線程都完成任務(wù),就可以手動關(guān)閉線程池。
  • 如何判斷子線程任務(wù)是都都結(jié)束了呢?
    1.CAS原子類
private static AtomicInteger successCount=new AtomicInteger(0);private static AtomicInteger failureCount=new AtomicInteger(0);private static class Job implements Runnable{private void work() throws IOException, InterruptedException {Random random=new Random();int n=random.nextInt(5);if(n<2){throw new IOException();}Thread.sleep(5);}@Overridepublic void run() {try{work();//successCount++;successCount.getAndIncrement();}catch (IOException e){//failureCount++;failureCount.getAndIncrement();} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) throws InterruptedException {for(int i=0;i<COUNT;i++){Thread thread=new Thread(new Job());thread.start();}while(successCount.get()+failureCount.get()!=COUNT){Thread.sleep(1000);System.out.println("任務(wù)還沒完成");}System.out.println("任務(wù)全部完成");}

2.CountDownLatch:開始會設(shè)定要等待的線程數(shù),主線程阻塞,每執(zhí)行完一個子線程就調(diào)用countDown(),此時計數(shù)器-1,直到計時器為0時才將主線程喚醒,不為0 就一直await(),為0說明子線程任務(wù)都執(zhí)行完了,就可以關(guān)閉線程池了。

CountDownLatch countDownLatch = new CountDownLatch(detailUrlList.size());//指定countDownLatch要等待的線程數(shù)for (String url : detailUrlList) {pool.execute(new Job(url,dataSource2,countDownLatch));}countDownLatch.await();//如果沒處理結(jié)束,就等待pool.shutdown();//最后關(guān)閉線程池}

2.5總結(jié)問題

  • 在創(chuàng)建數(shù)據(jù)庫的時候,要合理的設(shè)計每個字段的類型,不能盲目浪費資源。
  • 多線程設(shè)計,一定要考慮線程安全問題,不然出大錯。
  • 學(xué)會不斷地優(yōu)化項目。

三.詩詞可視化分析模塊

3.1技術(shù)選型

3.1.1 echarts可視化

echarts是一個開源免費的javascript可視化庫,柱狀圖和詞云都是來自于它。而且它是開源的,中文文檔,方便上手。

3.1.2 jquery的發(fā)起ajax請求

因為echarts的數(shù)據(jù)是寫死的,所以使用jquery來發(fā)起ajax請求,用httpservlet來處理請求,返回一個json格式的字符串,等加載成功執(zhí)行success方法去進行可視化,這樣數(shù)據(jù)就是從請求響應(yīng)獲取的,不再是寫死的。

3.1.3 FastJson格式

返回Json格式的第三方庫有很多,比如Gson,FastJson等,我選擇FastJson主要是因為寫起來簡單,是阿里巴巴維護的,我這個應(yīng)用小,也估計碰不到它的BUG。

3.2導(dǎo)入依賴

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.62</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency>

3.3代碼開發(fā)

3.3.1 JDBC建立數(shù)據(jù)庫連接

這里用的是餓漢的設(shè)計模式,來進行數(shù)據(jù)庫連接。

3.3.2 整理詩的數(shù)量

  • 繼承HttpServlet,通過doGet方法來處理ajax發(fā)起的http請求,用復(fù)合查詢sql語句就可以搞定,再將數(shù)據(jù)寫入到JSONArray中,返回一個Json格式的字符串。
SELECT author, count(*) AS cnt FROM tangpoetry GROUP BY author HAVING cnt >=? ORDER BY cnt DESC
  • 用@WebServlet(“rank.json”)來配置path路徑,就不需要去web.xml去配置servlet了。
  • 發(fā)起ajax請求,收到響應(yīng)后去執(zhí)行success里面的方法,進行柱狀圖的渲染。
method: "get", // 發(fā)起 ajax 請求時,使用什么 http 方法url: "rank.json?condition=10", // 請求哪個 urldataType: "json", // 返回的數(shù)據(jù)當(dāng)成什么格式解析success: function (data) { // 成功后,執(zhí)行什么方法

通過html頁面的script標簽找到j(luò)s文件去執(zhí)行。

3.3.3 整理分詞

  • 繼承HttpServlet,通過doGet方法處理請求,將分詞都先放入到list中,再用map來整理每個詞出現(xiàn)的次數(shù),最后將Key和Value來放入到JSONArray中,返回一個json格式的字符串。
  • 同樣用@WebServlet("/words.json")

3.4驗證效果

總結(jié)

以上是生活随笔為你收集整理的唐诗分析项目设计文档的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。