Python 爬取 熱詞並進行分類數據分析-[解釋修復+熱詞引用]


日期:2020.02.02

博客期:141

星期日

 

  【本博客的代碼如若要使用,請在下方評論區留言,之后再用(就是跟我說一聲)】

  所有相關跳轉:

  a.【簡單准備

  b.【雲圖制作+數據導入

  c.【拓撲數據

  d.【數據修復

  e.【解釋修復+熱詞引用】(本期博客)

   f.【JSP演示+頁面跳轉

  g.【熱詞分類+目錄生成

  h.【熱詞關系圖+報告生成

  i . 【App制作

  j . 【安全性改造


  嗯~昨天相當於把數據重新爬了一邊,但是貌似數據仍然不合適。問題到底出在什么地方呢?我直接回答了吧!如果我們的需求僅僅是雲圖展示,那么這些數據就夠用了,甚至還多,因為任務是要實現“標記熱詞出現在哪個新聞里”,這就需要我們記錄一下標題。當然!這也不難實現。我先把我所有的 Python 類全部單獨分包做成一個.py文件。然后,我將數據庫文件重新配置,將sql文件覆蓋到上一篇博客中(本篇博客也會發出下載鏈接)。然后找到之前的添加解釋的類,進行二次利用,重新爬取!這個任務也做完了以后呢,我會把之前的鏈接分別對應到每一個熱詞,利用 jsp 技術實現熱詞相關信息的展示。最后,將探索一下熱詞之間的緊密程度(說實在的我現在有點兒不太理解這是什么意思,等睡一覺,起來問了老師,再修改本篇博客),利用 ECharts 接口制作可供展示的關系圖,努力肝了一天發現只做到了展示,沒能完成熱詞關系探索,嗯,交給今后的我了。

  1、整理文件(修改之前的 爬取網頁的 文件 不再 撰寫)

    嗯,現在我已經將文件規整好了,如下圖。先說一下,改造以后的python代碼將每一個類分別單獨封裝成一個.py文件,每一個執行過程將單獨使用一個.py文件,並放入到 itWords.process 包當中!我想過可以將所有執行過程寫到一個.py文件里,但這樣的話就有點兒亂,最終還是決定分開寫。

    

     itWords.basic 包:

      此包類已經被整合,詳細參照博客: Python 爬取的類封裝【將來可能會改造,持續更新...】(2020年寒假小目標09)

    itWords.bean 包:

 1 import codecs
 2 
 3 
 4 class KeyWords:
 5     # 熱詞
 6     word = ""
 7     # 對應鏈接
 8     link = ""
 9     # 頻數
10     num = 0
11 
12     def __init__(self,word,link,num):
13         self.word = word
14         self.link = link
15         self.num = num
16 
17     # 整理成 一行 字符串
18     def __toString__(self):
19         return self.word +"\t"+str(self.num)+"\t"+self.link
20 
21     # 將 自動整理好的字符串 帶換行符 追加 到文件后
22     def __toFile__(self,filePath):
23         f = codecs.open(filePath, "a+", 'utf-8')
24         f.write(self.__toString__() + "\n")
25         f.close()
KeyWords.py
 1 import codecs
 2 
 3 
 4 class News:
 5     # 標題
 6     title = ""
 7     # 內容
 8     info = ""
 9     # 鏈接
10     link = ""
11 
12     # 初始化
13     def __init__(self,title,info,link):
14         self.title = title
15         self.info = info
16         self.link = link
17 
18     # 整理成 一行 字符串
19     def __toString__(self):
20         return self.link+"\t"+self.title+"\t"+self.info
21 
22     # 將 自動整理好的字符串 帶換行符 追加 到文件后
23     def __toFile__(self,filePath):
24         f = codecs.open(filePath, "a+", 'utf-8')
25         f.write(self.__toString__() + "\n")
26         f.close()
27 
28     # 將 標題和內容 銜接的 字符串 予以返回 ( 計算詞語頻率 )
29     def getSimple(self):
30         return self.title+self.info
News.py

     itWords.process 包:

 1 import codecs
 2 
 3 
 4 def makeSql():
 5     file_path = "../../testFile/rc/words_sql.txt"
 6     f = codecs.open(file_path, "w+", 'utf-8')
 7     f.write("")
 8     f.close()
 9 
