python 爬蟲應用——校園網搜索引擎(crawler application——Campus web search engine part-two)(下)

 

來自 《Python項目案例開發從入門到實戰》(清華大學出版社  鄭秋生 夏敏捷主編)中爬蟲應用——校園網搜索引擎html

這一部分的下半節代碼內容主要講的是 網頁排名和搜索模塊python

網頁排名採用TF(Term Frequency)/IDF(Inverse Document Frequency)統計。
其中TF意思是詞頻,表示詞條t在文檔d中出現的頻率。IDF意思是逆文本頻率指數,計算公式是 idf = log(N/df),其中N是文檔總數,df是包含詞條t的文檔數量,當有TF(詞頻)和IDF(逆文檔頻率)後,將這兩個詞相乘,就能獲得一個詞的TF-IDF的值。某個詞在文章中的TF-IDF越大,那麼通常而言這個詞在這篇文章的重要性會越高,因此經過計算文章中各個詞的TF-IDF,由大到小排序,排在最前面的幾個詞,就是該文章的關鍵詞。web

注意: 要想這部分的代碼運行成功,必定要先看個人博客中前兩章的內容 《 python 爬蟲應用——校園網搜索引擎(crawler application——Campus web search engine part-one)(上)》 而後生成 viewsdu.db 數據庫才能夠運行成功。sql

import sqlite3 import jieba import urllib import lxml import math from urllib import request from collections import deque from bs4 import BeautifulSoup # 連接已經建立好的數據庫(這個在上一篇博客中已經教了如何建立)
conn = sqlite3.connect("viewsdu.db") # 建立遊標對象
c = conn.cursor() # 計算doc瀏覽器中的總函數
c.execute('select count (*) from doc') # fetchall返回的是[(82,)],即文檔的條目總數,爲了計算IDF中的文檔總數
N = 1 + c.fetchall()[0][0] # target = input('請輸入搜索詞: ')
target = '校園'
# 將搜索內容粉刺
seggen = jieba.cut_for_search(target) # 字典,用於存儲「文檔號: 文檔得分」,文檔得分越高,表示這個詞在這個文檔中的重要程度越高
score = {} for word in seggen: print('獲得查詢詞', word) # 建立字典,返回的是word在每一個文檔中出現的次數,即TF詞頻的結果
    tf = {} c.execute('select list from word where term=?', (word,)) result = c.fetchall() if len(result) > 0: # 獲得當 term=word 時的 list 的值,這裏返回的是字符串,如'3 3 4 4 5 5 58 58'
        doclist = result[0][0] # 根據空格切割字符串,返回列表如 ['3', '3', '4', '4', '5', '5', '58', '58',]
        doclist = doclist.split(' ') # 把字符串轉換爲整型,返回的是 [3, 3, 4, 4, 5, 5, 58, 58]
        doclist = [int(x) for x in doclist] # set是集合,python中的集合主要用來去重,set(doclist)後結果就是 {3, 4, 5, 58},最終df再獲得長度4
        df = len(set(doclist)) # 逆文本頻率指數的計算公式,IDF=log(文檔總數/包含詞條的文檔數量)
        idf = math.log(N/df) # 計算詞頻TF,即在某文檔中出現的次數,返回的結果是{3:2, 4:2, 5:2, 58:2}
        for num in doclist: if num in tf: tf[num] = tf[num] + 1
            else: tf[num] = 1
        # !!!注意,當你看懂了這個是用字典表示列表中每一個字出現的次數的時候,你能夠用下面這一行代碼替換上面的5行代碼,效果同樣
        # tf = {i: doclist.count(i) for i in doclist}

        # TF統計結束,如今開始計算score=TF∗IDF
        for num in tf: if num in score: # 若是該num文檔已經有分數了,則累加
                score[num] = score[num] + tf[num]*idf else: score[num] = tf[num]*idf # 對score字典按字典的值排序
sortedlist = sorted(score.items(), key=lambda d: d[1], reverse=True) print('得分列表', sortedlist) cnt = 0 for num, docscore in sortedlist: cnt = cnt + 1
    # 根據num的值在doc瀏覽器中找到相對應的連接(網址)
    c.execute('select link from doc where id=?', (num,)) # 獲得具體連接的字符串
    url = c.fetchall()[0][0] # 輸出網址和對應得分
    print(url, '得分: ', docscore) try: # 打開網頁
        response = request.urlopen(url) # 能夠輸出網頁內容
        content = response.read().decode('utf-8') except: print('oops...讀取網頁出錯') continue
    # 解析網頁輸出標題
    soup = BeautifulSoup(content, 'lxml') # 獲得網頁標題
    title = soup.title if title is None: print('No title') else: # 
        title = title.text print(title) # 超過20條則結束,即輸出前20條
    if cnt > 20: break
if cnt == 0: print('無搜索結果') pass

結果:數據庫

相關文章
相關標籤/搜索