4六、elasticsearch(搜索引擎)scrapy寫入數據到elasticsearch中

百度雲搜索,搜各類資料:http://www.lqkweb.com
搜網盤,搜各類資料:http://www.swpan.cn

前面咱們講到的elasticsearch(搜索引擎)操做,如:增、刪、改、查等操做都是用的elasticsearch的語言命令,就像sql命令同樣,固然elasticsearch官方也提供了一個python操做elasticsearch(搜索引擎)的接口包,就像sqlalchemy操做數據庫同樣的ORM框,這樣咱們操做elasticsearch就不用寫命令了,用elasticsearch-dsl-py這個模塊來操做,也就是用python的方式操做一個類便可html

elasticsearch-dsl-py下載python

下載地址:https://github.com/elastic/el...git

文檔說明:http://elasticsearch-dsl.read...github

首先安裝好elasticsearch-dsl-py模塊web

一、elasticsearch-dsl模塊使用說明sql

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(搜索引擎)

二、scrapy寫入數據到elasticsearch中app

爬蟲文件dom

# -*- 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命令

運行爬蟲

image

寫入elasticsearch(搜索引擎)狀況

image

補充: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)
相關文章
相關標籤/搜索