校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > Python實戰之手寫一個搜索引擎

Python實戰之手寫一個搜索引擎

熱門標簽:荊州云電銷機器人供應商 外呼不封號系統 溫州旅游地圖標注 江蘇房產電銷機器人廠家 悟空智電銷機器人6 幫人做地圖標注收費算詐騙嗎 電信營業廳400電話申請 蘇州電銷機器人十大排行榜 遼寧400電話辦理多少錢

一、前言

這篇文章,我們將會嘗試從零搭建一個簡單的新聞搜索引擎

當然,一個完整的搜索引擎十分復雜,這里我們只介紹其中最為核心的幾個模塊

分別是數據模塊、排序模塊和搜索模塊,下面我們會逐一講解,這里先從宏觀上看一下它們之間的工作流程

二、工作流程

三、數據模塊

數據模塊的主要作用是爬取網絡上的數據,然后對數據進行清洗并保存到本地存儲

一般來說,數據模塊會采用非定向爬蟲技術廣泛爬取網絡上的數據,以保證充足的數據源

但是由于本文只是演示,所以這里我們僅會采取定向爬蟲爬取中國社會科學網上的部分文章素材

而且因為爬蟲技術我們之前已經講過很多,這里就不打算細講,只是簡單說明一下流程

首先我們定義一個數據模塊類,名為 DataLoader,類中有一個核心變量 data 用于保存爬取下來的數據

以及兩個相關的接口 grab_data (爬取數據) 和 save_data (保存數據到本地)

grab_data() 的核心邏輯如下:

1.首先調用 get_entry(),獲取入口鏈接

def get_entry(self):
    baseurl = 'http://his.cssn.cn/lsx/sjls/'
    entries = []
    for idx in range(5):
        entry = baseurl if idx == 0 else baseurl + 'index_' + str(idx) + '.shtml'
        entries.append(entry)
    return entries

2.然后調用 parse4links(),遍歷入口鏈接,解析得到文章鏈接

def parse4links(self, entries):
    links = []
    headers = {
        'USER-AGENT': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
    }
    for entry in entries:
        try:
            response = requests.get(url = entry, headers = headers)
            html = response.text.encode(response.encoding).decode('utf-8')
            time.sleep(0.5)
        except:
            continue

        html_parser = etree.HTML(html)
        link = html_parser.xpath('//div[@class="ImageListView"]/ol/li/a/@href')
        link_filtered = [url for url in link if 'www' not in url]
        link_complete = [entry + url.lstrip('./') for url in link_filtered]
        links.extend(link_complete)

    return links

3.接著調用 parse4datas(),遍歷文章鏈接,解析得到文章內容

def parse4datas(self, entries):
    datas = []
    headers = {
        'USER-AGENT': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
    }
    data_count = 0
    for entry in entries:
        try:
            response = requests.get(url = entry, headers = headers)
            html = response.text.encode(response.encoding).decode('utf-8')
            time.sleep(0.2)
        except:
            continue

        html_parser = etree.HTML(html)
        title = html_parser.xpath('//span[@class="TitleFont"]/text()')
        content = html_parser.xpath('//div[@class="TRS_Editor"]//p//text()')
        content = [cont.replace('\u3000', '').replace('\xa0', '').replace('\n', '').replace('\t', '') for cont in content]
        content = [cont for cont in content if len(cont) > 30 and not re.search(r'[《|》]', cont)]

        if len(title) != 0 or len(content) != 0:
            data_count += 1
            datas.append({
                'id'  : data_count,
                'link': entry,
                'cont': '\t'.join(content),
                'title': title[0]
            })

    return datas

grab_data() 的核心代碼如下:

def grab_data(self):
    # 獲取入口鏈接
    entries = self.get_entry()
    # 遍歷入口鏈接,解析得到文章鏈接
    links = self.parse4links(entries)
    # 遍歷文章鏈接,解析得到文章內容
    datas = self.parse4datas(links)
    # 將相關數據寫入變量 data
    self.data = pd.DataFrame(datas)

save_data() 的核心代碼如下:

def save_data(self):
    # 將變量 data 寫入 csv 文件
    self.data.to_csv(self.data_path, index = None)

至此,我們已經爬取并保存好數據 data,數據以 DataFrame 形式存儲,保存在 csv 文件,格式如下:

