47、Python快速開發(fā)分布式搜索引擎Scrapy精講—elasticsearch(搜索引擎)用Django實現(xiàn)搜索的自動補全功能

百度云搜索,搜各種資料:http://bdy.lqkweb.com

搜網(wǎng)盤,搜各種資料:http://www.swpan.cn

image

elasticsearch(搜索引擎)提供了自動補全接口

官方說明:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html

1霞幅、創(chuàng)建搜索自動補全字段suggest

自動補全需要用到一個字段名稱為suggest類型為Completion類型的一個字段

所以我們需要用將前面的elasticsearch-dsl操作elasticsearch(搜索引擎)增加suggest類型為Completion

注意:因為elasticsearch-dsl源碼問題漠吻,設置字段為Completion類型指定分詞器時會報錯,所以我們需要重寫CustomAnalyzer類

只有Completion類型才是司恳,其他類型不用途乃,其他類型直接指定分詞器即可

#!/usr/bin/env python

from datetime import datetime
from elasticsearch_dsl import DocType, Date, Nested, Boolean, \
    analyzer, InnerObjectWrapper, Completion, Keyword, Text, Integer

# 更多字段類型見第三百六十四節(jié)elasticsearch(搜索引擎)的mapping映射管理
from elasticsearch_dsl.analysis import CustomAnalyzer as _CustomAnalyzer    #導入CustomAnalyzer類

from elasticsearch_dsl.connections import connections                       # 導入連接elasticsearch(搜索引擎)服務器方法
connections.create_connection(hosts=['127.0.0.1'])

class CustomAnalyzer(_CustomAnalyzer):                                      # 自定義CustomAnalyzer類,來重寫CustomAnalyzer類
    def get_analysis_definition(self):
        return {}

ik_analyzer = CustomAnalyzer("ik_max_word", filter=["lowercase"])           # 實例化重寫的CustomAnalyzer類傳入分詞器和大小寫轉(zhuǎn)扔傅,將大寫轉(zhuǎn)換成小寫

class lagouType(DocType):                                                   # 自定義一個類來繼承DocType類
    suggest = Completion(analyzer=ik_analyzer)
    # 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"                                                     # 設置索引名稱(相當于數(shù)據(jù)庫名稱)
        doc_type = 'biao'                                                   # 設置表名稱

if __name__ == "__main__":          # 判斷在本代碼文件執(zhí)行才執(zhí)行里面的方法倘屹,其他頁面調(diào)用的則不執(zhí)行里面的方法
    lagouType.init()                # 生成elasticsearch(搜索引擎)的索引银亲,表,字段等信息

# 使用方法說明:
# 在要要操作elasticsearch(搜索引擎)的頁面纽匙,導入此模塊
# lagou = lagouType()           #實例化類
# lagou.title = '值'            #要寫入字段=值
# lagou.description = '值'
# lagou.keywords = '值'
# lagou.url = '值'
# lagou.riqi = '值'
# lagou.save()                  #將數(shù)據(jù)寫入elasticsearch(搜索引擎)

2务蝠、搜索自動補全字段suggest寫入數(shù)據(jù)

搜索自動補全字段suggest接收的要搜索的字段分詞數(shù)據(jù),詳情見下面的自定義分詞函數(shù)

elasticsearch-dsl操作elasticsearch(搜索引擎)

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

from datetime import datetime
from elasticsearch_dsl import DocType, Date, Nested, Boolean, \
    analyzer, InnerObjectWrapper, Completion, Keyword, Text, Integer
from elasticsearch_dsl.connections import connections                       # 導入連接elasticsearch(搜索引擎)服務器方法
# 更多字段類型見第三百六十四節(jié)elasticsearch(搜索引擎)的mapping映射管理
from elasticsearch_dsl.analysis import CustomAnalyzer as _CustomAnalyzer    #導入CustomAnalyzer類

connections.create_connection(hosts=['127.0.0.1'])

class CustomAnalyzer(_CustomAnalyzer):                                      # 自定義CustomAnalyzer類烛缔,來重寫CustomAnalyzer類
    def get_analysis_definition(self):
        return {}

