关于elasticsearch:46elasticsearch搜索引擎scrapy写入数据到elasticsearch中

75次阅读

共计 12191 个字符,预计需要花费 31 分钟才能阅读完成。

【百度云搜寻,搜各种材料:http://www.lqkweb.com】
【搜网盘,搜各种材料:http://www.swpan.cn】

后面咱们讲到的 elasticsearch(搜索引擎)操作,如:增、删、改、查等操作都是用的 elasticsearch 的语言命令,就像 sql 命令一样,当然 elasticsearch 官网也提供了一个 python 操作 elasticsearch(搜索引擎)的接口包,就像 sqlalchemy 操作数据库一样的 ORM 框,这样咱们操作 elasticsearch 就不必写命令了,用 elasticsearch-dsl-py 这个模块来操作,也就是用 python 的形式操作一个类即可

elasticsearch-dsl-py 下载

下载地址:https://github.com/elastic/el…

文档阐明:http://elasticsearch-dsl.read…

首先装置好 elasticsearch-dsl-py 模块

1、elasticsearch-dsl 模块应用阐明

create_connection(hosts=[‘127.0.0.1’]):连贯 elasticsearch(搜索引擎)服务器办法,能够连贯多台服务器
class Meta:设置索引名称和表名称
索引类名称.init(): 生成索引和表以及字段
实例化索引类.save(): 将数据写入 elasticsearch(搜索引擎)

elasticsearch_orm.py 操作 elasticsearch(搜索引擎)文件

#!/usr/bin/env python
# -*- coding:utf8 -*-
from datetime import datetime
from elasticsearch_dsl import DocType, Date, Nested, Boolean, \
    analyzer, InnerObjectWrapper, Completion, Keyword, Text, Integer

# 更多字段类型见第三百六十四节 elasticsearch(搜索引擎)的 mapping 映射治理

from elasticsearch_dsl.connections import connections       # 导入连贯 elasticsearch(搜索引擎)服务器办法
connections.create_connection(hosts=['127.0.0.1'])

class lagouType(DocType):                                                   # 自定义一个类来继承 DocType 类
    # Text 类型须要分词,所以须要晓得中文分词器,ik_max_wordwei 为中文分词器
    title = Text(analyzer="ik_max_word")                                    # 设置,字段名称 = 字段类型,Text 为字符串类型并且能够分词建设倒排索引
    description = Text(analyzer="ik_max_word")
    keywords = Text(analyzer="ik_max_word")
    url = Keyword()                                                         # 设置,字段名称 = 字段类型,Keyword 为一般字符串类型,不分词
    riqi = Date()                                                           # 设置,字段名称 = 字段类型,Date 日期类型

    class Meta:                                                             # Meta 是固定写法
        index = "lagou"                                                     # 设置索引名称(相当于数据库名称)
        doc_type = 'biao'                                                   # 设置表名称

if __name__ == "__main__":          # 判断在本代码文件执行才执行外面的办法,其余页面调用的则不执行外面的办法
    lagouType.init()                # 生成 elasticsearch(搜索引擎)的索引,表,字段等信息

# 应用办法阐明:# 在要要操作 elasticsearch(搜索引擎)的页面,导入此模块
# lagou = lagouType()           #实例化类
# lagou.title = '值'            #要写入字段 = 值
# lagou.description = '值'
# lagou.keywords = '值'
# lagou.url = '值'
# lagou.riqi = '值'
# lagou.save()                  #将数据写入 elasticsearch(搜索引擎)

2、scrapy 写入数据到 elasticsearch 中

爬虫文件

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from adc.items import LagouItem,LagouItemLoader  #导入 items 容器类, 和 ItemLoader 类
import time

class LagouSpider(CrawlSpider):                     #创立爬虫类
    name = 'lagou'                                  #爬虫名称
    allowed_domains = ['www.luyin.org']             #起始域名
    start_urls = ['http://www.luyin.org/']          #起始 url

    custom_settings = {
        "AUTOTHROTTLE_ENABLED": True,                             #笼罩掉 settings.py 里的雷同设置,开启 COOKIES
        "DOWNLOAD_DELAY":5
    }

    rules = (
        #配置抓取列表页规定
        Rule(LinkExtractor(allow=('ggwa/.*')), follow=True),

        #配置抓取内容页规定
        Rule(LinkExtractor(allow=('post/\d+.html.*')), callback='parse_job', follow=True),
    )

    def parse_job(self, response):                  #回调函数,留神:因为 CrawlS 模板的源码创立了 parse 回调函数,所以切记咱们不能创立 parse 名称的函数
        atime = time.localtime(time.time())         #获取零碎以后工夫
        dqatime = "{0}-{1}-{2} {3}:{4}:{5}".format(
            atime.tm_year,
            atime.tm_mon,
            atime.tm_mday,
            atime.tm_hour,
            atime.tm_min,
            atime.tm_sec
        )  # 将格式化工夫日期,独自取出来拼接成一个残缺日期

        url = response.url

        item_loader = LagouItemLoader(LagouItem(), response=response)   # 将数据填充进 items.py 文件的 LagouItem
        item_loader.add_xpath('title', '/html/head/title/text()')
        item_loader.add_xpath('description', '/html/head/meta[@name="Description"]/@content')
        item_loader.add_xpath('keywords', '/html/head/meta[@name="keywords"]/@content')
        item_loader.add_value('url', url)
        item_loader.add_value('riqi', dqatime)
        article_item = item_loader.load_item()