10     fw = open("../../testFile/rc/news.txt", mode='r', encoding='utf-8')
11     tmp = fw.readlines()
12 
13     num = tmp.__len__()
14 
15     for i in range(0,num):
16         group = tmp[i].split("\t")
17         group[0] = "'" + group[0] + "'"
18         group[2] = "'" + group[2][0:group[2].__len__()-1] + "'"
19         f = codecs.open(file_path, "a+", 'utf-8')
20         f.write("Insert into words values ("+group[0]+","+group[1]+","+group[2]+");"+"\n")
21         f.close()
22 
23 
24 def makeOne():
25     file_path = "../../testFile/rc/keyword_moreinfo.txt"
26     fw = open("../../testFile/rc/keywords.txt", mode='r', encoding='utf-8')
27     tmp = fw.readlines()
fileR.py

    itWords 包:

 1 import jieba
 2 import jieba.analyse
 3 
 4 
 5 # 新聞段落高頻詞分析器
 6 class ToolToMakeHighWords:
 7     # 要處理的字符串
 8     test_str = ""
 9 
10     # 初始化
11     def __init__(self,test_str):
12         self.test_str = str(test_str)
13         pass
14 
15     # 使用 文件 建立數據
16     def buildWithFile(self,filePath,type):
17         file = open(filePath, encoding=type)
18         self.test_str = file.read()
19 
20     # 直接給予 字符串 建立
21     def buildWithStr(self,test_str):
22         self.test_str = test_str
23         pass
24 
25     # 統計詞
26     def getWords(self,isSimple,isAll):
27         if(isSimple):
28             words = jieba.lcut_for_search(self.test_str)
29             return words
30         else:
31             # True - 全模式 , False - 精准模式
32             words = jieba.cut(self.test_str, cut_all=isAll)
33             return words
34 
35     # 統計詞頻並排序
36     def getHighWords(self,words):
37         data = {}
38         for charas in words:
39             if len(charas) < 2:
40                 continue
41             if charas in data:
42                 data[charas] += 1
43             else:
44                 data[charas] = 1
45 
46         data = sorted(data.items(), key=lambda x: x[1], reverse=True)  # 排序
47 
48         return data
49 
50     # 獲取 前 num 名的高頻詞 ( 帶頻率 )
51     def selectObjGroup(self,num):
52         a = jieba.analyse.extract_tags(self.test_str, topK=num, withWeight=True, allowPOS=())
53         return a
54 
55     # 獲取 前 num 名的高頻詞 ( 不帶頻率 )
56     def selectWordGroup(self,num):
57         b = jieba.analyse.extract_tags(self.test_str, topK=num, allowPOS=())
58         return b
ToolToMakeHighWords.py
 1 import parsel
 2 from urllib import request
 3 import codecs
 4 
 5 from itWords.bean.KeyWords import KeyWords
 6 from itWords.Oranpick import Oranpick
 7 
 8 # [ 連續網頁爬取的對象 ]
 9 from itWords.ToolToMakeHighWords import ToolToMakeHighWords
