当前位置: 首页 > 科技观察

10分钟搭建一个好玩的Python全文搜索引擎

时间:2023-03-11 20:24:29 科技观察

有群友在群里问如何快速搭建一个搜索引擎。搜索了一下,看到了这段代码所在的Git:https://github.com/asciimoo/searx官方很贴心,很方便,提供了一个docker镜像,基本以后就可以轻松使用了拉下来。执行命令cid=$(sudodockerps-a|grepsearx|awk'{print$1}')echosearxcidis$cidif["$cid"!=""];thensudodockerstop$cidsudodockerrm$cidfisudodockerrun-d--namesearx-eIMAGE_PROXY=True-eBASE_URL=http://yourdomain.com-p7777:8888wonderfall/searx然后就可以使用了,查看docker正常状态,可以正常使用。想想,是不是很方便?我们来看看源码是如何实现的。我们打开里面的代码。其实本质就是对请求后的结果做一个大聚合。Asforthedatasource,我们可以是来于DB,或者文件,我们可以看一下他的核心代码fromurllibimporturlencodefromjsonimportloadsfromcollectionsimportIterablesearch_url=Noneurl_query=Nonecontent_query=Nonetitle_query=Nonesuggestion_query=''results_query=''#parametersforengineswithpagingsupport##numberofresultsoneachpage#(onlyneededifthesiterequiresnotapagenumber,butanoffset)page_size=1#numberofthefirstpage(usually0or1)first_page_num=1defiterate(iterable):iftype(iterable)==dict:it=iterable.iteritems()else:it=enume速率(可迭代)forindex,valueinit:yieldstr(索引),valuedefis_iterable(obj):iftype(obj)==str:returnFalseiftype(obj)==unicode:returnFalsereturnisinstance(obj,Iterable)defparse(查询):q=[]forpartinquery.split('/'):ifpart=='':continueelse:q.append(part)returnqdefdo_query(data,q):ret=[]ifnotq:returnretqqkey=q[0]forkey,valueiniterate(data):iflen(q)==1:ifkey==qkey:ret.append(value)elifis_iterable(value):ret.extend(do_query(value,q))else:ifnotis_iterable(value):continueifkey==qkey:ret.extend(do_query(值,q[1:]))else:ret.extend(do_query(value,q))returnretdefquery(data,query_string):q=parse(query_string)returndo_query(data,q)defrequest(query,params):query=urlencode({'q':query})[2:]fp={'query':query}ifpagingandsearch_url.find('{pageno}')>=0:fp['pageno']=(params['pageno']-1)*page_size+first_page_numparams['url']=search_url.format(**fp)params['query']=queryreturnparamsdefresponse(resp):results=[]json=loads(resp.text)ifresults_query:forresultinquery(json,r结果查询)[0]:url=查询(结果,url_查询)[0]标题=查询(结果,标题查询)[0]内容=查询(结果,内容查询)[0]results.append({'url':url,'title':title,'content':content})else:forurl,title,contentzip(query(json,url_query),query(json,title_query),query(json,content_query)):results.append({'url':url,'title':title,'content':content})ifnotsuggestion_query:returnresultsforsuggestioninquery(json,suggestion_query):results.append({'suggestion':suggestion})returnresultsresults每个响应的结果我们必须很容易的数据自定义返回的(可以是网络,可以是数据库,也可以是文件),我们再想一想,如果我们可以hack响应结果,那么我们可以把我们爬取的数据作为返回结果,如果是1024就好了,你可以打造自己的“爱好”小引擎,代码我就不贴了,大家可以自己玩。结合jieba分词,可以更好玩。