ik_analyzer = CustomAnalyzer("ik_max_word", filter=["lowercase"])           # 實例化重寫的CustomAnalyzer類傳入分詞器和大小寫轉(zhuǎn)馏段,將大寫轉(zhuǎn)換成小寫

class lagouType(DocType):                                                   # 自定義一個類來繼承DocType類
    suggest = Completion(analyzer=ik_analyzer)
    # 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"                                                     # 設置索引名稱(相當于數(shù)據(jù)庫名稱)
        doc_type = 'biao'                                                   # 設置表名稱

def gen_suggest(index, info_tuple):
    # 根據(jù)字符串生成搜索建議數(shù)組
    """
    此函數(shù)主要用于,連接elasticsearch(搜索引擎),使用ik_max_word分詞器巫员,將傳入的字符串進行分詞庶香,返回分詞后的結(jié)果
    此函數(shù)需要兩個參數(shù):
    第一個參數(shù):要調(diào)用elasticsearch(搜索引擎)分詞的索引index,一般是(索引操作類._doc_type.index)
    第二個參數(shù):是一個元組简识,元祖的元素也是元組赶掖,元素元祖里有兩個值一個是要分詞的字符串,第二個是分詞的權(quán)重七扰,多個分詞傳多個元祖如下
    書寫格式:
    gen_suggest(lagouType._doc_type.index, (('字符串', 10),('字符串', 8)))
    """
    es = connections.create_connection(lagouType._doc_type.using)       # 連接elasticsearch(搜索引擎)奢赂,使用操作搜索引擎的類下面的_doc_type.using連接
    used_words = set()
    suggests = []
    for text, weight in info_tuple:
        if text:
            # 調(diào)用es的analyze接口分析字符串,
            words = es.indices.analyze(index=index, analyzer="ik_max_word", params={'filter':["lowercase"]}, body=text)
            anylyzed_words = set([r["token"] for r in words["tokens"] if len(r["token"])>1])
            new_words = anylyzed_words - used_words
        else:
            new_words = set()

        if new_words:
            suggests.append({"input":list(new_words), "weight":weight})

    # 返回分詞后的列表颈走,里面是字典膳灶,
    # 如:[{'input': ['錄音', '廣告'], 'weight': 10}, {'input': ['新能源', '汽車',], 'weight': 8}]
    return suggests

if __name__ == "__main__":          # 判斷在本代碼文件執(zhí)行才執(zhí)行里面的方法,其他頁面調(diào)用的則不執(zhí)行里面的方法
    lagouType.init()                # 生成elasticsearch(搜索引擎)的索引,表轧钓,字段等信息
# 使用方法說明:
# 在要要操作elasticsearch(搜索引擎)的頁面序厉,導入此模塊
# lagou = lagouType()           #實例化類
# lagou.title = '值'            #要寫入字段=值
# lagou.description = '值'
# lagou.keywords = '值'
# lagou.url = '值'
# lagou.riqi = '值'
# lagou.save()                  #將數(shù)據(jù)寫入elasticsearch(搜索引擎)

suggest字段寫入數(shù)據(jù)

# -*- 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,文件是專門用于,接收爬蟲獲取到的數(shù)據(jù)信息的毕箍,就相當于是容器文件

import scrapy
from scrapy.loader.processors import MapCompose, TakeFirst
from scrapy.loader import ItemLoader                            # 導入ItemLoader類也就加載items容器類填充數(shù)據(jù)
from adc.models.elasticsearch_orm import lagouType, gen_suggest  # 導入elasticsearch操作模塊

class LagouItemLoader(ItemLoader):                  # 自定義Loader繼承ItemLoader類弛房,在爬蟲頁面調(diào)用這個類填充數(shù)據(jù)到Item類
    default_output_processor = TakeFirst()          # 默認利用ItemLoader類,加載items容器類填充數(shù)據(jù)霉晕,是列表類型庭再,可以通過TakeFirst()方法,獲取到列表里的內(nèi)容

