当前位置: 代码迷 >> 综合 >> scrapy+jieba+whoosh实现搜索引擎
  详细解决方案

scrapy+jieba+whoosh实现搜索引擎

热度:9   发布时间:2024-02-12 03:05:37.0

开始

学校小学期开了一门信息检索的课,结果碰到了大作业是实现垂直领域的搜索引擎,其中我们是要用网页展示的(当然了也可以用命令行,只是扣一点分)。

自己在csdn和github上收集了很多资料,但是好多都没办法实现,尤其是(我感觉见到最多的一个项目)就是《Python分布式爬虫打造搜索引擎》。

这个主要原因是一是因为原来的网站伯乐在线不明原因不能访问了,二是因为自己实现完scrapy爬虫后在Elasticsearch和Django的交互上卡住了,后面只能放弃了。

后面和同学们交流了下,发现有个特别方便的python库whoosh+jieba,可以帮助我们实现搜索引擎,简单快捷。这个博客我是只展示了在命令行实现搜索引擎,至于弄前端实现网页,我可能得等我忙完学校开学考试再发一篇blog讲解。

心中默念 信息检索sb课程 什么都没学就让我们实现

scrapy爬虫

这部分内容,我其实可以建议大家直接去看,资源很多,我在这里分享下一个博主的blog第四部分,大家可以跟着他实现,只看他scrapy爬虫的部分。

我这部分的代码也会给出来hitsz新闻引擎。我这里主要是是实现了爬取学校官网新闻,对代码进行了些小改动。

PS:这里爬虫用到了xpath,大家可以去chrome的商店里面下载一个xpath helper的插件,这里xpath怎么使用就不讲解了,主要提供思路,自己试着修改下xpath来看看能定位到什么东西。

就这里特别要注意
pip install elasticsearch_dsl==5.1.0
其他正常pip就好了

具体使用是
1、用pycharm打开 ArticleSpider的文件夹。
大家一定要整个文件用pycharm打开,不要只打开某一个py文件!!!会省很多事情!!!
在这里插入图片描述
2、运行 main.py即可,或者用命令行运行也可以。
3、最后会输出一个json文件,也就是图中的articleexport.json。

我这里已经包含好数据,爬取了200页学校官网新闻网址。你可以不用跑这部分代码,直接跳过到搜索引擎建立的部分。
在这里插入图片描述

jieba+whoosh实现搜索引擎

到了这部分就简单了,就是调库就完事了。大家先看看,jieba+whoosh实现简单搜索的代码。
在jieba的github地址里面找到的一个test。test_whoosh

PS:pip install jieba,whoosh

# -*- coding: UTF-8 -*-
from __future__ import unicode_literals
import sys,os
sys.path.append("../")
from whoosh.index import create_in,open_dir
from whoosh.fields import *
from whoosh.qparser import QueryParserfrom jieba.analyse.analyzer import ChineseAnalyzeranalyzer = ChineseAnalyzer()schema = Schema(title=TEXT(stored=True), path=ID(stored=True), content=TEXT(stored=True, analyzer=analyzer))
if not os.path.exists("tmp"):os.mkdir("tmp")ix = create_in("tmp", schema) # for create new index
#ix = open_dir("tmp") # for read only
writer = ix.writer()writer.add_document(title="document1",path="/a",content="This is the first document we’ve added!"
)writer.add_document(title="document2",path="/b",content="The second one 你 中文测试中文 is even more interesting! 吃水果"
)writer.add_document(title="document3",path="/c",content="买水果然后来世博园。"
)writer.add_document(title="document4",path="/c",content="工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作"
)writer.add_document(title="document4",path="/c",content="咱俩交换一下吧。"
)writer.commit()
searcher = ix.searcher()
parser = QueryParser("content", schema=ix.schema)for keyword in ("水果世博园","你","first","中文","交换机","交换"):print("result of ",keyword)q = parser.parse(keyword)results = searcher.search(q)for hit in results:print(hit.highlights("content"))print("="*10)for t in analyzer("我的好朋友是李明;我爱北京天安门;IBM和Microsoft; I have a dream. this is intetesting and interested me a lot"):print(t.text)

大家可以先复制这段代码跑一跑,并修改下。