yield article_item

items.py 文件

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
#items.py, 文件是专门用于,接管爬虫获取到的数据信息的,就相当于是容器文件

import scrapy
from scrapy.loader.processors import MapCompose,TakeFirst
from scrapy.loader import ItemLoader                #导入 ItemLoader 类也就加载 items 容器类填充数据
from adc.models.elasticsearch_orm import lagouType  #导入 elasticsearch 操作模块

class LagouItemLoader(ItemLoader):                  #自定义 Loader 继承 ItemLoader 类,在爬虫页面调用这个类填充数据到 Item 类
    default_output_processor = TakeFirst()          #默认利用 ItemLoader 类,加载 items 容器类填充数据,是列表类型,能够通过 TakeFirst()办法,获取到列表里的内容

def tianjia(value):                                 #自定义数据预处理函数
    return value                                    #将解决后的数据返给 Item

class LagouItem(scrapy.Item):                       #设置爬虫获取到的信息容器类
    title = scrapy.Field(                           #接管爬虫获取到的 title 信息
        input_processor=MapCompose(tianjia),        #将数据预处理函数名称传入 MapCompose 办法里解决,数据预处理函数的形式参数 value 会主动接管字段 title
    )
    description = scrapy.Field()
    keywords = scrapy.Field()
    url = scrapy.Field()
    riqi = scrapy.Field()

    def save_to_es(self):
        lagou = lagouType()                         # 实例化 elasticsearch(搜索引擎对象)
        lagou.title = self['title']                 # 字段名称 = 值
        lagou.description = self['description']
        lagou.keywords = self['keywords']
        lagou.url = self['url']
        lagou.riqi = self['riqi']
        lagou.save()                                # 将数据写入 elasticsearch(搜索引擎对象)
        return

pipelines.py 文件

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
from adc.models.elasticsearch_orm import lagouType  #导入 elasticsearch 操作模块

class AdcPipeline(object):
    def process_item(self, item, spider):

        #也能够在这里将数据写入 elasticsearch 搜索引擎,这里的毛病是对立解决
        # lagou = lagouType()
        # lagou.title = item['title']
        # lagou.description = item['description']
        # lagou.keywords = item['keywords']
        # lagou.url = item['url']
        # lagou.riqi = item['riqi']
        # lagou.save()
        item.save_to_es()       #执行 items.py 文件的 save_to_es 办法将数据写入 elasticsearch 搜索引擎
        return item

settings.py 文件,注册 pipelines

# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {'adc.pipelines.AdcPipeline': 300,}

main.py 爬虫启动文件

#!/usr/bin/env python
# -*- coding:utf8 -*-

from scrapy.cmdline import execute  #导入执行 scrapy 命令办法
import sys
import os

sys.path.append(os.path.join(os.getcwd())) #给 Python 解释器,增加模块新门路 , 将 main.py 文件所在目录增加到 Python 解释器

execute(['scrapy', 'crawl', 'lagou', '--nolog'])  #执行 scrapy 命令

# execute(['scrapy', 'crawl', 'lagou'])  #执行 scrapy 命令

运行爬虫

写入 elasticsearch(搜索引擎)状况

补充:elasticsearch-dsl  的 增删改查

#!/usr/bin/env python
# -*- coding:utf8 -*-
from datetime import datetime
from elasticsearch_dsl import DocType, Date, Nested, Boolean, \
    analyzer, InnerObjectWrapper, Completion, Keyword, Text, Integer

# 更多字段类型见第三百六十四节 elasticsearch(搜索引擎)的 mapping 映射治理

from elasticsearch_dsl.connections import connections       # 导入连贯 elasticsearch(搜索引擎)服务器办法
connections.create_connection(hosts=['127.0.0.1'])

class lagouType(DocType):                                                   # 自定义一个类来继承 DocType 类
    # Text 类型须要分词,所以须要晓得中文分词器,ik_max_wordwei 为中文分词器
    title = Text(analyzer="ik_max_word")                                    # 设置,字段名称 = 字段类型,Text 为字符串类型并且能够分词建设倒排索引
    description = Text(analyzer="ik_max_word")
    keywords = Text(analyzer="ik_max_word")
    url = Keyword()                                                         # 设置,字段名称 = 字段类型,Keyword 为一般字符串类型,不分词
    riqi = Date()                                                           # 设置,字段名称 = 字段类型,Date 日期类型

    class Meta:                                                             # Meta 是固定写法
        index = "lagou"                                                     # 设置索引名称(相当于数据库名称)
        doc_type = 'biao'                                                   # 设置表名称

if __name__ == "__main__":          # 判断在本代码文件执行才执行外面的办法,其余页面调用的则不执行外面的办法
    lagouType.init()                # 生成 elasticsearch(搜索引擎)的索引,表,字段等信息

# 应用办法阐明:# 在要要操作 elasticsearch(搜索引擎)的页面,导入此模块
# lagou = lagouType()           #实例化类
# lagou.title = '值'            #要写入字段 = 值
# lagou.description = '值'
# lagou.keywords = '值'
# lagou.url = '值'
# lagou.riqi = '值'
# lagou.save()                  #将数据写入 elasticsearch(搜索引擎)

1 新增数据

from adc.models.elasticsearch_orm import lagouType  #导入方才配置的 elasticsearch 操作模块

     lagou = lagouType()                         # 实例化 elasticsearch(搜索引擎对象)
     lagou._id = 1             #自定义 ID,很重要,当前都是依据 ID 来操作

        lagou.title = self['title']                 # 字段名称 = 值
        lagou.description = self['description']
        lagou.keywords = self['keywords']
        lagou.url = self['url']
        lagou.riqi = self['riqi']
        lagou.save()                                # 将数据写入 elasticsearch(搜索引擎对象)

2 删除指定数据

from adc.models.elasticsearch_orm import lagouType  #导入方才配置的 elasticsearch 操作模块
sousuo_orm = lagouType()                    # 实例化
sousuo_orm.get(id=1).delete()               # 删除 id 等于 1 的数据

3 批改指定的数据

from adc.models.elasticsearch_orm import lagouType  #导入方才配置的 elasticsearch 操作模块

sousuo_orm = lagouType()                           # 实例化
sousuo_orm.get(id=1).update(title='123456789')     # 批改 id 等于 1 的数据

以上全副应用 elasticsearch-dsl 模块

留神上面应用的原生 elasticsearch 模块

删除指定应用,就是相当于删除指定数据库

应用原生 elasticsearch 模块删除指定索引

from elasticsearch import Elasticsearch                                     # 导入原生的 elasticsearch(搜索引擎)接口
client = Elasticsearch(hosts=settings.Elasticsearch_hosts)                  # 连贯原生的 elasticsearch

# 应用原生 elasticsearch 模块删除指定索引
#要做容错解决,如果索引不存在会报错
            try:
                client.indices.delete(index='jxiou_zuopin')
            except Exception as e:
                pass

原生查问

from elasticsearch import Elasticsearch                 # 导入原生的 elasticsearch(搜索引擎)接口
            client = Elasticsearch(hosts=Elasticsearch_hosts)       # 连贯原生的 elasticsearch

response = client.search(# 原生的 elasticsearch 接口的 search()办法,就是搜寻,能够反对原生 elasticsearch 语句查问
                index="jxiou_zuopin",                               # 设置索引名称
                doc_type="zuopin",                                  # 设置表名称
                body={                                              # 书写 elasticsearch 语句
                    "query": {
                        "multi_match": {                            # multi_match 查问
                            "query": sousuoci,                      # 查问关键词
                            "fields": ["title"]                     # 查问字段
                        }
                    },
                    "from": (page - 1) * tiaoshu,                   # 从第几条开始获取
                    "size": tiaoshu,                                # 获取多少条数据
                    "highlight": {                                  # 查问关键词高亮解决
                        "pre_tags": ['<span class="gaoliang">'],    # 高亮开始标签
                        "post_tags": ['</span>'],                   # 高亮完结标签
                        "fields": {                                 # 高亮设置
                            "title": {}                             # 高亮字段}
                    }
                }
            )
            # 开始获取数据
            total_nums = response["hits"]["total"]                  # 获取查问后果的总条数

            hit_list = []                                           # 设置一个列表来贮存搜寻到的信息,返回给 html 页面

            for hit in response["hits"]["hits"]:                                # 循环查问到的后果
                hit_dict = {}                                                   # 设置一个字典来贮存循环后果
                if "title" in hit["highlight"]:                                 # 判断 title 字段,如果高亮字段有类容
                    hit_dict["title"] = "".join(hit["highlight"]["title"])      # 获取高亮里的 title
                else:
                    hit_dict["title"] = hit["_source"]["title"]                 # 否则获取不是高亮里的 title

                hit_dict["id"] = hit["_source"]["nid"]                          # 获取返回 nid

                # 加密样音地址
                hit_dict["yangsrc"] = jia_mi(str(hit["_source"]["yangsrc"]))    # 获取返回 yangsrc

                hit_list.append(hit_dict)

正文完
 0