def tianjia(value):                                 # 自定義數(shù)據(jù)預處理函數(shù)
    return value                                    # 將處理后的數(shù)據(jù)返給Item

class LagouItem(scrapy.Item):                       # 設置爬蟲獲取到的信息容器類
    title = scrapy.Field(                           # 接收爬蟲獲取到的title信息
        input_processor=MapCompose(tianjia),        # 將數(shù)據(jù)預處理函數(shù)名稱傳入MapCompose方法里處理牺堰,數(shù)據(jù)預處理函數(shù)的形式參數(shù)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']
        # 將title和keywords數(shù)據(jù)傳入分詞函數(shù)拄轻,進行分詞組合后返回寫入搜索建議字段suggest
        lagou.suggest = gen_suggest(lagouType._doc_type.index, ((lagou.title, 10),(lagou.keywords, 8)))
        lagou.save()                                # 將數(shù)據(jù)寫入elasticsearch(搜索引擎對象)
        return

寫入elasticsearch(搜索引擎)后的情況

{
    "_index": "lagou",
    "_type": "biao",
    "_id": "AV5MDu0NXJs9MkF5tFxW",
    "_version": 1,
    "_score": 1,
    "_source": {
        "title": "LED光催化滅蚊燈廣告錄音_廣告錄音網(wǎng)-火紅廣告錄音_叫賣錄音下載_語音廣告制作",
        "keywords": "各類小商品,廣告錄音,叫賣錄音,火紅廣告錄音",
        "url": "http://www.luyin.org/post/2486.html",
        "suggest": [
            {
                "input": [
                    "廣告"
                    ,
                    "火紅"
                    ,
                    "制作"
                    ,
                    "叫賣"
                    ,
                    "滅蚊燈"
                    ,
                    "語音"
                    ,
                    "下載"
                    ,
                    "led"
                    ,
                    "錄音"
                    ,
                    "滅蚊"
                    ,
                    "光催化"
                    ,
                    "催化"
                ],
                "weight": 10
            }
            ,
            {
                "input": [
                    "小商品"
                    ,
                    "廣告"
                    ,
                    "各類"
                    ,
                    "火紅"
                    ,
                    "叫賣"
                    ,
                    "商品"
                    ,
                    "小商"
                    ,
                    "錄音"
                ],
                "weight": 8
            }
        ],
        "riqi": "2017-09-04T16:43:20",
        "description": "LED光催化滅蚊燈廣告錄音 是廣告錄音網(wǎng)-火紅廣告錄音中一篇關(guān)于 各類小商品 的文章,歡迎您閱讀和評論,專業(yè)叫賣錄音-廣告錄音-語音廣告制作"
    }
}
image

用Django實現(xiàn)搜索的自動補全功能說明

1.將搜索框綁定一個事件伟葫,每輸入一個字觸發(fā)這個事件恨搓,獲取到輸入框里的內(nèi)容,用ajax將輸入的詞請求到Django的邏輯處理函數(shù)筏养。

2.在邏輯處理函數(shù)里斧抱,將請求詞用elasticsearch(搜索引擎)的fuzzy模糊查詢,查詢suggest字段里存在請求詞的數(shù)據(jù)渐溶,將查詢到的數(shù)據(jù)添加到自動補全

html代碼:

<!DOCTYPE html >
<html xmlns="http://www.w3.org/1999/xhtml">
{#引入靜態(tài)文件路徑#}
{% load staticfiles %}
<head>
<meta http-equiv="X-UA-Compatible" content="IE=emulateIE7" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>lcv-search 搜索引擎</title>
<link href="{% static 'css/style.css'%}" rel="stylesheet" type="text/css" />
<link href="{% static 'css/index.css'%}" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="container">
    <div id="bd">
        <div id="main">
            <h1 class="title">
                <div class="logo large"></div>
            </h1>
            <div class="nav ue-clear">
                <ul class="searchList">
                    <li class="searchItem current" data-type="article">文章</li>
                    <li class="searchItem" data-type="question">問答</li>
                    <li class="searchItem" data-type="job">職位</li>
                </ul>
            </div>
            <div class="inputArea">
                {% csrf_token %}
                <input type="text" class="searchInput" />
                <input type="button" class="searchButton" onclick="add_search()" />
                <ul class="dataList">
                    <li>如何學好設計</li>
                    <li>界面設計</li>
                    <li>UI設計培訓要多少錢</li>
                    <li>設計師學習</li>
                    <li>哪里有好的網(wǎng)站</li>
                </ul>
            </div>

            <div class="historyArea">
                <p class="history">
                    <label>熱門搜索:</label>

                </p>
                <p class="history mysearch">
                    <label>我的搜索:</label>
                    <span class="all-search">
                        <a href="javascript:;">專注界面設計網(wǎng)站</a>
                        <a href="javascript:;">用戶體驗</a>
                        <a href="javascript:;">互聯(lián)網(wǎng)</a>
                        <a href="javascript:;">資費套餐</a>
                    </span>

                </p>
            </div>
        </div><!-- End of main -->
    </div><!--End of bd-->

    <div class="foot">
        <div class="wrap">
            <div class="copyright">Copyright &copy;uimaker.com 版權(quán)所有  E-mail:admin@uimaker.com</div>
        </div>
    </div>
</div>
</body>
<script type="text/javascript" src="{% static 'js/jquery.js'%}"></script>
<script type="text/javascript" src="{% static 'js/global.js'%}"></script>
<script type="text/javascript">
    var suggest_url = "/suggest/"
    var search_url = "/search/"

    $('.searchList').on('click', '.searchItem', function(){
        $('.searchList .searchItem').removeClass('current');
        $(this).addClass('current');
    });

    function removeByValue(arr, val) {
      for(var i=0; i<arr.length; i++) {
        if(arr[i] == val) {
          arr.splice(i, 1);
          break;
        }
      }
    }

    // 搜索建議
    $(function(){
        $('.searchInput').bind(' input propertychange ',function(){
            var searchText = $(this).val();
            var tmpHtml = ""
            $.ajax({
                cache: false,
                type: 'get',
                dataType:'json',
                url:suggest_url+"?s="+searchText+"&s_type="+$(".searchItem.current").attr('data-type'),
                async: true,
                success: function(data) {
                    for (var i=0;i<data.length;i++){
                        tmpHtml += '<li><a href="'+search_url+'?q='+data[i]+'">'+data[i]+'</a></li>'
                    }
                    $(".dataList").html("")
                    $(".dataList").append(tmpHtml);
                    if (data.length == 0){
                        $('.dataList').hide()
                    }else {
                        $('.dataList').show()
                    }
                }
            });
        } );
    })

    hideElement($('.dataList'), $('.searchInput'));

</script>
<script>
    var searchArr;
    //定義一個search的辉浦,判斷瀏覽器有無數(shù)據(jù)存儲(搜索歷史)
    if(localStorage.search){
    //如果有,轉(zhuǎn)換成 數(shù)組的形式存放到searchArr的數(shù)組里(localStorage以字符串的形式存儲茎辐,所以要把它轉(zhuǎn)換成數(shù)組的形式)
        searchArr= localStorage.search.split(",")
    }else{
    //如果沒有宪郊,則定義searchArr為一個空的數(shù)組
        searchArr = [];
    }
    //把存儲的數(shù)據(jù)顯示出來作為搜索歷史
    MapSearchArr();

    function add_search(){
        var val = $(".searchInput").val();
        if (val.length>=2){
            //點擊搜索按鈕時,去重
            KillRepeat(val);
            //去重后把數(shù)組存儲到瀏覽器localStorage
            localStorage.search = searchArr;
            //然后再把搜索內(nèi)容顯示出來
            MapSearchArr();
        }

        window.location.href=search_url+'?q='+val+"&s_type="+$(".searchItem.current").attr('data-type')

    }

    function MapSearchArr(){
        var tmpHtml = "";
        var arrLen = 0
        if (searchArr.length >= 5){
            arrLen = 5
        }else {
            arrLen = searchArr.length
        }
        for (var i=0;i<arrLen;i++){
            tmpHtml += '<a href="'+search_url+'?q='+searchArr[i]+'">'+searchArr[i]+'</a>'
        }
        $(".mysearch .all-search").html(tmpHtml);
    }
    //去重
    function KillRepeat(val){
        var kill = 0;
        for (var i=0;i<searchArr.length;i++){
            if(val===searchArr[i]){
                kill ++;
            }
        }
        if(kill<1){
            searchArr.unshift(val);
        }else {
            removeByValue(searchArr, val)
            searchArr.unshift(val)
        }
    }

</script>
</html>

Django路由映射

"""pachong URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.10/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^/pre>, views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^/pre>, Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from app1 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^/pre>, views.indexluoji),
    url(r'^index/', views.indexluoji),
    url(r'^suggest//pre>, views.suggestluoji,name="suggest"),     # 搜索字段補全請求

]

Django靜態(tài)文件配置

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
#配置靜態(tài)文件前綴
STATIC_URL = '/static/'
#配置靜態(tài)文件目錄
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

備注:搜索自動補全fuzzy查詢

#搜索自動補全fuzzy查詢
POST lagou/biao/_search?pretty
{
  "suggest":{          #字段名稱
    "my_suggest":{       #自定義變量
      "text":"廣告",      #搜索詞
      "completion":{
        "field":"suggest",  #搜索字段
        "fuzzy":{
          "fuzziness":1    #編輯距離
        }
      }
    }
  },
  "_source":"title"
}

Django邏輯處理文件

from django.shortcuts import render

# Create your views here.
from django.shortcuts import render,HttpResponse
from django.views.generic.base import View
from app1.models import lagouType   #導入操作elasticsearch(搜索引擎)類
import json

def indexluoji(request):
    print(request.method)  # 獲取用戶請求的路徑
    return render(request, 'index.html')

def suggestluoji(request):                                      # 搜索自動補全邏輯處理
    key_words = request.GET.get('s', '')                        # 獲取到請求詞
    re_datas = []
    if key_words:
        s = lagouType.search()                                  # 實例化elasticsearch(搜索引擎)類的search查詢
        s = s.suggest('my_suggest', key_words, completion={
            "field": "suggest", "fuzzy": {
                "fuzziness": 2
            },
            "size": 5
        })
        suggestions = s.execute_suggest()
        for match in suggestions.my_suggest[0].options:
            source = match._source
            re_datas.append(source["title"])
    return HttpResponse(json.dumps(re_datas), content_type="application/json")
image

最終完成

image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拖陆,一起剝皮案震驚了整個濱河市弛槐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌依啰,老刑警劉巖乎串,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異速警,居然都是意外死亡叹誉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門闷旧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來长豁,“玉大人,你說我怎么就攤上這事鸠匀。” “怎么了逾柿?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵缀棍,是天一觀的道長宅此。 經(jīng)常有香客問我,道長爬范,這世上最難降的妖魔是什么父腕? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮青瀑,結(jié)果婚禮上璧亮,老公的妹妹穿的比我還像新娘。我一直安慰自己斥难,他們只是感情好枝嘶,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著哑诊,像睡著了一般群扶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上镀裤,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天竞阐,我揣著相機與錄音,去河邊找鬼暑劝。 笑死骆莹,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的担猛。 我是一名探鬼主播幕垦,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼毁习!你這毒婦竟也來了智嚷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤纺且,失蹤者是張志新(化名)和其女友劉穎盏道,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體载碌,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡猜嘱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了嫁艇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片朗伶。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖步咪,靈堂內(nèi)的尸體忽然破棺而出论皆,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布点晴,位于F島的核電站感凤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏粒督。R本人自食惡果不足惜陪竿,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望屠橄。 院中可真熱鬧族跛,春花似錦、人聲如沸锐墙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贮匕。三九已至姐仅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間刻盐,已是汗流浹背掏膏。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留敦锌,地道東北人馒疹。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像乙墙,于是被迫代替她去往敵國和親颖变。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容