10 
11 
12 class Surapity:
13     page = 1
14     headers = {
15         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36'}
16     basicURL = ""
17     oran = ""
18 
19     # ---[定義構造方法]
20     def __init__(self):
21         self.page = 1
22         self.basicURL = "https://news.cnblogs.com/"
23         self.oran = Oranpick("https://start.firefoxchina.cn/")
24 
25     def __close__(self):
26         self.oran.__close__()
27 
28     def __next__(self):
29         self.page = self.page + 1
30         self.basicURL = 'https://news.cnblogs.com/n/page/'+str(self.page)+'/'
31 
32     # 獲取 url 的內部 HTML 代碼
33     def getHTMLText(self):
34         req = request.Request(url=self.basicURL, headers=self.headers)
35         r = request.urlopen(req).read().decode()
36         return r
37 
38     # 獲取頁面內的基本鏈接
39     def getMop(self,filePath):
40         index_html = self.getHTMLText()
41         index_sel = parsel.Selector(index_html)
42         links = index_sel.css(".news_entry a::attr(href)").extract()
43         size = links.__len__()
44         for i in range(0,size):
45             link = "https://news.cnblogs.com"+links[i]
46             self.oran.__reset__(link)
47             news = self.oran.getNews()
48             ttm = ToolToMakeHighWords(news.getSimple())
49             words = ttm.getHighWords(ttm.getWords(False,False))
50             leng = words.__len__()
51             # 頻數 要在 15次 以上
52             for i in range(0,leng):
53                 if words[i][1]<=15:
54                     break
55                 keyw = KeyWords(word=words[i][0],link=link,num=words[i][1])
56                 keyw.__toFile__(filePath)
Surapity.py
 1 import parsel
 2 import time
 3 from selenium import webdriver
 4 
 5 from itWords.basic import StrSpecialDealer
 6 from itWords.bean import News
 7 
 8 
 9 # [ 一次性網頁爬取的對象 ]
10 
11 
12 class Oranpick:
13     basicURL = ""
14     profile = ""
15 
16     # ---[定義構造方法]
17     def __init__(self, url):
18         self.basicURL = url
19         self.profile = webdriver.Firefox()
20         self.profile.get("https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fnews.cnblogs.com%2Fn%2F654191%2F")
21         self.profile.find_element_by_id("LoginName").send_keys("youraccount")
22         self.profile.find_element_by_id("Password").send_keys("yourpassword")
23         time.sleep(2)
24         self.profile.find_element_by_id("submitBtn").click()
25         # 給予 15s 的驗證碼人工驗證環節
26         time.sleep(15)
27         self.profile.get(url)
28 
29     # 重新設置
30     def __reset__(self,url):
31         self.basicURL = url
32         self.profile.get(url)
33 
34     # ---[定義釋放方法]
35     def __close__(self):
36         self.profile.quit()
37 
38     # 獲取 url 的內部 HTML 代碼
39     def getHTMLText(self):
40         a = self.profile.page_source
41         return a
42 
43     # 獲取基本數據
44     def getNews(self):
45         index_html = self.getHTMLText()
46         index_sel = parsel.Selector(index_html)
47         context = index_sel.css('#news_title a')[0].extract()
48         context = StrSpecialDealer.getReaction(context)
49         context = StrSpecialDealer.simpleDeal(context)
50         conform = index_sel.css('#news_body')[0].extract()
51         conform = StrSpecialDealer.deleteRe(conform)
52         conform = StrSpecialDealer.simpleDeal(conform)
53         news = News(title=context, info=conform, link=self.basicURL)
54         return news
Oranpick.py

    整理完成,接下來還會改代碼的,上面的 basic 包應該是不會改了。

  2、重寫 Bean 相關的基礎類,並重新爬取(可記錄標題)

     需要將表示 標題 的 title 屬性加到 KeyWords 類中,並修改 init 初始化方法 和 toString 轉性方法:

 1 import codecs
 2 
 3 
 4 class KeyWords:
 5     # 熱詞
 6     word = ""
 7     # 對應鏈接
 8     link = ""
 9     # 頻數
10     num = 0
11     # 鏈接標題
12     title = ""
13 
14     def __init__(self,word,link,num,title):
15         self.word = word
16         self.link = link
17         self.num = num
18         self.title = title
19 
20     # 整理成 一行 字符串
21     def __toString__(self):
22         return self.word +"\t"+str(self.num)+"\t"+self.title+"\t"+self.link
23 
24     # 將 自動整理好的字符串 帶換行符 追加 到文件后
25     def __toFile__(self,filePath):
26         f = codecs.open(filePath, "a+", 'utf-8')
27         f.write(self.__toString__() + "\n")
28         f.close()
KeyWords.py

    之后找到引用 KeyWords 的地方,也就是 Surapity 類的 getMop() 方法,將  keyw = KeyWords(word=words[i][0],link=link,num=words[i][1])   一句改成 

  keyw = KeyWords(word=words[i][0],link=link,num=words[i][1],title=news.title) ,修改完成后:

 1 import parsel
 2 from urllib import request
 3 import codecs
 4 
 5 from itWords.bean.KeyWords import KeyWords
 6 from itWords.Oranpick import Oranpick
 7 
 8 # [ 連續網頁爬取的對象 ]
 9 from itWords.ToolToMakeHighWords import ToolToMakeHighWords
10 
11 
12 class Surapity:
13     page = 1
14     headers = {
15         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36'}
16     basicURL = ""
17     oran = ""
18 
19     # ---[定義構造方法]
20     def __init__(self):
21         self.page = 1
22         self.basicURL = "https://news.cnblogs.com/"
23         self.oran = Oranpick("https://start.firefoxchina.cn/")
24 
25     def __close__(self):
26         self.oran.__close__()
27 
28     def __next__(self):
29         self.page = self.page + 1
30         self.basicURL = 'https://news.cnblogs.com/n/page/'+str(self.page)+'/'
31 
32     # 獲取 url 的內部 HTML 代碼
33     def getHTMLText(self):
34         req = request.Request(url=self.basicURL, headers=self.headers)
35         r = request.urlopen(req).read().decode()
36         return r
37 
38     # 獲取頁面內的基本鏈接
39     def getMop(self,filePath):
40         index_html = self.getHTMLText()
41         index_sel = parsel.Selector(index_html)
42         links = index_sel.css(".news_entry a::attr(href)").extract()
43         size = links.__len__()
44         for i in range(0,size):
45             link = "https://news.cnblogs.com"+links[i]
46             self.oran.__reset__(link)
47             news = self.oran.getNews()
48             ttm = ToolToMakeHighWords(news.getSimple())
49             words = ttm.getHighWords(ttm.getWords(False,False))
50             leng = words.__len__()
51             # 頻數 要在 15次 以上
52             for i in range(0,leng):
53                 if words[i][1]<=15:
54                     break
55                 keyw = KeyWords(word=words[i][0],link=link,num=words[i][1],title=news.title)
56                 keyw.__toFile__(filePath)
Surapity.py

    之后,在 process 編寫 過程文件 paData.py 重新爬取

 1 from itWords.Surapity import Surapity
 2 from itWords.basic.StringWriter import StringWriter
 3 
 4 
 5 def main():
 6     filepath = "../../testFile/rc/news.txt"
 7     s = Surapity()
 8     StringWriter(filepath).makeFileNull()
 9     s.getMop(filepath)
10     s.__next__()
11     s.getMop(filepath)
12     while s.page <= 100:
13         s.__next__()
14         s.getMop(filepath)
15     s.__close__()
16 
17 
18 main()
paData.py

    爬取得到結果如下:

    

  3、簡單的數據導入(附帶sql文件)

     在MySql中,重新建立 words 表:

      

     准備 Insert 語句,修改 fileR.py ,並執行:

 1 import codecs
 2 
 3 
 4 def makeSql():
 5     file_path = "../../testFile/rc/words_sql.txt"
 6     f = codecs.open(file_path, "w+", 'utf-8')
 7     f.write("")
 8     f.close()
 9 
10     fw = open("../../testFile/rc/news.txt", mode='r', encoding='utf-8')
11     tmp = fw.readlines()
12 
13     num = tmp.__len__()
14 
15     for i in range(0,num):
16         group = tmp[i].split("\t")
17         group[0] = "'" + group[0] + "'"
18         group[3] = "'" + group[3][0:group[3].__len__()-1] + "'"
19         f = codecs.open(file_path, "a+", 'utf-8')
20         f.write("Insert into words values ("+group[0]+","+group[1]+",'"+group[2]+"',"+group[3]+");"+"\n")
21         f.close()
22 
23 makeSql()
fileR.py

    之后,進入數據庫,選擇新建查詢,輸入 testFile/rc/words_sql.txt 文件內的sql語句,並予以執行

    使用上次建視圖的代碼重新建立視圖(也可以建成新表)名稱:keywords,如圖:

      

     Sql 文件下載地址:https://files.cnblogs.com/files/onepersonwholive/words.zip

  4、解釋修復——重新利用 百度百科 進行解釋性文字爬取

    先使用 Navicat 導出 keywords 表,設置 \t 為列間隔,\n 為行間隔,導出 txt 文件(不要文本限定符)

    

    之后,將此文件剪切到 testFile/rc/keywords.txt 處

    編寫新的Bean類 ExplainThings:

 1 class ExplainThings:
 2     # --- [ 方法域 ]
 3     # 初始化
 4     def __init__(self,word,exp,num):
 5         self.word = word
 6         self.num = num
 7         self.exp = exp
 8 
 9     # 整理成 一行 字符串
10     def __toString__(self):
11         return self.word + "\t" + str(self.num) + "\t" + self.exp
12 
13     # 整理成 Insert 語句
14     def __toSql__(self):
15         return "Insert into keywords VALUES ('"+self.word+"',"+str(self.num)+",'"+self.exp+"');"
16 
17     # --- [ 屬性域 ]
18     # 熱詞
19     word = ""
20     # 解釋
21     exp = ""
22     # 頻數
23     num = 0
ExplainThings.py

    之后將老代碼,進行整合和修改

 1 from itWords.WebConnector import WebConnector
 2 from itWords.basic.StrSpecialDealer import StrSpecialDealer
 3 from itWords.basic.StringWriter import StringWriter
 4 from itWords.bean.ExplainThings import ExplainThings
 5 
 6 wc = WebConnector()
 7 sw = StringWriter("../../testFile/rc/moreinfo.txt")
 8 
 9 sw.makeFileNull()
10 
11 fw = open("../../testFile/rc/keywords.txt", mode='r', encoding='utf-8')
12 lines = fw.readlines()
13 
14 num = lines.__len__()
15 print(num)
16 for i in range(0, num):
17     print(str(i))
18     str_line = lines[i]
19     gr = str_line.split("\t")
20     name_b = StrSpecialDealer.simpleDeal(gr[0])
21     num_b = StrSpecialDealer.simpleDeal(gr[1])
22     wc.__reset__()
23     wc.getMore(name_b)
24     more_b = wc.getFirstChanel()
25     ex = ExplainThings(word=name_b,exp=more_b,num=num_b)
26     sw.write(ex.__toSql__())
27 
28 wc.__close__()
paExplain.py

    爬取得到Insert數據以后,將keywords表刪掉(或視圖),新建 keywords表,將 Insert文件執行一邊

      

     最終得到數據,如圖所示:

  5、jsp實現熱詞的信息展示(附帶 按照 詞頻或熱詞拼寫 的 順序或逆序 排序)——先顯示單頁30條數據

     緊趕慢趕,寫了展示部分,這還需要進一步的改造,今天時間不多了,還要抓緊時間趕另一項任務呢!

     先設置每一頁30個數據,數據橫向顯示好像有點兒不妥,豎向感覺也不太合適啊!頁面跳轉交給明天的我來寫。

  6、將鏈接寫到每一個對應熱詞當中去

     實現了點擊 “詳細信息”鏈接可以跳轉頁面至單個熱詞的頁面

 

     總算是在2月3號以前寫完了,呼!明天整理頁面的問題!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM