使用Python实现简单的搜索引擎,完整源码

ε祈祈猫儿з 提交于 2019-11-27 16:31:27

版权声明:转载请注明出处!

https://blog.csdn.net/qq_35993946/article/details/88087827

这是博主我大学期间写的课程设计,希望能对看这篇博客的你有所帮助。

课程设计主要要求如下:

结合本学期《信息检索与搜索引擎技术》课程教学内容,利用网络爬虫技术、文档倒排索引技术、向量空间模型技术、检索排序技术,编写一个搜索引擎系统,系统能够实现根据输入关键词检索出与查询关键词相关的文档,并写出对应的程序设计及实现报告。具体要求如下:

利用网络爬虫技术编写程序实现从互联网中动态爬去网页数据;

利用分词工具(如ICTCLAS、结巴分词等)实现对爬取的文本进行分词,并建立倒排索引;

利用向量空间模型对分词后的文本及查询文本进行向量化表示,并计算查询向量和文档向量之间的相似性;

利用BM25算法、统计语言模型方法、或PageRank算法计算查询文本与文档之间的相关度得分,并根据相关度得分对文档进行排序。

 

目录

一、 系统概述 

1.1搜索引擎概述 

1.2本搜索引擎概述 

二、 系统需求分析 

2.1云南旅游业分析 

2.2系统可行性分析 

三、算法原理及程序实现 

3.1系统架构设计 

3.2网络爬虫 

3.2.1网络爬虫简介 

3.2.2网页分析 

3.3结巴分词并建立索引 

3.3.1结巴分词简介 

3.3.2倒排索引原理

3.3.3程序实现 

3.4向量空间模型 

3.4.1向量空间模型原理 

3.4.2代码实现原理 

3.5 BM25算法 

3.5.1 BM25算法原理 

3.5.2 代码实现 

3.6 网页实现框架:Flask及后台处理 

3.6.1Flask简介 

3.6.2代码实现 

3.7 web界面设计 

3.7.1 HTML简介 

3.7.2 网页界面 

四、程序展示 

五、总结与体会 

六、参考文献 

七、附录 

摘要

随着科技的进步与发展,互联网成为21世纪的宠儿,网络信息也复杂多样。这些繁杂的网络信息在给我们带来便利的同时也产生了极大的问题,比如如何在这海量的信息里面找到自己所需要的内容,成为当前互联网技术的热门领域。互联网信息复杂多样,因此想要迅速、快捷的找到所需要的信息内容,就需要搜索引擎来帮忙实现。本文就对搜索引擎的工作原理,组成和数据结构等方面进行分析,实现搜索引擎,并能对云南旅游网的内容进行搜索,适应用户的查询需求。

关键词: 搜索引擎;信息检索;网络爬虫;向量空间模型;网页排序

 

  • 系统概述

随着信息时代的来临,互联网的迅速普及应用,已经成为我们 正常生活中不可或缺的一部分。因为互联网信息具备共享等多种特性,使得网络信息成倍的增加。谷歌公司所收录的网页信息都已经过百亿,而且每天还在不断的攀升,想要在这么多数据里面,选取对自己有用的信息,就需要借助搜索引擎来进行实现。 搜索引擎是从1994年诞生,随着互联网的信息日益增多,搜索引擎也在不断的发展,从1994年到现在历经三个阶段。搜索引擎的第一个阶段就是1994年到1996年,这个阶段的搜索引擎以集中式检索 为主。当时网络信息并没有很多,一般都是少于百万的网页,也没有 索引,检索速度也非常慢。也是采用网络、数据库等关键技术来实现。第二个阶段是1996年到1998年,这个期间,搜索引擎采用分布式检索方案,使用多个微型计算机来协同工作,其目的是为了提高数据规模和响应速度。一般可以响应千万次的用户检索请求。第三代搜索引擎,就当前所使用的搜索引擎,也是搜索引擎极为繁荣的时期。它拥有完整的索引数据库,除了一般的搜索,还有主题搜索和地域搜索。但是这些搜索结果反馈给用户的数据量较大,检索结果的相关度又成为研究的核心。