很明显,我们可以看到要修改的地方其实很简单
1、就是writer.add_document,这里相对于添加搜索的对象,这里是一个个加入。我们前面爬虫得到了json文件,那我们是不是可以用循环把json文件里面的数据导入就好了。
2、这段代码是第一次用来建立tmp的缓存文件,相当于存储了模型信息,后面我们可以直接读取这些信息,没必要再次建立。

schema = Schema(title=TEXT(stored=True), path=ID(stored=True), content=TEXT(stored=True, analyzer=analyzer))
if not os.path.exists("tmp"):os.mkdir("tmp")ix = create_in("tmp", schema) # for create new index

把上面的代码注释掉,改成下面的。

ix = open_dir("tmp") # for read only

3、就是对象的属性,记得要修改,我这里只用了title,url和content三个属性,大家看着改一下。

ok了接下来,我就把我的修改后的代码放上来。

# -*- coding: UTF-8 -*-
from __future__ import unicode_literals
import sys,os
sys.path.append("../")
from whoosh.index import create_in,open_dir
from whoosh.fields import *
from whoosh.qparser import QueryParserfrom jieba.analyse.analyzer import ChineseAnalyzeranalyzer = ChineseAnalyzer()import jsonwith open('articleexport.json','r',encoding='utf-8') as fp:json_data=json.load(fp)schema = Schema(title=TEXT(stored=True), url=TEXT(stored=True), content=TEXT(stored=True, analyzer=analyzer))
if not os.path.exists("tmp"):os.mkdir("tmp")ix = create_in("tmp", schema) # for create new index
#ix = open_dir("tmp") # for read only
writer = ix.writer()for item in json_data:writer.add_document(title=item['title'],url=item['url'],content=item['content'])
'''writer.add_document(title="document1",path="/a",content="This is the first document we’ve added!" )writer.add_document(title="document2",path="/b",content="The second one 你 中文测试中文 is even more interesting! 吃水果" )writer.add_document(title="document3",path="/c",content="买水果然后来世博园。" )writer.add_document(title="document4",path="/c",content="工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作" )writer.add_document(title="document4",path="/c",content="咱俩交换一下吧。" ) '''writer.commit()
searcher = ix.searcher()
parser = QueryParser("content", schema=ix.schema)
'''for keyword in ("水果世博园","你","first","中文","交换机","交换"):print("result of ",keyword)q = parser.parse(keyword)results = searcher.search(q)for hit in results:print(hit.highlights("content"))print(hit.rank)print("="*10)'''#for t in analyzer("我的好朋友是李明;我爱北京天安门;IBM和Microsoft; I have a dream. this is intetesting and interested me a lot"):
# print(t.text)if __name__ == '__main__':search_text=input("Please input :")while(search_text):q = parser.parse(search_text)results = searcher.search(q)for hit in results:#print(hit.highlights("content"))print(hit['title'])print(hit['url'])print(hit.score)print('=' * 10)print('*'*20+"search end !"+'*'*20)search_text = input("Please input :")

展示

大家run一下,文件夹下面的whoosh_try.py。在命令行中input你要搜索的信息。

在这里插入图片描述
在这里插入图片描述
效果大概这样了,输出三个,第一个是title,第二个是url,也就是原文链接,第三个内部评分指标(?)。输出内容可以自己修改,大家可以自己尝试修改。

我发现这个搜索引擎有个问题就是,相关度太低了它就不会输出,比如 “湛江”,其实我自己用es查询时是有好几篇content都有出现过,但用了whoosh时却只展示一个。但要是查“哈工大”“百年校庆”“周玉”等关键词,效果就非常好。

结束

兄弟萌这次博客就写到这里了!喜欢就点个赞吧,有问题下面留言或者私信都可以。这算是自己找到最容易实现的搜索引擎方法,其他的用到es或者lucence的对于大二学生来说有点太难了。

再次吐槽这门课,明明感觉没学到什么东西,结果还得整个这个大作业人都傻了,而且数据库前端后端一个都没学过,爬虫也是现学现会的。

网页版搜索引擎之后我看看有没时间写一篇blog,根据我身边大部分同学的思路就是自己手写一个丑到不行网页,用flask框架前后端联通就ok了。

  相关解决方案