您的位置:首页 > 编程语言 > Python开发

python无脑搜索引擎实现<一>

2015-11-12 23:55 926 查看
越来越多没填的坑。而我还在开新的坑。。。。。。

这次实现了一个搜索引擎,语言为python,搜索内容为自己从知乎上面抓下来的10万个问题。仅搜索问题题目。

以下大概是搜索效果:



其实搜索引擎的建立基础流程也就那样,最主要的是大量,不不不,巨量的数据处理,巨量的算法,巨量的排序。

下面是流程分析:

一 爬取网页

这一块感觉没啥好说的, 就是学了两三天scrapy,当然其中很多的弯弯绕绕我也没搞懂,但是基本的使用确实能满足要求了。爬取使用了深度优先爬,本程序中,使用的方式是从五个种子问题开始,爬标题,url,html文档,获取当前页面中http://www.zhihu.com/question开头的网址。然后从获取的新的网址中进行新一轮的递归,从而完成深度优先的爬取。不过书上说广度优先爬取比较好,因为如果从首页开始爬,深度越浅,说明该页面越重要(有道理)。但是我们爬知乎的问题之间的关系都是平行的,所以不存在这个问题。

爬到的数据库用sqlite3存起来,不得不敬服一下女朋友在数据库上深厚的造诣,我是搞不定数据库的语法了T T。

保存结果用SQLiteSpy打开大概这样:



id就是自动增长的主键,也就是后面会说的docID,url是url,title是title(。。。),然后code是html代码,太长了后面自动没显示。之所以存html是因为。。反正都要把html爬下来,学校的校园网要钱,不存下来太浪费了,万一想做全文索引呢?

10w条数据,占了6G,女朋友爬的百度知道,也是10W,竟然爬了16G= =,流量在燃烧。

二 分词

其实之所以用python,很大程度是因为python有jieba这个相当好用+高效+无脑的分词库给我们用,这里必须要感谢其作者
fxsjy


jieba太好用了,无论是效果还是简易性,好用到我都不想讲,留个连接,需要的自己学习:http://www.oschina.net/p/jieba

对每一个page,我们都对其title进行分词然后存入词典。嗯就这样。

三 索引

1)词典

词典是什么呢?上一部我们分词,分词完呢就需要给每个词分配一个wordID,从word->wordID的映射称之为词典。嗯。至于分配什么wordID,你可以用MD5或者什么花式哈希,但我用的自动递增。嗯。

2)正排索引

正排索引:就是docID->hitlist的索引。docID就是之前给每一个page分配的ID,hitlist就是对title分词后形成的列表。也就是通过docID,索引到该title的分词结果。其实正排索引还需要记录共有多少个hit,hit就是分出来的词。按照大众玩法,是在内存中建立一定数量的正排索引,然后一股脑写到一个临时倒排文件,然后再建立新的正排索引,写到新的临时倒排文件。最后合并所有临时倒排文件。不过我这儿一共就10Wpage,所以直接就都在内存中操作了。

3) 倒排索引

倒排索引:就是wordID到docList的索引。docList就是包含该wordID的所有title所在的doc的编号的集合。这个倒排索引怎么建呢?在1)和2)中,我们一边建立正排索引,一边建立词典(其实词典应该是已知的)。然后正排索引是一个docID对应多个wordID,我们把所有正排索引按照wordID进行一次稳定排序。这样一来,wordID就变成了递增的。又因为docID是天然不刺激,不,是天然有序的。所以连续的wordID对应的docID也是有序的。然后依次把每一个wordID对应的所有docID写入倒排表的该wordID表项中。即不需要在磁盘上做任何数据的移动,依次写入即可。从而大大增加了效率。当然,我们这点儿可怜的数据量,不仅没有多个临时倒排文件,连倒排表都是在内存中建立后再写入的磁盘。

词典以及使用正排表生成的倒排表的逻辑概念如下图所示:



再次:hit就是分出来的词

4)查询系统

好了,服务端的做完了,该做给人用的接口了

1. 输入query

2. 对query分词

3. 对2中的每个词,在lexicon中转为wordID

4. 对3中的每一个wordID,在倒排索引中找到出现过的所有docID

5. 对4中的每一个检索出来的docID,记录其被由query分词得到的所有词检索出来的总次数

6. 对5种所有的检索次数排序,返回检索出来总次数最高的10个doc的url和title

7. print

好了,就这样了,逻辑上大概就解释完了,代码我就不贴了,后面可能再单独分析代码,不过按我的以前的情况来看。。有空细细分析代码的可能性好像不是很大。

代码放在了EZSearchEngine

使用方法:

fork下来,然后运行SearchEngine目录下的SearchMain.py就成。

index.db里面放着词典和倒排索引,不在这儿秀了,如果有人看,可以fork了自己看。。。

最后再测试一下搜索:



第二条好像排序过高,这种玩具,果然毕竟还是图样。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: