Django Haystack 全文檢索與關(guān)鍵詞高亮的實(shí)現(xiàn)
作者:HelloGitHub-追夢(mèng)人物
文中所涉及的示例代碼,已同步更新到HelloGitHub-Team 倉(cāng)庫(kù)
博客提供 RSS 訂閱應(yīng)該是標(biāo)配,這樣讀者就可以通過(guò)一些聚合閱讀工具訂閱你的博客,時(shí)時(shí)查看是否有文章更新,而不必每次都跳轉(zhuǎn)到博客上來(lái)查看?,F(xiàn)在我們就來(lái)為博客添加 RSS 訂閱功能。
在此之前我們使用了 Django 內(nèi)置的一些方法實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的搜索功能。但這個(gè)搜索功能實(shí)在過(guò)于簡(jiǎn)單,沒(méi)有多大的實(shí)用性。對(duì)于一個(gè)搜索引擎來(lái)說(shuō),至少應(yīng)該能夠根據(jù)用戶(hù)的搜索關(guān)鍵詞對(duì)搜索結(jié)果進(jìn)行排序以及高亮關(guān)鍵字。現(xiàn)在我們就來(lái)使用 django-haystack 實(shí)現(xiàn)這些特性。
Django Haystack 簡(jiǎn)介
django-haystack 是一個(gè)專(zhuān)門(mén)提供搜索功能的 django 第三方應(yīng)用,它支持 Solr、Elasticsearch、Whoosh、Xapian 等多種搜索引擎,上一版本的教程中我們使用 Whoosh 加 jieba 中文分詞的方案,原因是為了簡(jiǎn)單,無(wú)需安裝外部服務(wù)。但現(xiàn)在有了 docker,安裝一個(gè)外部服務(wù)就是輕而易舉的事情,所以這次我們采用更為強(qiáng)大的 elasticsearch 作為我們博客的搜索引擎,同時(shí)使用 elasticsearch 的中文分詞插件 ik,來(lái)提升中文搜索的效果。
安裝必要依賴(lài)
安裝 django-haystack
django-haystack 安裝非常簡(jiǎn)單,只需要執(zhí)行 pipenv install django-haystack 即可。需要注意的是,目前 elasticsearch 有 2 系列和 5 系列兩大版本,本來(lái)新項(xiàng)目的原則是盡可能采用新版本,但目前 django-haystack 在 pypi 上發(fā)布的穩(wěn)定版只支持 elasticsearch2,master 分支下支持 elasticsearch5,因此處于穩(wěn)定性考慮,我們暫時(shí)使用 elasticsearch2,后續(xù)如果 django-haystack 發(fā)布了支持 elasticsearch5 的pypi版本,我們會(huì)升級(jí)到 elasticsearch5,有了 docker,升級(jí)就是輕而易舉的事情。
由于使用 elasticsearch 服務(wù),haystack 連接 elasticsearch 需要 python 版本的 SDK 支持,因此還需要安裝 elasticsearch python SDK,這里我們不要直接使用 pipenv 安裝,而是手動(dòng)編輯 Pipfile 文件,指定 SDK 的版本,否則 pipenv 默認(rèn)會(huì)安裝最新版。打開(kāi) Pipfile 文件,將依賴(lài)手動(dòng)添加到 packages 板塊下:
[packages] django = "~=2.2" elasticsearch = ">=2,<3"
安裝 elasticsearch 2
接下來(lái)就是構(gòu)建一個(gè)新的容器來(lái)運(yùn)行 elasticsearch 服務(wù),因此首先需要來(lái)編排容器鏡像,回顧一下容器鏡像的目錄結(jié)構(gòu):
compose\ local\ production\ django\ nginx\
由于 elasticsearch 在線(xiàn)上環(huán)境和本地測(cè)試都要使用,我們把鏡像編排在 production 目錄下,新建一個(gè) elasticsearch 目錄,用來(lái)存放和 elasticsearch 相關(guān)的內(nèi)容。Dockfile 內(nèi)容如下:
FROM elasticsearch:2.4.6-alpine COPY ./compose/production/elasticsearch/elasticsearch-analysis-ik-1.10.6.zip /usr/share/elasticsearch/plugins/ RUN cd /usr/share/elasticsearch/plugins/ && mkdir ik && unzip elasticsearch-analysis-ik-1.10.6.zip -d ik/ RUN rm /usr/share/elasticsearch/plugins/elasticsearch-analysis-ik-1.10.6.zip USER root COPY ./compose/production/elasticsearch/elasticsearch.yml /usr/share/elasticsearch/config/ RUN chown elasticsearch:elasticsearch /usr/share/elasticsearch/config/elasticsearch.yml USER elasticsearch
這個(gè)鏡像從 elasticsearch 的官方基礎(chǔ)鏡像 2.4.6 版本進(jìn)行構(gòu)建,接著我們把 ik 分詞插件復(fù)制到 elasticsearch 安裝插件的目錄下,然后解壓?jiǎn)⒂谩?/p>
接著我們又把 elasticsearch.yml 配置文件復(fù)制到容器內(nèi),然后切換用戶(hù)為 elasticsearch,因?yàn)槲覀儗⒁?elasticsearch 用戶(hù)和組運(yùn)行 elasticsearch 服務(wù)。
elasticsearch.yml 配置文件內(nèi)容很簡(jiǎn)單:
bootstrap.memory_lock: true network.host: 0.0.0.0
其中 bootstrap.memory_lock 這個(gè)參數(shù)是為了提高 elasticsearch 的效率(涉及到 JVM 相關(guān)的優(yōu)化,不做過(guò)多介紹)。network.host 指定服務(wù)啟動(dòng)的地址。
接著修改 docker compose 文件,我們先在本地啟動(dòng),因此修改 local.yml 文件,加入 elasticsearch 服務(wù):
version: '3' volumes: database_local: esdata_local: services: hellodjango_blog_tutorial_local: # 其它配置不變... depends_on: - elasticsearch_local elasticsearch_local: build: context: . dockerfile: ./compose/production/elasticsearch/Dockerfile image: elasticsearch_local container_name: elasticsearch_local volumes: - esdata_local:/usr/share/elasticsearch/data ports: - "9200:9200" environment: - "ES_JAVA_OPTS=-Xms512m -Xmx512m" ulimits: memlock: soft: -1 hard: -1 nproc: 65536 nofile: soft: 65536 hard: 65536
主要是加入了 elasticsearch 服務(wù),其中 environment 和 ulimits 的參數(shù)與 elasticksearch 服務(wù)調(diào)優(yōu)有關(guān),對(duì)于簡(jiǎn)單的博客搜索來(lái)說(shuō),調(diào)優(yōu)的意義不是很大,因此這里不做過(guò)多介紹,感興趣的可以參考 elasticksearch 的官方文檔。
配置 Haystack
安裝好 django haystack 后需要在項(xiàng)目的 settings.py 做一些簡(jiǎn)單的配置。
首先是把 django haystack 加入到 INSTALLED_APPS 設(shè)置里:
blogproject/settings.py
INSTALLED_APPS = [ 'django.contrib.admin', # 其它 app... 'haystack', 'blog', 'comments', ]
然后加入如下配置項(xiàng):
blogproject/common.py
# 搜索設(shè)置 HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'haystack.elasticsearch2_backend.Elasticsearch2SearchEngine', 'URL': '', 'INDEX_NAME': 'hellodjango_blog_tutorial', }, } HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10 HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
HAYSTACK_CONNECTIONS 的 ENGINE 指定了 django haystack 使用的搜索引擎,這里我們使用了 haystack 默認(rèn)的 Elasticsearch2 搜索引擎。PATH 指定了索引文件需要存放的位置,我們?cè)O(shè)置為項(xiàng)目根目錄 BASE_DIR 下的 whoosh_index 文件夾(在建立索引是會(huì)自動(dòng)創(chuàng)建)。
HAYSTACK_SEARCH_RESULTS_PER_PAGE 指定如何對(duì)搜索結(jié)果分頁(yè),這里設(shè)置為每 10 項(xiàng)結(jié)果為一頁(yè)。
HAYSTACK_SIGNAL_PROCESSOR 指定什么時(shí)候更新索引,這里我們使用 haystack.signals.RealtimeSignalProcessor,作用是每當(dāng)有文章更新時(shí)就更新索引。由于博客文章更新不會(huì)太頻繁,因此實(shí)時(shí)更新沒(méi)有問(wèn)題。
由于開(kāi)發(fā)環(huán)境和線(xiàn)上環(huán)境,elasticsearch 服務(wù)的 url 地址是不同的,所以我們?cè)?common 的配置中沒(méi)有指定 url,在 local.py 設(shè)置文件指定之:
HAYSTACK_CONNECTIONS['default']['URL'] = 'http://elasticsearch_local:9200/'
處理數(shù)據(jù)
接下來(lái)就要告訴 django haystack 使用哪些數(shù)據(jù)建立索引以及如何存放索引。如果要對(duì) blog 應(yīng)用下的數(shù)據(jù)進(jìn)行全文檢索,做法是在 blog 應(yīng)用下建立一個(gè) search_indexes.py 文件,寫(xiě)上如下代碼:
blog/search_indexes.py
from haystack import indexes from .models import Post class PostIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) def get_model(self): return Post def index_queryset(self, using=None): return self.get_model().objects.all()
這是 django haystack 的規(guī)定。要相對(duì)某個(gè) app 下的數(shù)據(jù)進(jìn)行全文檢索,就要在該 app 下創(chuàng)建一個(gè) search_indexes.py 文件,然后創(chuàng)建一個(gè) XXIndex 類(lèi)(XX 為含有被檢索數(shù)據(jù)的模型,如這里的 Post),并且繼承 SearchIndex 和 Indexable。
為什么要?jiǎng)?chuàng)建索引?索引就像是一本書(shū)的目錄,可以為讀者提供更快速的導(dǎo)航與查找。在這里也是同樣的道理,當(dāng)數(shù)據(jù)量非常大的時(shí)候,若要從這些數(shù)據(jù)里找出所有的滿(mǎn)足搜索條件的幾乎是不太可能的,將會(huì)給服務(wù)器帶來(lái)極大的負(fù)擔(dān)。所以我們需要為指定的數(shù)據(jù)添加一個(gè)索引(目錄),在這里是為 Post 創(chuàng)建一個(gè)索引,索引的實(shí)現(xiàn)細(xì)節(jié)是我們不需要關(guān)心的,我們只關(guān)心為哪些字段創(chuàng)建索引,如何指定。
每個(gè)索引里面必須有且只能有一個(gè)字段為 document=True,這代表 django haystack 和搜索引擎將使用此字段的內(nèi)容作為索引進(jìn)行檢索(primary field)。注意,如果使用一個(gè)字段設(shè)置了document=True,則一般約定此字段名為text,這是在 SearchIndex 類(lèi)里面一貫的命名,以防止后臺(tái)混亂,當(dāng)然名字你也可以隨便改,不過(guò)不建議改。
并且,haystack 提供了 use_template=True 在 text 字段中,這樣就允許我們使用數(shù)據(jù)模板去建立搜索引擎索引的文件,說(shuō)得通俗點(diǎn)就是索引里面需要存放一些什么東西,例如 Post 的 title 字段,這樣我們可以通過(guò) title 內(nèi)容來(lái)檢索 Post 數(shù)據(jù)了。舉個(gè)例子,假如你搜索 Python ,那么就可以檢索出 title 中含有 Python 的Post了,怎么樣是不是很簡(jiǎn)單?數(shù)據(jù)模板的路徑為 templates/search/indexes/youapp/<model_name>_text.txt(例如 templates/search/indexes/blog/post_text.txt),其內(nèi)容為:
templates/search/indexes/blog/post_text.txt {{ object.title }} {{ object.body }}
這個(gè)數(shù)據(jù)模板的作用是對(duì) Post.title、Post.body 這兩個(gè)字段建立索引,當(dāng)檢索的時(shí)候會(huì)對(duì)這兩個(gè)字段做全文檢索匹配,然后將匹配的結(jié)果排序后作為搜索結(jié)果返回。
配置 URL
接下來(lái)就是配置 URL,搜索的視圖函數(shù)和 URL 模式 django haystack 都已經(jīng)幫我們寫(xiě)好了,只需要項(xiàng)目的 urls.py 中包含它:
blogproject/urls.py
urlpatterns = [ # 其它... path('search/', include('haystack.urls')), ]
另外在此之前我們也為自己寫(xiě)的搜索視圖配置了 URL,把那個(gè) URL 刪掉,以免沖突:
blog/urls.py
# path('search/', views.search, name='search'),
修改搜索表單
修改一下搜索表單,讓它提交數(shù)據(jù)到 django haystack 搜索視圖對(duì)應(yīng)的 URL:
<form role="search" method="get" id="searchform" action="{% url 'haystack_search' %}"> <input type="search" name="q" placeholder="搜索" required> <button type="submit"><span class="ion-ios-search-strong"></span></button> </form>
主要是把表單的 action 屬性改為 {% url 'haystack_search' %}
創(chuàng)建搜索結(jié)果頁(yè)面
haystack_search 視圖函數(shù)會(huì)將搜索結(jié)果傳遞給模板 search/search.html,因此創(chuàng)建這個(gè)模板文件,對(duì)搜索結(jié)果進(jìn)行渲染:
templates/search/search.html
{% extends 'base.html' %} {% load highlight %} {% block main %} {% if query %} {% for result in page.object_list %} <article class="post post-{{ result.object.pk }}"> <header class="entry-header"> <h1 class="entry-title"> <a href="{{ result.object.get_absolute_url }}" rel="external nofollow" rel="external nofollow" rel="external nofollow" >{% highlight result.object.title with query %}</a> </h1> <div class="entry-meta"> <span class="post-category"> <a href="{% url 'blog:category' result.object.category.pk %}" rel="external nofollow" > {{ result.object.category.name }}</a></span> <span class="post-date"><a href="#" rel="external nofollow" rel="external nofollow" > <time class="entry-date" datetime="{{ result.object.created_time }}"> {{ result.object.created_time }}</time></a></span> <span class="post-author"><a href="#" rel="external nofollow" rel="external nofollow" >{{ result.object.author }}</a></span> <span class="comments-link"> <a href="{{ result.object.get_absolute_url }}#comment-area" rel="external nofollow" > {{ result.object.comment_set.count }} 評(píng)論</a></span> <span class="views-count"><a href="{{ result.object.get_absolute_url }}" rel="external nofollow" rel="external nofollow" rel="external nofollow" >{{ result.object.views }} 閱讀</a></span> </div> </header> <div class="entry-content clearfix"> <p>{% highlight result.object.body with query %}</p> <div class="read-more cl-effect-14"> <a href="{{ result.object.get_absolute_url }}" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="more-link">繼續(xù)閱讀 <span class="meta-nav">→</span></a> </div> </div> </article> {% empty %} <div class="no-post">沒(méi)有搜索到你想要的結(jié)果!</div> {% endfor %} {% if page.has_previous or page.has_next %} <div class="text-center" style="margin-top: 30px"> {% if page.has_previous %} <a href="?q={{ query }}&page={{ page.previous_page_number }}" rel="external nofollow" >{% endif %}« Previous {% if page.has_previous %}</a>{% endif %} <span style="margin: 0 10px">|</span> {% if page.has_next %}<a href="?q={{ query }}&page={{ page.next_page_number }}" rel="external nofollow" >{% endif %}Next »{% if page.has_next %}</a>{% endif %} </div> {% endif %} {% else %} 請(qǐng)輸入搜索關(guān)鍵詞,例如 django {% endif %} {% endblock main %}
這個(gè)模板基本和 blog/index.html 一樣,只是由于 haystack 對(duì)搜索結(jié)果做了分頁(yè),傳給模板的變量是一個(gè) page 對(duì)象,所以我們從 page 中取出這一頁(yè)對(duì)應(yīng)的搜索結(jié)果,然后對(duì)其循環(huán)顯示,即 {% for result in page.object_list %}。另外要取得 Post(文章)以顯示文章的數(shù)據(jù)如標(biāo)題、正文,需要從 result 的 object 屬性中獲取。query 變量的值即為用戶(hù)搜索的關(guān)鍵詞。
高亮關(guān)鍵詞
注意到百度的搜索結(jié)果頁(yè)面,含有用戶(hù)搜索的關(guān)鍵詞的地方都是被標(biāo)紅的,在 django haystack 中實(shí)現(xiàn)這個(gè)效果也非常簡(jiǎn)單,只需要使用 {% highlight %} 模板標(biāo)簽即可,其用法如下:
# 使用默認(rèn)值 {% highlight result.summary with query %} # 這里我們?yōu)?{{ result.summary }} 里所有的 {{ query }} 指定了一個(gè)<div></div>標(biāo)簽,并且將class設(shè)置為highlight_me_please,這樣就可以自己通過(guò)CSS為{{ query }}添加高亮效果了,怎么樣,是不是很科學(xué)呢 {% highlight result.summary with query html_tag "div" css_class "highlight_me_please" %} # 可以 max_length 限制最終{{ result.summary }} 被高亮處理后的長(zhǎng)度 {% highlight result.summary with query max_length 40 %}
在博客文章搜索頁(yè)中我們對(duì) title 和 body 做了高亮處理:{% highlight result.object.title with query %},{% highlight result.object.body with query %}。高亮處理的原理其實(shí)就是給文本中的關(guān)鍵字包上一個(gè) span 標(biāo)簽并且為其添加 highlighted 樣式(當(dāng)然你也可以修改這個(gè)默認(rèn)行為,具體參見(jiàn)上邊給出的用法)。因此我們還要給 highlighted 類(lèi)指定樣式,在 base.html 中添加即可:
base.html
<head> <title>Black & White</title> ... <style> /* 搜索關(guān)鍵詞高亮 */ span.highlighted { color: red; } </style> ... </head>
建立索引文件
最后一步就是建立索引文件了,運(yùn)行命令 :
$ docker exec -it hellodjango_blog_tutorial_local python manage.py rebuild_index
就可以建立索引文件了。一切就緒后,就可以嘗試搜索了。但是體驗(yàn)下來(lái)會(huì)發(fā)現(xiàn)搜索的結(jié)果并不是很友好,很多關(guān)鍵詞文章中命名存在但搜索結(jié)果中卻沒(méi)有顯示,原因是 haystack 專(zhuān)門(mén)為英文搜索設(shè)計(jì),如果使用其默認(rèn)的搜索引擎分詞器,中文搜索的結(jié)果就不是很理想,接下來(lái)我們來(lái)將它默認(rèn)的分詞器設(shè)置為中文分詞器。
修改搜索引擎為中文分詞
還記得文章開(kāi)頭編排 elasticsearch 的 Docker 鏡像時(shí),我們將一個(gè) elasticsearch 的中文分詞插件復(fù)制到了 elasticsearch 的插件目錄,接下來(lái)要做的,就是讓 haystack 在創(chuàng)建索引時(shí),使用指定的插件來(lái)對(duì)進(jìn)行分詞并創(chuàng)建索引,具體做法是,首先在 blog 應(yīng)用下創(chuàng)建一個(gè) elasticsearch2_ik_backend.py,代碼如下:
from haystack.backends.elasticsearch2_backend import Elasticsearch2SearchBackend, Elasticsearch2SearchEngine DEFAULT_FIELD_MAPPING = {'type': 'string', "analyzer": "ik_max_word", "search_analyzer": "ik_smart"} class Elasticsearch2IkSearchBackend(Elasticsearch2SearchBackend): def __init__(self, *args, **kwargs): self.DEFAULT_SETTINGS['settings']['analysis']['analyzer']['ik_analyzer'] = { "type": "custom", "tokenizer": "ik_max_word", } super(Elasticsearch2IkSearchBackend, self).__init__(*args, **kwargs) class Elasticsearch2IkSearchEngine(Elasticsearch2SearchEngine): backend = Elasticsearch2IkSearchBackend
這些代碼的作用是,繼承 haystack 默認(rèn)的 Elasticsearch2SearchBackend 和 Elasticsearch2SearchEngine,覆蓋掉它的一些默認(rèn)行為,這里主要就是讓 haystack 在創(chuàng)建索引時(shí),使用指定的 ik 分詞器。
由于自定義了搜索引擎,因此在配置文件中將原來(lái)指定的 Elasticsearch2SearchEngine 替換為自定義的 Engine:
# 搜索設(shè)置 HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'blog.elasticsearch2_ik_backend.Elasticsearch2IkSearchEngine', 'URL': '', 'INDEX_NAME': 'hellodjango_blog_tutorial', }, } HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10 HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
由于修改了索引創(chuàng)建方式,因此需要重建一下索引:python manage.py rebuild_index。然后就可以查看搜索結(jié)果了,中文搜索體驗(yàn)是不是好了很多?
防止標(biāo)題被截?cái)?/strong>
haystack 在展示搜索結(jié)果時(shí),默認(rèn)行為是將第一個(gè)出現(xiàn)的關(guān)鍵詞前的內(nèi)容截?cái)?,被截掉的部分用省略?hào)代替。對(duì)于正文來(lái)說(shuō),因?yàn)閮?nèi)容較多,截?cái)嗍呛侠淼?,但是?duì)于標(biāo)題這種較短的內(nèi)容來(lái)說(shuō),截?cái)嗑蜎](méi)有必要了。同樣的,我們通過(guò)繼承的方式,替換掉 haystack 的默認(rèn)行為。我們?cè)?blog/utils.py 中繼承 HaystackHighlighter 這個(gè)用于高亮搜索關(guān)鍵詞的輔助類(lèi)。
from django.utils.html import strip_tags from haystack.utils import Highlighter as HaystackHighlighter class Highlighter(HaystackHighlighter): """ 自定義關(guān)鍵詞高亮器,不截?cái)噙^(guò)短的文本(例如文章標(biāo)題) """ def highlight(self, text_block): self.text_block = strip_tags(text_block) highlight_locations = self.find_highlightable_words() start_offset, end_offset = self.find_window(highlight_locations) if len(text_block) < self.max_length: start_offset = 0 return self.render_html(highlight_locations, start_offset, end_offset)
關(guān)鍵代碼是:if len(text_block) < self.max_length:,start_offset 是 haystack 根據(jù)關(guān)鍵詞算出來(lái)第一個(gè)關(guān)鍵詞在文本中出現(xiàn)的位置。max_length 指定了展示結(jié)果的最大長(zhǎng)度。我們?cè)诖a中做一個(gè)判斷,如果文本內(nèi)容 text_block 沒(méi)有超過(guò)允許的最大長(zhǎng)度,就將 start_offset 設(shè)為 0,這樣就從文本的第一個(gè)字符開(kāi)始展示,標(biāo)題這種短文本就不會(huì)被截?cái)嗔恕?/p>
然后設(shè)置,讓 haystack 在高亮文本時(shí),使用我們自定義的輔助類(lèi):
HAYSTACK_CUSTOM_HIGHLIGHTER = 'blog.utils.Highlighter'
在來(lái)看一下搜索效果吧!
線(xiàn)上發(fā)布
以上步驟都是在本地運(yùn)行調(diào)試的,elasticsearch 服務(wù)也是在本地的 Docker 容器中運(yùn)行,接下來(lái)在 production.yml 中加入 elasticsearch 服務(wù),就可以發(fā)布線(xiàn)上了,配置內(nèi)容和 local.yml 是一樣的,只是簡(jiǎn)單修改一下服務(wù)名和容器名等命名:
elasticsearch: build: context: . dockerfile: ./compose/production/elasticsearch/Dockerfile image: hellodjango_blog_tutorial_elasticsearch container_name: hellodjango_blog_tutorial_elasticsearch volumes: - esdata:/usr/share/elasticsearch/data ports: - "9200:9200" environment: - "ES_JAVA_OPTS=-Xms512m -Xmx512m" ulimits: memlock: soft: -1 hard: -1 nproc: 65536 nofile: soft: 65536 hard: 65536
別忘了修改 settings/production.py,修改線(xiàn)上環(huán)境 elasticsearch 服務(wù)的連接地址:
HAYSTACK_CONNECTIONS['default']['URL'] = 'http://hellodjango_blog_tutorial_elasticsearch:9200/'
這樣就可以直接發(fā)布線(xiàn)上了!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于Pandas缺失值inf與nan的處理實(shí)踐
這篇文章主要介紹了關(guān)于Pandas缺失值inf與nan的處理實(shí)踐,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06Django生成數(shù)據(jù)庫(kù)及添加用戶(hù)報(bào)錯(cuò)解決方案
這篇文章主要介紹了Django生成數(shù)據(jù)庫(kù)及添加用戶(hù)報(bào)錯(cuò)解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10Python實(shí)現(xiàn)將Excel轉(zhuǎn)換成為image的方法
今天小編就為大家分享一篇Python實(shí)現(xiàn)將Excel轉(zhuǎn)換成為image的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10如何使用Python處理HDF格式數(shù)據(jù)及可視化問(wèn)題
這篇文章主要介紹了如何使用Python處理HDF格式數(shù)據(jù)及可視化問(wèn)題,本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06python 不關(guān)閉控制臺(tái)的實(shí)現(xiàn)方法
在win32下,雙擊python程序會(huì)打開(kāi)dos窗口,但是執(zhí)行完畢后就會(huì)關(guān)閉,看不到輸出的結(jié)果2011-10-10Python中執(zhí)行MySQL結(jié)果限制和分頁(yè)查詢(xún)示例詳解
這篇文章主要為大家介紹了Python中執(zhí)行MySQL結(jié)果限制和分頁(yè)查詢(xún)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11詳解用 python-docx 創(chuàng)建浮動(dòng)圖片
這篇文章主要介紹了詳解用 python-docx 創(chuàng)建浮動(dòng)圖片,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01python如何生成隨機(jī)n位數(shù)字與字母組合(創(chuàng)建隨機(jī))
這篇文章主要介紹了python如何生成隨機(jī)n位數(shù)字與字母組合(創(chuàng)建隨機(jī)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08