|---------------------------------------------------|
|    id    |     link   |     cont     |    title   |
|---------------------------------------------------|
|  page id |  page link | page content | page title |
|---------------------------------------------------|
|  ......  |   ......   |    ......    |   ......   |
|---------------------------------------------------|

四、索引模塊

索引模型的主要作用是構建倒排索引 (inverted index),這是搜索引擎中十分關鍵的一環

一般來說,構建索引的目的就是為了提高查詢速度

普通的索引一般是通過文章標識索引文章內容,而倒排索引則正好相反,通過文章內容索引文章標識

具體來說,倒排索引會以文章中出現過的詞語作為鍵,以該詞所在的文章標識作為值來構建索引

首先我們定義一個索引模塊類,名為 IndexModel,類中有一個核心變量 iindex 用于保存倒排索引

以及兩個相關的接口 make_iindex (構建索引) 和 save_iindex (保存索引到本地)

make_iindex() 的核心代碼如下(具體邏輯請參考注釋):

def make_iindex(self):
    # 讀取數據
    df = pd.read_csv(self.data_path)
    # 特殊變量,用于搜索模塊
    TOTAL_DOC_NUM = 0 # 總文章數量
    TOTAL_DOC_LEN = 0 # 總文章長度
    # 遍歷每一行
    for row in df.itertuples():
        doc_id = getattr(row, 'id') # 文章標識
        cont = getattr(row, 'cont') # 文章內容

        TOTAL_DOC_NUM += 1
        TOTAL_DOC_LEN += len(cont)

        # 對文章內容分詞
        # 并將其變成 {word: frequency, ...} 的形式
        cuts = jieba.lcut_for_search(cont)
        word2freq = self.format(cuts)

        # 遍歷每個詞,將相關數據寫入變量 iindex
        for word in word2freq:
            meta = {
                'id': doc_id,
                'dl': len(word2freq),
                'tf': word2freq[word]
            }
            if word in self.iindex:
                self.iindex[word]['df'] = self.iindex[word]['df'] + 1
                self.iindex[word]['ds'].append(meta)
            else:
                self.iindex[word] = {}
                self.iindex[word]['df'] = 1
                self.iindex[word]['ds'] = []
                self.iindex[word]['ds'].append(meta)

    # 將特殊變量寫入配置文件
    self.config.set('DATA', 'TOTAL_DOC_NUM', str(TOTAL_DOC_NUM)) # 文章總數
    self.config.set('DATA', 'AVG_DOC_LEN', str(TOTAL_DOC_LEN / TOTAL_DOC_NUM)) # 文章平均長度
    with open(self.option['filepath'], 'w', encoding = self.option['encoding']) as config_file:
        self.config.write(config_file)

save_iindex() 的核心代碼如下:

def save_iindex(self):
    # 將變量 iindex 寫入 json 文件
    fd = open(self.iindex_path, 'w', encoding = 'utf-8')
    json.dump(self.iindex, fd, ensure_ascii = False)
    fd.close()

至此,我們們經構建并保存好索引 iindex,數據以 JSON 形式存儲,保存在 json 文件,格式如下:

{
    word: {
        'df': document_frequency,
        'ds': [{
            'id': document_id,
            'dl': document_length,
            'tf': term_frequency
        }, ...]
    },
    ...
}

五、搜索模塊

在得到原始數據和構建好倒排索引后,我們就可以根據用戶的輸入查找相關的內容

具體怎么做呢?

1.首先我們對用戶的輸入進行分詞

2.然后根據倒排索引獲取每一個詞相關的文章

3.最后計算每一個詞與相關文章之間的得分,得分越高,說明相關性越大

這里我們定義一個搜索模塊類,名為 SearchEngine,類中有一個核心函數 search 用于查詢搜索