本系统利用Python语言对搜索引擎的三个主要部件进行实现,能够完成搜索引擎的基本功能。通过本系统,用户能对云南旅游网的信息进行搜索,主要是爬取云南旅游网(http://travel.yunnan.cn/),方便用户在云南旅游,方便查找攻略,给用户创造一个愉快的旅游环境。

系统的工作流程分为四步,从网上抓取网页,建立索引数据库,根据用户的关键词在索引数据库中进行搜索,对搜索结果进行相关度排序处理。它主要由网络蜘蛛、索引器和检索器三部分组成。网络蜘蛛,英文名称Web Spider,它的主要功能是从指定的IP出发,便利整个互联网中所存在的网页,它可以借助网页中的URL爬到其他网页中去,不停的对这个过程进行重复,将爬过的网页搜集起来并存储到页面存储库中去。Indexer,索引器,它的主要功能是将Web Spider收集回来的网页进行分析,提取网页中所含的信息,并按照相关度进行计算,将这些相关信息建立完整的网页索引数据库。Searcher,检索器,用户输入关键词进行搜索,它负责对关键词进行分解,根据搜索器从网页索引数据库中查询到相关度较高的网页,对其进行排序处理,然后交给系统,系统会把结果进行组织处理,反馈给用户。搜索引擎对于文件的存储要求较高,操作系统又有自身的缺陷,在大型文件的管理方面存在诸多局限,这就需要搜索引擎自行定义和管理大型文件系统。大型文件是一种跨多文件系统的虚拟文件,支持64位寻址方式,可自动处理多文件系统的分配和寻址。

在进行软件开发前期,我们需要进行Python开发环境的搭建,需要Python程序开发包:Python3.6 ,开发IDE:JetBrains PyCharm2017.1,结巴中文分词包:jieba,网页实现框架:Flask,实现HTTP的第三方库requests。后面第三节会对本搜索引擎所用到的相关技术进行介绍,包括爬虫技术,结巴分词,向量空间模型,BM25算法等。

 

  • 系统需求分析

2.1旅游业分析

搜索引擎能自动从英特网搜集信息,经过一定整理以后,提供给用户进行查询的系统。英特网上的信息浩瀚万千,而且毫无秩序,所有的信息象汪洋上的一个个小岛,网页链接是这些小岛之间纵横交错的桥梁,而搜索引擎,则为你绘制一幅一目了然的信息地图,供你随时查阅。

随着我国经济的发展,旅游成了人们新的消费需求。在旅游业快速发展的同时,人们对旅游的附加产品的需求也越来越大。

查阅资料我们能知道这些数据,云南省2018年上半年累计接待海外游客362.83万人次,比去年同期增长8.23%;接待国内游客33596.97万人次,比去年同期增长27.18%;实现旅游业总收入4201.35亿元,比去年同期增长26.78%。

各州市紧紧围绕旅游强省目标任务进行旅游市场及产业建设,实现旅游接待量和旅游收入双增长。在目前公开的数据中,客接待量全省前三位的州市分别为红河(3116.47万人次)、大理(2448.56万人次)、楚雄(2354.72万人次);旅游收入全省前三位的州市分别为大理(377.19亿元)、红河(332.67亿元)、保山(332亿元)。

在出游时,人们经常会查阅资料,地图、住宿、交通、美食等。人们可能会去百度搜索,或者去app上查找。但是,百度烦人的医疗广告,许多的恶意刷景点好评。导致许多我们搜索到的并不是我们想要的,因此,开发一个无广告、准确而好用的旅游攻略搜索引擎会受到大部分游客的欢迎。

2.2系统可行性分析

2.1 对现有系统的分析

现有搜索引擎如百度、Google等难以为用户提供有效的个性化服务。由于不同用户的兴趣爱好各不相同,所以所需的检索结果也应该具有一定的针对性,但现有的搜索引擎无法为单个用户提供有效的个性化服务,大大增加了用户查询有用信息的时间。 

2.2 对建议技术的可行性分析

2.2.1 技术上的可行性

此次系统开发使用Python语言,该语言简单易学,又增强了可视化、数据库及Internet编程功能,很容易就可以进行系统开发。因此系统开发工具可以采用Python进行开发。而对IDE,采用JetBrains PyCharm。该软件简单易懂,应用广泛,比较适合新手上路使用。 

2.2.2 管理上的可行性

因为系统主要应用于出门来云南旅游的人士,后期爬虫数据处理量增多搜索结果更多更准确后,可以考虑部署到服务器上,让更多人使用。

2.3 社会因素的分析

随着科学技术的不断提高,计算机科学日渐成熟,大数据时代,信息需求越来越大。爬取公共数据,该软件的开发不会侵犯国家、集体和他人的利益。

三、算法原理及程序实现

3.1系统架构设计

搜索引擎有基本的五大模块,分别是信息采集,信息处理,建立索引,查询和 web 交互。本次课程设计研究的是如何在信息处理分析的基础上,建立一个完整的中文搜索引擎。所以该系统主要由以下几个详细部分组成:爬取数据,中文分词,相关度排序,建立索引库,建立查询服务器,建立web交互。

3.2网络爬虫

3.2.1网络爬虫简介

网络爬虫是捜索引擎抓取系统的重要组成部分。爬虫的主要目的是将互联网上的网页下载到本地形成一个或联网内容的镜像备份。

   

一个通用的网络爬虫的框架如图所示:

  网络爬虫的基本工作流程如下:

    1.首先选取一部分精心挑选的种子URL;

    2.将这些URL放入待抓取URL队列;

    3.从待抓取URL队列中取出待抓取在URL,解析DNS,并且得到主机的ip,并 将URL对应的网页下载下来,存储进已下载网页库中。此外,将这些URL放进已抓 取URL队列。

    4.分析已抓取URL队列中的URL,分析其中的其他URL,并且将URL放入待抓 取URL队列,从而进入下一个循环。

3.2.2网页分析

(1)分析要爬取的网页的代码,确定我们所需要的内容并用XPATH表达式定位其内容,用正则表达式筛选我们需要的内容,将编号,title,url,写入本地,存入docs.txt中。

# encoding=utf-8
# 导入爬虫包
from selenium import webdriver
# 睡眠时间
import time
import re
import os
import requests
# 打开编码方式utf-8打开

# 睡眠时间 传入int为休息时间,页面加载和网速的原因 需要给网页加载页面元素的时间
def s(int):
    time.sleep(int)


# html/body/div[1]/table/tbody/tr[2]/td[1]/input
# http://dmfy.emindsoft.com.cn/common/toDoubleexamp.do

if __name__ == '__main__':
    #查询的文件位置
   # fR = open('D:\\test.txt','r',encoding = 'utf-8')

    # 模拟浏览器,使用谷歌浏览器,将chromedriver.exe复制到谷歌浏览器的文件夹内
    chromedriver = r"C:\\Users\\zhaofahu\\AppData\\Local\\Google\\Chrome\\Application\\chromedriver.exe"
    # 设置浏览器
    os.environ["webdriver.chrome.driver"] = chromedriver
    browser = webdriver.Chrome(chromedriver)
    # 最大化窗口 用不用都行
    browser.maximize_window()
  #  header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}

    # 要爬取的网页
    neirongs = []  # 网页内容
    response = []  # 网页数据
    travel_urls = []
    urls = []
    titles = []
    writefile = open("docs.txt", 'w', encoding='UTF-8')
    url = 'http://travel.yunnan.cn/yjgl/index.shtml'
    # 第一页
    browser.get(url)
    response.append(browser.page_source)
    # 休息时间
    s(3)

    # 第二页的网页数据
    #browser.find_element_by_xpath('// *[ @ id = "downpage"]').click()
    #s(3)
    #response.append(browser.page_source)
    #s(3)

    # 第三页的网页数据
    #browser.find_element_by_xpath('// *[ @ id = "downpage"]').click()
    #s(3)
    #response.append(browser.page_source)


    # 3.用正则表达式来删选数据
    reg = r'href="(//travel.yunnan.cn/system.*?)"'
    # 从数据里爬取data。。。
    # 。travel_urls 旅游信息网址
    for i in range(len(response)):
        travel_urls = re.findall(reg, response[i])

    # 打印出来放在一个列表里
    for i in range(len(travel_urls)):
        url1 = 'http:' + travel_urls[i]
        urls.append(url1)
        browser.get(url1)
        content = browser.find_element_by_xpath('/html/body/div[7]/div[1]/div[3]').text
        # 获取标题作为文件名
        b = browser.page_source
        travel_name = browser.find_element_by_xpath('//*[@id="layer213"]').text
        titles.append(travel_name)
    print(titles)
    print(urls)
    for j in range(len(titles)):
        writefile.write(str(j) + '\t\t' + titles[j] + '\t\t' + str(urls[j])+'\n')

    s(1)
    browser.close()

 

3.3结巴分词并建立索引

3.3.1结巴分词简介

jieba 是一个基于Python的中文分词工具对于一长段文字,其分词原理大体可分为三步:

1.首先用正则表达式将中文段落粗略的分成一个个句子。

2.将每个句子构造成有向无环图,之后寻找最佳切分方案。

3.最后对于连续的单字,采用HMM模型将其再次划分。

jieba分词分为“默认模式”(cut_all=False),“全模式”(cut_all=True)以及搜索引擎模式。对于“默认模式”,又可以选择是否使用 HMM 模型(HMM=True,HMM=False)。

3.3.2倒排索引原理

倒排索引(英语:Inverted index),也常被称为反向索引、置入档案或反向档案,是一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。它是文档检索系统中最常用的数据结构。通过倒排索引,可以根据单词快速获取包含这个单词的文档列表。倒排索引主要由两个部分组成:“单词词典”和“倒排文件”。

倒排索引有两种不同的反向索引形式:

一条记录的水平反向索引(或者反向档案索引)包含每个引用单词的文档的列表。

一个单词的水平反向索引(完全反向索引)又包含每个单词在一个文档中的位置。

后者的形式提供了更多的兼容性(比如短语搜索),但是需要更多的时间和空间来创建。

通过上面的定义可以知道,一个倒排索引包含一个单词词典和一个倒排文件。其中单词词典包含了所有粒度的拆分词;倒排文件则保存了该词对应的所有相关信息。

 

3.3.3程序实现 

  1. 对爬取的文档进行分词主要代码
class Doc:
    def __init__(self):
        self.field = {}
    def add(self, field, content):
        self.field[field] = content
    def get(self, field):
        return self.field[field]

     2.建立索引库关键代码

#  建索引
from doc import Doc
import jieba
import math

class Indexer:
    inverted = {}   # 记录词所在文档及词频
    idf = {}         # 词的逆文档频率
    id_doc = {}     # 文档与词的对应关系

    def __init__(self, file_path):
        self.doc_list = []
        self.index_writer(file_path)

    def index_writer(self, file_path):
        with open(file_path, 'r', encoding='utf-8') as f:
            for line in f.readlines():
                key, title, link = line.strip().split('\t\t')
                doc = Doc()
                doc.add('key', key)
                doc.add('title', title)
                doc.add('link', link)
                self.doc_list.append(doc)
        self.index()

    def index(self):
        doc_num = len(self.doc_list)     # 文档总数
        for doc in self.doc_list:
            key = doc.get('key')
            # 正排
            self.id_doc[key] = doc

            # 倒排
            term_list = list(jieba.cut_for_search(doc.get('title')))   # 分词
            for t in term_list:
                if t in self.inverted:

                    if key not in self.inverted[t]:
                        self.inverted[t][key] = 1
                    else:
                        self.inverted[t][key] += 1
                else:
                    self.inverted[t] = {key: 1}

        for t in self.inverted:
            self.idf[t] = math.log10(doc_num / len(self.inverted[t]))

        print("inverted terms:%d" % len(self.inverted))
        print("index done")

if __name__ == '__main__':
    print("index")
    Indexer("docs.txt")

3.4向量空间模型

3.4.1向量空间模型原理

向量空间模型(vector space model)概念简单,把对文本内容的处理简化为向量空间中的向量运算,并且它以空间上的相似度表达语义的相似度,直观易懂。当文档被表示为文档空间的向量,就可以通过计算向量之间的相似性来度量文档间的相似性。文本处理中最常用的相似性度量方式是余弦距离。

搜索引擎需要计算“用户查询”和爬下来的众多”网页“之间的相似度,从而把最相似的排在最前返回给用户。

3.4.2代码实现原理

代码主要使用的算法是tf-idf

tf:term frequency 词频

idf:inverse document frequency 倒文档频率

主要思想是:如果某个词或短语在一篇文章中出现的频率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。

第一步:把每个网页文本分词,成为词包(bag of words)。

第三步:统计网页(文档)总数M。

第三步:统计第一个网页词数N,计算第一个网页第一个词在该网页中出现的次数n,再找出该词在所有文档中出现的次数m。则该词的tf-idf 为:n/N * 1/(m/M)  (还有其它的归一化公式,这里是最基本最直观的公式)

第四步:重复第三步,计算出一个网页所有词的tf-idf 值。

第五步:重复第四步,计算出所有网页每个词的tf-idf 值。

代码如下:
# 关键词统计和词频统计,以列表形式返回
def Count(resfile):
    t = {}
    infile = open(resfile, 'r', encoding='utf-8-sig')
    f = infile.readlines()
    count = len(f)
    # print(count)
    infile.close()
    s = open(resfile, 'r', encoding='utf-8-sig')
    i = 0
    while i < count:
        line = s.readline()
    # 去换行符
        line = line.rstrip('\n')
        # print(line)
        words = line.split(" ")
        #   print(words)

        for word in words:
                if word != "" and t.__contains__(word):
                    num = t[word]
                    t[word] = num + 1
                if word !="":
                    t[word] = 1
        i = i + 1

    # 字典按键值降序
    dic = sorted(t.items(), key=lambda t: t[1], reverse=True)
    # print(dic)
    # print()
    s.close()
    return (dic)

def MergeWord(T1, T2):

    MergeWord = []
    duplicateWord = 0
    for ch in range(len(T1)):
        MergeWord.append(T1[ch][0])
    for ch in range(len(T2)):
        if T2[ch][0] in MergeWord:
            duplicateWord = duplicateWord + 1
        else:
            MergeWord.append(T2[ch][0])

    # print('重复次数 = ' + str(duplicateWord))
    # 打印合并关键词
    # print(MergeWord)
    return MergeWord


# 得出文档向量
def CalVector(T1, MergeWord):
    TF1 = [0] * len(MergeWord)
    for ch in range(len(T1)):
        TermFrequence = T1[ch][1]
        word = T1[ch][0]
        i = 0
    while i < len(MergeWord):
        if word == MergeWord[i]:
            TF1[i] = TermFrequence
            break
        else:
            i = i + 1
        # print(TF1)
    return TF1


def CalConDis(v1, v2, lengthVector):
    # 计算出两个向量的乘积
    B = 0
    i = 0
    while i < lengthVector:
        B = v1[i] * v2[i] + B
        i = i + 1
    # print('乘积 = ' + str(B))

    # 计算两个向量的模的乘积
    A = 0
    A1 = 0
    A2 = 0
    i = 0
    while i < lengthVector:
        A1 = A1 + v1[i] * v1[i]
        i = i + 1
    # print('A1 = ' + str(A1))

    i = 0
    while i < lengthVector:
        A2 = A2 + v2[i] * v2[i]
        i = i + 1
        # print('A2 = ' + str(A2))

    A = math.sqrt(A1) * math.sqrt(A2)
    print('两篇文章的相似度 = ' + format(float(B) / A, ".3f"))

3.5 BM25算法

3.5.1 BM25算法原理

BM25 是一种用来评价搜索词和文档之间相关性的算法,它是一种基于概率检索模型提出的算法。BM25属于bag-of-words模型,bag-of-words模型只考虑document中词频,不考虑句子结构或者语法关系之类,把document当做装words的袋子,具体袋子里面可以是杂乱无章的。对每一个搜索查询,我们很容易给每个文档定义一个“相关分数”。当用户进行搜索时,我们可以使用相关分数进行排序而不是使用文档出现时间来进行排序。这样,最相关的文档将排在第一个,无论它是多久之前创建的(当然,有的时候和文档的创建时间也是有关的)。

我们要从最简单的、基于统计的方法说起。这种方法不需要理解语言本身,而是通过统计词语的使用、匹配和基于文档中特有词的普及率的权重等情况来决定“相关分数”。

这个算法不关心词语是名词还是动词,也不关心词语的意义。它唯一关心的是哪些是常用词,那些是稀有词。如果一个搜索语句中包括常用词和稀有词,最好让包含稀有词的文档的评分高一些,同时降低常用词的权重。

3.5.2 代码实现

(1)对搜索词进行结巴分词;

   term_list = []
        query = query.split()
        for entry in query:
            # 分词
            term_list.extend(jieba.cut_for_search(entry))

  1. 计算tf-idf,找出候选doc;

# TF−IDF=tf∗idf
tf_idf = {}
for term in term_list:
    if term in self.index.inverted:
        for doc_id, fre in self.index.inverted[term].items():
            if doc_id in tf_idf:
                tf_idf[doc_id] += (1 + math.log10(fre)) * self.index.idf[term]
            else:
                tf_idf[doc_id] = (1 + math.log10(fre)) * self.index.idf[term]

(3)文档相关度排序。
        sorted_doc = sorted(tf_idf.items(), key=operator.itemgetter(1), reverse=True)
        res = [self.index.id_doc[doc_id] for doc_id, score in sorted_doc]
        return res

(4)计算搜索词与爬取文档的匹配度然后将文档排序

from index import Indexer
import jieba
import operator
import math

"""
搜索
返回结果:(相关问题,相似度)列表
搜索步骤:
    1.分词
    2.计算tf-idf,找出候选doc
    3.对文档排序
"""

class Searcher:

    def __init__(self, index):
        self.index = index

    def search(self, query):
        term_list = []
        query = query.split()
        for entry in query:
            # 分词
            term_list.extend(jieba.cut_for_search(entry))

        # 计算tf-idf,找出候选doc
        tf_idf = {}
        for term in term_list:
            if term in self.index.inverted:
                for doc_id, fre in self.index.inverted[term].items():
                    if doc_id in tf_idf:
                        tf_idf[doc_id] += (1 + math.log10(fre)) * self.index.idf[term]
                    else:
                        tf_idf[doc_id] = (1 + math.log10(fre)) * self.index.idf[term]
        # 排序
        sorted_doc = sorted(tf_idf.items(), key=operator.itemgetter(1), reverse=True)

        res = [self.index.id_doc[doc_id] for doc_id, score in sorted_doc]
        return res

 

3.6 网页实现框架:Flask及后台处理

3.6.1Flask简介

Flask 是一个 Python 实现的 Web 开发微框架。基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。

3.6.2代码实现

# coding:utf-8
from flask import Flask, request, render_template, redirect, url_for
from index import Indexer
from search import Searcher
import jieba

from urllib import parse
import json

app = Flask(__name__, static_url_path='')


@app.route("/", methods=['POST', 'GET'])
def main():
    if request.method == 'POST' and request.form.get('query'):
        query = request.form['query']
        return redirect(url_for('search', query=query))

    return render_template('index.html')


@app.route("/q/<query>", methods=['POST', 'GET'])
def search(query):
    docs = searcher.search(query)
    terms = list(jieba.cut_for_search(query))
    result = highlight(docs, terms)
    return render_template('search.html', docs=result, value=query, length=len(docs))


def highlight(docs, terms):
    result = []
    print()
    for doc in docs:
        content = doc.get('title')
        for term in terms:
            content = content.replace(term, '<em><font color="red">{}</font></em>'.format(term))
        result.append((doc.get('link'), content))
    return result


index = Indexer("docs.txt")
searcher = Searcher(index)

if __name__ == "__main__":
    app.run(host='localhost', port=8080, debug=True)

3.7 web界面设计

3.7.1 HTML简介

超文本标记语言(标准通用标记语言下的一个应用,外语缩写HTML),是迄今为止网络上应用最为广泛的语言,也是构成网页文档的主要语言。HTML文本是由HTML命令组成的描述性文本,HTML命令可以说明文字、图形、动画、声音、表格、链接等。HTML的结构包括头部(Head)、主体(Body)两大部分,其中头部描述浏览器所需的信息,而主体则包含所要说明的具体内容。

3.7.2 网页界面

(1)主页显示输入框和搜索按钮,提交搜索内容。调用百度的界面css,能保存搜索历史记录。

关键代码:

index.html

<!DOCTYPE HTML>
<html>
<head>
    <title>搜索</title>
    <!-- Custom Theme files -->
    <link href="css/style.css" rel="stylesheet" type="text/css" media="all"/>
    <!-- Custom Theme files -->
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="keywords"
          content="Flat Search Box Responsive, Login form web template, Sign up Web Templates, Flat Web Templates, Login signup Responsive web template, Smartphone Compatible web template, free webdesigns for Nokia, Samsung, LG, SonyErricsson, Motorola web design"/>
    <!--Google Fonts-->
    <link href='http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800'
          rel='stylesheet' type='text/css'>
    <!--Google Fonts-->
</head>
<body>
<!--search start here-->
<div class="search">
    <i> </i>
    <div class="s-bar">
        <form method="post">
            <input type="text" name="query">
            <input type="submit" value="搜索攻略"/>
        </form>
    </div>

</div>
</body>
</html>

 (2)副页查询:search.html

<!doctype html>
<html ng-app="app">


<head>
    <meta charset="UTF-8">
    <title>搜索</title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
</head>
<body ng-controller="ctrl">


<div class="container">
    <br>
    <br>
    <form class="form-inline" method="post" action="/">
        <div class="form-group">
            <input type="text" style="height: 40px; width: 360px;" class="form-control" ng-model="query"
                   value="{{ value }}" name="query" id="query"/>
        </div>
        <input class="btn btn-small btn-success" role="button" type="submit" value="攻略搜一下" id="btn">
    </form>
    <br>
    <br>共有{{ length }}条结果
    <br>
    <div id="box">
    {% for doc in docs %}
    <p><a href="{{ doc[0] }}" target="_blank">{{ doc[1]|safe }}</a></p>
    <p>来源:{{ doc[0] }}</p>
    <br>
    {% endfor %}
</div>
</div>
</body>
</html>

 

四、程序展示

4.1搜索页主界面:index.html

   

4.2搜索结果页,搜索词能在结果中高亮显示:

4.3页面跳转:

4.4无结果

搜索博主名字(xxx),发现无结果!!!what fuck??,原来是我没爬取我的网站。呵呵呵,没我的名字。

五、总结与体会(开始了万年不变的套路模式。。。

我们身处在一个信息时代,可以通过很多途径接触到关于生活、学习等各方面的知识,但是如何在浩渺的信息海洋里快速而准确地找到我们所需要的东西呢,这成为很多人面临的重要的问题,所以学习信息检索和搜索引擎技术就显得尤为重要了。

没学习网络信息检索之前,我们总觉得只要有搜索引擎就可以搜到我们需要的东西,但是面对庞杂的信息,我们往往会不知所措,因为当我们输入想要查询的内容后,网络上会出现成百上千个结果,然而这些结果可能没有一个是我们需要的,因此学习使用搜索引擎的原理和实现方法及查询技巧是非常必要的。

通过建立索引库,搜索查询服务器,以及Web交互,我们基本实现了搜索引擎的核心功能,建立了具有中文分词和关键词高亮显示功能的中文搜索引擎系统。总体来讲,该中文搜索引擎具有很好的可维护性和可扩展性,可以在此基础上开发适应不同业务需求的搜索引擎。

总结这次搜索引擎程序的实现,发现一个好的搜索引擎,首先需要一个好的爬虫,能够帮你把网络上的各种网页抓取到本地;能够对网页进行去重;考虑到时间或资源成本,还要求爬虫能对网页的重要性进行一定的判断,即先抓取“重要”的网页;还要能及时地更新已有的网页,其次,一个搜索引擎还需要有一套行之有效的索引系统,能够将搜索效率提高,这里涉及到太多东西,以后还需要继续学习。

 

六、看到了这里,我觉得你可以右上角点赞收藏转发了。。。谢谢各位!!!

要源码的话下面留言。。。。

版权声明:转载请注明出处! https://blog.csdn.net/qq_35993946/article/details/88087827

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!