要想实现一个搜索引擎,首先要了解什么是搜索引擎。简单地理解,搜索引擎是一个系统,它可以帮助用户去互联网上搜集与其检索内容相关的信息。
通常,一个搜索引擎由搜索器、索引器、检索器以及用户接口组成,其中各个部分的含义如下:
由于爬虫知识不是本节学习的重点,这里不再做深入介绍,我们假设搜索样本就存在于本地磁盘中。为了方便,这里只提供五个用于检索的文件,各文件存放的内容分别如下:
下面,根据以上知识,我们先实现一个最基本的搜索引擎:
class SearchEngineBase:
def __init__(self):
pass
#搜索器
def add_corpus(self, file_path):
with open(file_path, 'rb') as fin:
text = fin.read().decode('utf-8')
self.process_corpus(file_path, text)
#索引器
def process_corpus(self, id, text):
raise Exception('process_corpus not implemented.')
#检索器
def search(self, query):
raise Exception('search not implemented.')
#用户接口
def main(search_engine):
for file_path in ['1.txt', '2.txt', '3.txt', '4.txt', '5.txt']:
search_engine.add_corpus(file_path)
while True:
query = input()
results = search_engine.search(query)
print('found {} result(s):'.format(len(results)))
for result in results:
print(result)
以上代码仅是建立了搜索引擎的一个基本框架,它可以作为基类被其他类继承,那么继承自此类的类将分别代表不同的搜索引擎,它们应该各自实现基类中的 process_corpus() 和 search() 方法。
整个代码的运行过程是这样的,首先将各个检索文件中包含的内容连同该文件所在的路径一起传递给索引器,索引器会以该文件的路径建立索引,等待用户检索。
在 SearchEngineBase 类的基础上,下面实现了一个基本可以工作的搜索引擎:
#继承SearchEngineBase类,并重写了 process_corpus 和 search 方法
class SimpleEngine(SearchEngineBase):
def __init__(self):
super(SimpleEngine, self).__init__()
#建立索引时使用
self.__id_to_texts = {}
def process_corpus(self, id, text):
#以文件路径为键,文件内容为值,形成键值对,存储在字典中,由此建立索引
self.__id_to_texts[id] = text
def search(self, query):
results = []
#依次检索字典中的键值对,如果文件内容中包含用户要搜索的信息,则将此文件的文件路径存储在 results 列表中
for id, text in self.__id_to_texts.items():
if query in text:
results.append(id)
return results
search_engine = SimpleEngine()
main(search_engine)
运行结果为:
可以看到,用户搜索与“城东书院”有关的内容,最终检索到了 1.txt、3.txt和 4.txt 文件中包含与之相关的内容。由此,只需要短短十来行代码就可以实现一个基础的搜索引擎。