def search(self, query):
    BM25_scores = {}

    # 對用戶輸入分詞
    # 并將其變成 {word: frequency, ...} 的形式
    query = jieba.lcut_for_search(query)
    word2freq = self.format(query)

    # 遍歷每個詞
    # 計算每個詞與相關文章之間的得分(計算公式參考 BM25 算法)
    for word in word2freq:
        data = self.iindex.get(word)
        if not data:
            continue
        BM25_score = 0
        qf = word2freq[word]
        df = data['df']
        ds = data['ds']
        W = math.log((self.N - df + 0.5) / (df + 0.5))
        for doc in ds:
            doc_id = doc['id']
            tf = doc['tf']
            dl = doc['dl']
            K = self.k1 * (1 - self.b + self.b * (dl / self.AVGDL))
            R = (tf * (self.k1 + 1) / (tf + K)) * (qf * (self.k2 + 1) / (qf + self.k2))
            BM25_score = W * R
            BM25_scores[doc_id] = BM25_scores[doc_id] + BM25_score if doc_id in BM25_scores else BM25_score

    # 對所有得分按從大到小的順序排列,返回結果
    BM25_scores = sorted(BM25_scores.items(), key = lambda item: item[1])
    BM25_scores.reverse()
    return BM25_scores

到此這篇關于Python實戰之手寫一個搜索引擎的文章就介紹到這了,更多相關Python寫搜索引擎內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Mysql實現簡易版搜索引擎的示例代碼
  • MySQL全文索引實現簡單版搜索引擎實例代碼
  • 詳細介紹基于MySQL的搜索引擎MySQL-Fullltext
  • scrapy+flask+html打造搜索引擎的示例代碼
  • python基于搜索引擎實現文章查重功能
  • Python大批量搜索引擎圖像爬蟲工具詳解
  • 360搜索引擎自動收錄php改寫方案
  • php記錄搜索引擎爬行記錄的實現代碼
  • Python無損音樂搜索引擎實現代碼
  • 基于 Mysql 實現一個簡易版搜索引擎

標簽:三沙 濟南 臺灣 宿遷 喀什 景德鎮 黃山 欽州

