scrapy+jieba+whoosh实现搜索引擎

开始

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

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

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

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

心中默念 什么都没学就让我们实现

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 QueryParser

from jieba.analyse.analyzer import ChineseAnalyzer

analyzer = 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 QueryParser

from jieba.analyse.analyzer import ChineseAnalyzer

analyzer = ChineseAnalyzer()

import json

with 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了。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
好的,您的问题是关于如何基于PythonScrapy、Redis和Rule组件实现分布式爬虫爬取京东华为笔记本的。首先,您需要安装Scrapy和Redis,并在Scrapy的配置文件中添加Redis相关的配置: ```python # 在settings.py中添加以下配置 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" SCHEDULER = "scrapy_redis.scheduler.Scheduler" SCHEDULER_PERSIST = True REDIS_URL = 'redis://localhost:6379' ``` 然后,您需要编写Spider和Item Pipeline,其中Spider负责解析并抓取网页,Item Pipeline负责处理抓取到的数据。下面是一个示例的Spider代码: ```python from scrapy_redis.spiders import RedisSpider from scrapy.selector import Selector from ..items import ProductItem class JdSpider(RedisSpider): name = 'jd' redis_key = 'jd:start_urls' def parse(self, response): sel = Selector(response) products = sel.xpath('//div[@class="gl-i-wrap"]') for product in products: item = ProductItem() item['name'] = product.xpath('div[@class="p-name"]/a/em/text()').extract_first() item['price'] = product.xpath('div[@class="p-price"]/strong/i/text()').extract_first() item['url'] = product.xpath('div[@class="p-name"]/a/@href').extract_first() yield item ``` 在Item Pipeline中,您可以对抓取到的数据进行清洗和存储,下面是一个示例的Item Pipeline代码: ```python import pymongo class JdPipeline(object): def __init__(self, mongo_uri, mongo_db): self.mongo_uri = mongo_uri self.mongo_db = mongo_db @classmethod def from_crawler(cls, crawler): return cls( mongo_uri=crawler.settings.get('MONGO_URI'), mongo_db=crawler.settings.get('MONGO_DATABASE', 'items') ) def open_spider(self, spider): self.client = pymongo.MongoClient(self.mongo_uri) self.db = self.client[self.mongo_db] def close_spider(self, spider): self.client.close() def process_item(self, item, spider): self.db['products'].insert(dict(item)) return item ``` 最后,您需要创建一个Redis队列,并向队列中添加起始URL,如下所示: ```python import redis r = redis.Redis(host='localhost', port=6379) r.lpush('jd:start_urls', 'https://search.jd.com/Search?keyword=%E5%8D%8E%E4%B8%BA%E7%AC%94%E8%AE%B0%E6%9C%AC&enc=utf-8') ``` 最终,您就可以运行分布式爬虫并抓取京东华为笔记本的数据了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值