巨人網絡通訊聲明:本文標題《Python實戰之手寫一個搜索引擎》,本文關鍵詞  Python,實戰,之,手寫,一個,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Python實戰之手寫一個搜索引擎》相關的同類信息!
  • 本頁收集關于Python實戰之手寫一個搜索引擎的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    色又黄又爽网站www久久| 91精品国产综合久久久久久漫画| 日本韩国欧美在线| 久久亚洲影视婷婷| 亚洲成人综合视频| 99久久精品国产导航| 精品福利在线导航| 日韩和欧美一区二区三区| 成人国产亚洲欧美成人综合网| 日韩精品一区二区三区视频| 亚洲激情网站免费观看| 成人深夜福利app| 26uuu国产在线精品一区二区| 视频一区中文字幕| 欧美另类高清zo欧美| 亚洲一区二区五区| www.色综合.com| 中文字幕电影一区| 国产在线视视频有精品| 欧美一区二区三区白人| 一区二区三区免费网站| 91在线小视频| 亚洲色图视频网| 99视频在线精品| 最新中文字幕一区二区三区| 成人免费电影视频| 中文字幕日本不卡| 91蜜桃传媒精品久久久一区二区| 国产精品久久久久久久久动漫 | 免费精品视频最新在线| 欧美色涩在线第一页| 亚洲精品视频免费观看| 日本道在线观看一区二区| 亚洲人吸女人奶水| 色偷偷88欧美精品久久久| 一区二区三区**美女毛片| 色屁屁一区二区| 性久久久久久久久| 精品少妇一区二区三区免费观看| 国产麻豆日韩欧美久久| 国产农村妇女毛片精品久久麻豆 | 1区2区3区国产精品| 99精品国产99久久久久久白柏| 国产精品久久久久久久久久免费看| 成人夜色视频网站在线观看| 中文字幕亚洲精品在线观看| 在线观看日韩一区| 裸体在线国模精品偷拍| 久久久国产午夜精品| 91在线你懂得| 香蕉av福利精品导航| 精品欧美一区二区久久| 国产福利一区在线观看| 亚洲综合无码一区二区| 欧美xxxxxxxx| 成人免费毛片app| 五月激情六月综合| 亚洲精品在线网站| 91久久精品国产91性色tv | 亚洲一区二区三区视频在线 | 91社区在线播放| 亚洲成年人影院| 精品成人私密视频| 91亚洲精品一区二区乱码| 亚洲成人7777| 国产精品乱人伦中文| 51精品国自产在线| 懂色av一区二区三区免费看| 亚洲国产欧美在线人成| 久久精品一区蜜桃臀影院| 欧美日韩性生活| 丁香网亚洲国际| 日韩精品91亚洲二区在线观看| 国产精品国产成人国产三级| 欧美一区二区三区人| 91亚洲永久精品| 国产精品综合二区| 天天综合网天天综合色| 亚洲视频一区二区在线观看| 精品捆绑美女sm三区| 在线一区二区三区| 成人午夜精品在线| 精油按摩中文字幕久久| 伊人夜夜躁av伊人久久| 国产婷婷色一区二区三区 | 欧美亚洲丝袜传媒另类| 国产馆精品极品| 麻豆精品一区二区三区| 午夜精品福利在线| 亚洲日本成人在线观看| 国产精品日产欧美久久久久| 日韩美女视频在线| 91精品国产色综合久久ai换脸 | 亚洲一区二区三区国产| 国产精品色哟哟| 国产欧美精品一区| 久久亚洲综合色| 精品国产成人在线影院| 日韩欧美激情四射| 91精品国产色综合久久久蜜香臀| 在线观看精品一区| 色综合久久九月婷婷色综合| 99精品桃花视频在线观看| www.日韩精品| 不卡的电视剧免费网站有什么| 国产成人夜色高潮福利影视| 国产又黄又大久久| 国产酒店精品激情| 国产成人免费在线观看| 国产电影一区二区三区| 国产成人av一区二区三区在线 | 风间由美一区二区av101 | 亚洲国产成人私人影院tom| 国产精品亲子乱子伦xxxx裸| 国产日产欧产精品推荐色 | 一本大道久久a久久综合婷婷| 成人黄色在线看| 91视频你懂的| 欧美视频一二三区| 制服丝袜av成人在线看| 精品国产一区二区三区四区四| 欧美精品一区二区在线播放 | 精品久久久久久最新网址| 日韩一区二区三区在线| 久久亚洲精精品中文字幕早川悠里| 欧美r级在线观看| 国产欧美日韩在线| 亚洲男人的天堂在线观看| 亚洲电影一级黄| 老司机精品视频导航| 成人一区二区三区中文字幕| 色综合天天狠狠| 91精品国产综合久久精品| 欧美精品一区二区三区高清aⅴ | 成人av网址在线| 99riav一区二区三区| 欧美性大战久久久| 日韩精品在线一区二区| 国产精品―色哟哟| 亚洲国产成人高清精品| 精品一区二区三区久久久| 懂色中文一区二区在线播放| 在线免费观看视频一区| 日韩一区二区三区四区 | 香蕉久久夜色精品国产使用方法 | 91.com视频| 日本一区二区视频在线观看| 亚洲一区免费视频| 国产精品 日产精品 欧美精品| 色琪琪一区二区三区亚洲区| 欧美成人女星排名| 亚洲女与黑人做爰| 国产中文字幕一区| 欧美日韩一区二区三区四区| 久久久久久电影| 天天综合色天天综合色h| 国产成人午夜视频| 日韩一区二区在线看| 亚洲人成在线播放网站岛国| 久久超碰97中文字幕| 91久久精品一区二区三区| 国产日韩欧美制服另类| 日本欧美在线看| 在线观看91精品国产入口| 国产精品萝li| 国产一区二区三区av电影| 欧洲激情一区二区| 国产精品久久久久久久久快鸭| 毛片av一区二区三区| 欧美体内she精高潮| 亚洲少妇30p| 高清日韩电视剧大全免费| 欧美xxxxxxxx| 全部av―极品视觉盛宴亚洲| 欧美丝袜自拍制服另类| 亚洲欧美成aⅴ人在线观看| 国产不卡视频一区二区三区| 亚洲精品一区二区三区香蕉| 美腿丝袜亚洲三区| 777午夜精品免费视频| 亚洲激情中文1区| 99久久精品免费看国产免费软件| 国产亚洲午夜高清国产拍精品| 亚洲va中文字幕| 欧美日韩精品三区| 亚洲亚洲人成综合网络| 91亚洲国产成人精品一区二区三 | 欧美精品18+| 亚洲一区二三区| 欧美三级一区二区| 亚洲国产精品久久久久婷婷884 | 99久久久国产精品| 中文字幕电影一区| av中文字幕亚洲| 亚洲欧洲av色图| 91麻豆国产自产在线观看| 亚洲日本欧美天堂| 色诱视频网站一区| 亚洲国产日韩一级| 欧美乱妇23p|