<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[DBAREN个人站 - Aren's Blog - 粤ICP备18014360号-1]]></title><description><![CDATA[Aren's Blog]]></description><link>https://www.dbaren.com/</link><image><url>https://www.dbaren.com/favicon.png</url><title>DBAREN个人站 - Aren&apos;s Blog - 粤ICP备18014360号-1</title><link>https://www.dbaren.com/</link></image><generator>Ghost 3.36</generator><lastBuildDate>Sun, 02 Aug 2026 06:12:34 GMT</lastBuildDate><atom:link href="https://www.dbaren.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[基于Python的Xgboost实战代码]]></title><description><![CDATA[大数据机器学习，Python Xgboost使用方法与代码演示]]></description><link>https://www.dbaren.com/post/python-xgboost-how-to-use/</link><guid isPermaLink="false">61bf7278de98590001719771</guid><category><![CDATA[大数据]]></category><dc:creator><![CDATA[Aren]]></dc:creator><pubDate>Sun, 19 Dec 2021 18:02:57 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>参加了一下单位组织的大数据建模比赛，记录一下，当做个笔记</p>
<pre><code class="language-python">import pandas as pd
import numpy as np
from sklearn.model_selection import KFold
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from itertools import product as prod
</code></pre>
<p>封装工具函数</p>
<pre><code class="language-python"># 数据清洗函数
def data_filter(data):
	&quot;&quot;&quot;
    处理缺失值，挑选特征等等
    Input: 
        data: pd.Dataframe or np.array, 原始数据
    Return:
        filted_data: pd.Dataframe or np.array, 处理后的数据
    &quot;&quot;&quot;
    # 假设输入 Dataframe, 删除具有缺失值的数据样本
	# 数据清洗操作
	filted_data = data
	# filted_data[&quot;sample&quot;] = filted_data[&quot;sample&quot;].replace(np.nan, filted_data[&quot;sample&quot;].mean()) # 把NaN替换成均值

	filted_data = filted_data.dropna()  # 删除有缺少值的行
	return filted_data

# 字符串转数值枚举
def str_enum(data):
	filted_data = data
	# 字符串映射转数值枚举
	# 把品牌字段处理为枚举值
	a = filted_data[&quot;brnd_nam&quot;].drop_duplicates().reset_index()
	brand_dict = {}
	for i in a.index:
	    brand_dict[a[&quot;brnd_nam&quot;][i]] = i
	filted_data[&quot;brnd_nam&quot;] = filted_data[&quot;brnd_nam&quot;].map(brand_dict)
	filted_data[&quot;gdr_typ_nam&quot;].map({&quot;资料不详&quot;:0, &quot;男&quot;:1, &quot;女&quot;:2})
	filted_data[&quot;dou_ca_usr&quot;] = filted_data[&quot;dou_ca_usr&quot;].map({&quot;否&quot;:0, &quot;是&quot;:1})
	
	return filted_data

# K折获取训练数据、测试数据
def K_fold_train_test(X, y, random_seed=0):
    &quot;&quot;&quot;
    使用 K 折交叉验证获取多个训练集和测试集
    Input:
        X: np.array with shape(sample_num, feature_dim) 数据集所有样本的特征值
        y: np.array with shape(sample_num,) 数据集所有样本的对应标签
        random_seed: int 设置随机种子，决定每次随机采样是否产生相同的随机值
    Return:
        train_data: [tuple(X, y)] 返回一个 tuple 的列表，每一个 tuple 代表一个训练集
        test_data: [tuple(X, y)] 返回一个 tuple 的列表，每一个 tuple 代表一个测试集
    &quot;&quot;&quot;
    train_data = []
    test_data = []
    
    # sklearn.model_selection.RepeatedKFold 函数
    kf = KFold(n_splits=5, shuffle=True, random_state=random_seed)
    for train_index, test_index in kf.split(X):
        train_tup = (X[train_index], y[train_index])
        test_tup = (X[test_index], y[test_index])
        train_data.append(train_tup)
        test_data.append(test_tup)
    
    return train_data, test_data


&quot;&quot;&quot;
模型参数处理模块
Function to convert dictionary of lists to list of dictionaries of all combinations of listed variables. 
Example:
    list_of_param_dicts({'a': [1, 2], 'b': [3, 4]}) ---&gt; [{'a': 1, 'b': 3}, {'a': 1, 'b': 4}, {'a': 2, 'b': 3}, {'a': 2, 'b': 4}]
&quot;&quot;&quot;
def list_of_param_dicts(param_dict):
    &quot;&quot;&quot;
    Arguments:
        param_dict   -(dict) dictionary of parameters
    &quot;&quot;&quot;
    vals = list(prod(*[v for k, v in param_dict.items()]))
    keys = list(prod(*[[k]*len(v) for k, v in param_dict.items()]))
    return [dict([(k, v) for k, v in zip(key, val)]) for key, val in zip(keys, vals)]
</code></pre>
<pre><code class="language-python"># 训练集数据
df_train = pd.read_csv(&quot;train_set.csv&quot;)
# 测试集数据
df_test = pd.read_csv(&quot;test_set.csv&quot;)

# 训练数据删除指定的某几列
train_d=df_train.drop(labels=['usr_id',&quot;month&quot;,&quot;cust_typ_cd&quot;],axis=1)
train_d = str_enum(train_d)
train_d = data_filter(train_d)
train_d

# 测试数据删除指定的某几列
test_d = df_test.drop(labels=[&quot;month&quot;, &quot;cust_typ_cd&quot;],axis=1)
test_d = str_enum(test_d)
test_d = data_filter(test_d)
test_d
</code></pre>
<p>73分的方式调试模型：</p>
<pre><code class="language-python"># ================ Xgboost =====================
import xgboost as xgb
import random                              

train_data = train_d.values
train_features = train_data[:, 1:]                       # 训练数据特征
train_labels = train_data[:, 0]                          # 训练数据标签

data_length = len(train_data)
random.seed(2)                                            # 设置随机数，改变不同的种子会有不同的随机结果
sample_idx = list(range(len(train_data)))
random.shuffle(sample_idx)
split_idx = int(0.7*data_length)
train_X = train_features[sample_idx[:split_idx]]
train_y = train_labels[sample_idx[:split_idx]]
test_X = train_features[sample_idx[split_idx:]]
test_y = train_labels[sample_idx[split_idx:]]
train_y = train_y.astype('int')
test_y = test_y.astype('int')

# 数据归一化
std = StandardScaler()
train_X = std.fit_transform(train_X)
test_X = std.transform(test_X)

dtrain = xgb.DMatrix(train_X,train_y)
dtest = xgb.DMatrix(test_X)

# 用最优参数构建模型
param = {'max_depth':20, 'eta':0.3, 'objective':'binary:logistic', 'eval_metric':'logloss'}
xgboost_model = xgb.train(param, dtrain, num_boost_round=20)

predicted_y = xgboost_model.predict(dtest)
for i in range(len(predicted_y)):
    if predicted_y[i] &gt; 0.5:
        predicted_y[i]=1
    else:
        predicted_y[i]=0

print('=========================================================================================')
print('参数: ')
print(param)
print('准确率：', accuracy_score(test_y, predicted_y))
print('精度：', precision_score(test_y, predicted_y))
print('召回率：', recall_score(test_y, predicted_y))
print('F1：', f1_score(test_y, predicted_y))
</code></pre>
<p>或者用K折(效果更好，但因为进行K次会更耗时)</p>
<pre><code class="language-python"># ================================= XGBoost =============================
import xgboost as xgb

# 设定不同的参数
&quot;&quot;&quot;
param_dict = dict(
    max_depth = [6],
    eta = [0.3],
    subsample = [ 0.8],
	colsample_bytree = [0.8],
    objective = ['binary:logistic'],
    eval_metric = ['error','logloss','map', 'auc'],
    seed = [0]
	gamma = [0.1]
	
)
&quot;&quot;&quot;
param_dict = dict(
    max_depth = [20],
	eta = [0.5],
	subsample = [1],
	colsample_bytree = [1],
	objective = ['binary:logistic'],
	eval_metric = ['error']
)
# 获得多组不同的参数组合
param_list = list_of_param_dicts(param_dict)

# 每个参数组合运行一次结果，看看哪个好
best_f1 = 0.0
best_param = None
for param in param_list:
    accs = []
    pres = []
    recalls = []
    f1s = []
    for sample_idx in range(len(train_data)):
        train_X, train_y = train_data[sample_idx]
        test_X, test_y = test_data[sample_idx]
        train_y = train_y.astype('int')
        test_y = test_y.astype('int')
        
        # 数据归一化处理
        std = StandardScaler()
        train_X = std.fit_transform(train_X)
        test_X = std.transform(test_X)
        
        dtrain = xgb.DMatrix(train_X,train_y)
        dtest = xgb.DMatrix(test_X,test_y)
        
        xgboost_model = xgb.train(param, dtrain, num_boost_round=20)
        predicted_y = xgboost_model.predict(dtest)
        
        for i in range(len(predicted_y)):
            if predicted_y[i] &gt; 0.5:
                 predicted_y[i]=1
            else:
                predicted_y[i]=0
        accs.append(accuracy_score(dtest.get_label(), predicted_y))
        pres.append(precision_score(dtest.get_label(), predicted_y))
        recalls.append(recall_score(dtest.get_label(), predicted_y))
        f1s.append(f1_score(dtest.get_label(), predicted_y))
    print('=========================================================================================')
    print('参数: ')
    print(param)
    print('准确率：', np.mean(np.array(accs)))
    print('精度：', np.mean(np.array(pres)))
    print('召回率：', np.mean(np.array(recalls)))
    print('F1：', np.mean(np.array(f1s)))
        
    if np.mean(np.array(f1s)) &gt; best_f1:
        best_f1 = np.mean(np.array(f1s))
        best_param = param

print('=========================================================================================')
print('best F1 score:', best_f1)
print('best parameter: ', best_param)
</code></pre>
<pre><code class="language-python"># 确定最优参数后用最优参数在整个训练集上训练模型
import xgboost as xgb

train_data = train_d.values
train_features = train_data[:, 1:]                       # 训练数据特征
train_labels = train_data[:, 0]                          # 训练数据标签

test_data = test_d.values                                
test_features = test_data[:,1:]                          # 预测数据特征

# 数据归一化
std = StandardScaler()
train_features = std.fit_transform(train_features)
train_labels = train_labels.astype('int')
test_features = std.transform(test_features)

dtrain = xgb.DMatrix(train_features,train_labels)
dtest = xgb.DMatrix(test_features)
# 用最优参数构建模型
param = {'max_depth': 20, 'eta': 0.3, 'subsample': 1, 'colsample_bytree': 1, 'objective': 'binary:logistic', 'eval_metric': 'logloss'}
xgboost_model = xgb.train(param, dtrain, num_boost_round=20)

# 输入没有标签的测试集特征
predicted_y = xgboost_model.predict(dtest)
for i in range(len(predicted_y)):
    if predicted_y[i] &gt; 0.5:
        predicted_y[i]=1
    else:
        predicted_y[i]=0

# 结果组合成df，保存输出结果
df_y = pd.DataFrame(predicted_y.tolist(),columns=['pre_result'])
df_u = test_d['usr_id']
result = pd.concat([df_u,df_y], axis=1)
result.to_csv(&quot;result.csv&quot;,index=False)
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Linux下的用户创建和sudo授权，以及添加ssh-keygen免密码登录]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>因为一般不直接用root用户操作，添加用户并且授权、免密登录就是一套常规操作了。</p>
<blockquote>
<p>注：环境为centos7.8,操作的初始角色root</p>
</blockquote>
<h2 id>用户创建和授权</h2>
<p>创建用户<br>
<code>adduser username</code></p>
<p>设置密码<br>
<code>passwd username</code></p>
<p>vim /etc/sudoers 进入文件编辑器，root用户wq!保存即可</p>
<pre><code>## Allow root to run any commands anywhere
root ALL=(ALL) ALL #已有行
## 增加一行
username ALL=(ALL) ALL
</code></pre>
<p>客户端键入</p>
<blockquote>
<p>ssh-keygen</p>
</blockquote>
<p>一路回车</p>
<p>服务端切换用户,创建文件</p>
<pre><code>$ su username
$ cd ~
$ ssh-keygen
$ cd .ssh/
$ vim authorized_</code></pre>]]></description><link>https://www.dbaren.com/post/linux-adduser-sudo-and-ssh-keygen/</link><guid isPermaLink="false">5fa1801a92f27e0001c353a9</guid><category><![CDATA[Linux]]></category><dc:creator><![CDATA[Aren]]></dc:creator><pubDate>Tue, 03 Nov 2020 16:22:30 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>因为一般不直接用root用户操作，添加用户并且授权、免密登录就是一套常规操作了。</p>
<blockquote>
<p>注：环境为centos7.8,操作的初始角色root</p>
</blockquote>
<h2 id>用户创建和授权</h2>
<p>创建用户<br>
<code>adduser username</code></p>
<p>设置密码<br>
<code>passwd username</code></p>
<p>vim /etc/sudoers 进入文件编辑器，root用户wq!保存即可</p>
<pre><code>## Allow root to run any commands anywhere
root ALL=(ALL) ALL #已有行
## 增加一行
username ALL=(ALL) ALL
</code></pre>
<p>客户端键入</p>
<blockquote>
<p>ssh-keygen</p>
</blockquote>
<p>一路回车</p>
<p>服务端切换用户,创建文件</p>
<pre><code>$ su username
$ cd ~
$ ssh-keygen
$ cd .ssh/
$ vim authorized_keys
</code></pre>
<p>把客户端内的 ~/.ssh/id_rsa.pub 的内容全部复制服务端的 authorized_keys 内</p>
<blockquote>
<p>ssh username@host -p22</p>
</blockquote>
<p>done.</p>
<h2 id="ssh">如果ssh连接提示无权限：</h2>
<blockquote>
<p>在本地 SSH 登录服务器，使用新创建的用户，提示：<br>
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).<br>
原因是用户主目录下的 .ssh 目录与它里面的 authorized_keys 文件的权限不能。<br>
.ssh 目录的权限应该是 700，authorized_keys 这个文件的权限应该设置成 600 。<br>
注意 .ssh 目录与 authorized_keys 的拥有者都必须是你创建的那个用户。比如我创建了一个叫 aren 的用户，那它应该是 .ssh 与 authorized_keys 的拥有者，并且必须要设置合适的权限</p>
</blockquote>
<pre><code>$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh_authorized_keys
</code></pre>
<h2 id="sudousrlocalbin">sudo 下环境变量没有加入到/usr/local/bin导致找不到命令的话</h2>
<pre><code># 修改 /etc/sudoers
# 找到
# Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin

#改为
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
</code></pre>
<!--kg-card-end: markdown--><h2></h2>]]></content:encoded></item><item><title><![CDATA[Centos下通过docker搭建ghost博客]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>一些前言：</p>
<p>很早我就想搭个blog，N年前的标准答案是wordpress，撇开代码不谈，外观实在太落后了（来自外貌协会的一票否决），也轻微折腾了一下fork了一些基于laravel的博客、想着基于自己熟悉的框架也比较方便，甚至想着不如自己用go或者java全新写一个一切尽在掌握，均不了了之。</p>
<p>后来我“痛定思痛”想了下，我只是想要个美观的、功能满足需求的的博客系统，至于自定义做一些开发这种事，如果是可以动鼠标和敲命令解决的问题、我是绝对懒得写代码的。</p>
<p>于是我重新考察了一下流行的博客系统，Hexo/Ghost/Vuepress，最后我决定用Ghost，简单理由如下：</p>
<ul>
<li>默认就比较符合审美的简约风格（黑白），也可以自己换主题</li>
<li>支持移动端良好访问</li>
<li>支持markdown写法（用过md、这辈子都不想用doc）</li>
<li>支持文章评论（通过插件或者gitalk）</li>
<li>后台管理，可以选择接入数据库，也可以纯文档部署</li>
<li>资料和开发工具支撑比较完善</li>
</ul>
<p>那，决定了就安装部署呗，生产环境官方给的例子是ubuntu的安装，但我tx云用的是centos7，考虑了下我觉得不如用docker好了，毕竟docker现在来看早就是大势所趋，docker可以很好解决各种不同环境下的服务部署问题，docker既是技术力也是生产力、多学学也不亏。</p>
<h2 id>下面正式开始安装部署教程：</h2>
<p>1、更新yum</p>
<pre><code>$ yum</code></pre>]]></description><link>https://www.dbaren.com/post/install-ghost-on-centos7-by-docker/</link><guid isPermaLink="false">5f97f2c03f16150001615d43</guid><category><![CDATA[开发]]></category><dc:creator><![CDATA[Aren]]></dc:creator><pubDate>Tue, 27 Oct 2020 10:15:07 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>一些前言：</p>
<p>很早我就想搭个blog，N年前的标准答案是wordpress，撇开代码不谈，外观实在太落后了（来自外貌协会的一票否决），也轻微折腾了一下fork了一些基于laravel的博客、想着基于自己熟悉的框架也比较方便，甚至想着不如自己用go或者java全新写一个一切尽在掌握，均不了了之。</p>
<p>后来我“痛定思痛”想了下，我只是想要个美观的、功能满足需求的的博客系统，至于自定义做一些开发这种事，如果是可以动鼠标和敲命令解决的问题、我是绝对懒得写代码的。</p>
<p>于是我重新考察了一下流行的博客系统，Hexo/Ghost/Vuepress，最后我决定用Ghost，简单理由如下：</p>
<ul>
<li>默认就比较符合审美的简约风格（黑白），也可以自己换主题</li>
<li>支持移动端良好访问</li>
<li>支持markdown写法（用过md、这辈子都不想用doc）</li>
<li>支持文章评论（通过插件或者gitalk）</li>
<li>后台管理，可以选择接入数据库，也可以纯文档部署</li>
<li>资料和开发工具支撑比较完善</li>
</ul>
<p>那，决定了就安装部署呗，生产环境官方给的例子是ubuntu的安装，但我tx云用的是centos7，考虑了下我觉得不如用docker好了，毕竟docker现在来看早就是大势所趋，docker可以很好解决各种不同环境下的服务部署问题，docker既是技术力也是生产力、多学学也不亏。</p>
<h2 id>下面正式开始安装部署教程：</h2>
<p>1、更新yum</p>
<pre><code>$ yum update
</code></pre>
<p>2、删除可能存在的旧版本</p>
<pre><code>$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
</code></pre>
<p>3、安装 <code>yum-utils</code> 组件，获取稳定的docker安装包。</p>
<pre><code>$ sudo yum install -y yum-utils

$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
</code></pre>
<p>注意：<br>
有些安装教程会用下边的命令安装<code>yum-utils</code>，但个人发现centos7已经默认就启用了device-mapper和安装了lvm2，所以没必要安装那两个依赖，低版本的centos可能才需要。</p>
<pre><code>#  preinstall utils 
sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2
</code></pre>
<p>4、安装docker</p>
<pre><code>$ sudo yum install docker-ce docker-ce-cli containerd.io
</code></pre>
<p>5、安装docker-compose</p>
<pre><code>sudo curl -L &quot;https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)&quot; -o /usr/local/bin/docker-compose
</code></pre>
<p>墙的关系这里很难下，我是直接本地下载了再scp传上服务器。</p>
<p>6、赋予docker-compose执行权限</p>
<pre><code>sudo chmod +x /usr/local/bin/docker-compose
</code></pre>
<p>7、启动docker、给当前用户赋权</p>
<pre><code># start deamon and enable auto start when power on
sudo systemctl start docker
sudo systemctl enable docker

# add current user 
sudo groupadd docker
sudo gpasswd -a ${USER} docker
sudo systemctl restart docker
</code></pre>
<p>8、配置ghost的docker-compose.yml</p>
<blockquote>
<p>vim docker-compose.yml</p>
</blockquote>
<pre><code>version: '3.1'
services:
  ghost:
    image: ghost:3.36-alpine
    restart: always
    container_name: ghost
    ports:
      - 2368:2368
    depends_on:
      - mysql
    links:
      - mysql
    environment:
      database__client: mysql
      database__connection__host: mysql
      database__connection__user: root
      database__connection__password: xxxxyyyy
      database__connection__database: ghost
      url: https://www.dbaren.com
    volumes:
      - ./ghost-data:/var/lib/ghost/content
    network_mode: bridge
  mysql:
    image: mysql:5.7
    restart: always
    container_name: mysql
    volumes:
      - ./mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: xxxxyyyy
    network_mode: bridge
</code></pre>
<p>启动：</p>
<p><code>$ docker-compose up -d</code></p>
<p>9、安装配置nginx代理2368端口</p>
<p><code>$ yum install nginx</code></p>
<p><code>$ sudo touch /etc/nginx/conf.d/blog.conf</code></p>
<pre><code>server {
    listen 80;
    server_name www.dbaren.com;
    client_max_body_size 50M;
    access_log  /var/log/nginx/dbaren.com.access.log  main;
    error_log /var/log/nginx/dbaren.com.error.log     warn;

    location / {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host $http_host;
        proxy_set_header   X-Forwarded-For $remote_addr;
        proxy_set_header   X-Forwarded-Proto https;
        proxy_connect_timeout   30;
        proxy_read_timeout      30;
        proxy_send_timeout      30;
        proxy_pass http://127.0.0.1:2368;
    }
}
</code></pre>
<p>10、配置highlight.js优化代码显示</p>
<p>Code injection -&gt; Site Header</p>
<pre><code>&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.1/styles/darcula.min.css&quot; integrity=&quot;sha512-0+Gq7jQLhuoMdL8EednGo8delKMhKim1t3XrvVGTqbJPfyv5f4HUJ0DTEN+3E+aM4RGEEfmVJOiomnP9olm4iw==&quot; crossorigin=&quot;anonymous&quot; /&gt;
</code></pre>
<p>我这里用的高亮主题是darcula，可以按自己需要的选的：<a href="https://cdnjs.com/libraries/highlight.js">highlight.js</a></p>
<p>Site footer</p>
<pre><code>&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.1/highlight.min.js&quot; integrity=&quot;sha512-U12+KlhI3X2EY7U4NJZ+O0wujKcaMQZHABtaiZtE8UrPiK1O3Y4cjBe0mMFyyBptdaf+eh45hqNdsayeLQcneg==&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
&lt;script &gt;hljs.initHighlightingOnLoad();&lt;/script&gt;
</code></pre>
<p>参考资料：</p>
<p><a href="https://ghost.org/docs/setup/">官方的安装文档</a></p>
<p><a href="https://www.itsfun.top/writing-with-ghost/">不折腾了, 决定使用Ghost写博客</a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[给ghost添加gitalk评论功能]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>虽然有墙的关系github访问是不太行，但终究还是喜欢gitalk的方案来实现评论功能，<a href="https://gitalk.github.io/">Gitalk Demo</a> &amp; <a href="https://github.com/gitalk/gitalk">Gitalk</a></p>
<p>前置准备：</p>
<ul>
<li>github帐户，没有可<a href="https://github.com/signup">创建</a>；</li>
<li>github repository，用于保存评论（issues），没有可<a href="https://github.com/new">创建</a>；</li>
<li>github application授权，没有可<a href="https://github.com/settings/applications/new">创建</a>。</li>
</ul>
<p>进到Ghost后台 &gt; Settings &gt; Code injection，在Site Header增加以下代码：</p>
<pre><code class="language-html">&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css&quot;&gt;
&lt;style</code></pre>]]></description><link>https://www.dbaren.com/post/gei-ghosttian-jia-gitalkping-lun-gong-neng/</link><guid isPermaLink="false">5f97af07c57cfe0001de292c</guid><category><![CDATA[开发]]></category><dc:creator><![CDATA[Aren]]></dc:creator><pubDate>Tue, 27 Oct 2020 05:25:54 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>虽然有墙的关系github访问是不太行，但终究还是喜欢gitalk的方案来实现评论功能，<a href="https://gitalk.github.io/">Gitalk Demo</a> &amp; <a href="https://github.com/gitalk/gitalk">Gitalk</a></p>
<p>前置准备：</p>
<ul>
<li>github帐户，没有可<a href="https://github.com/signup">创建</a>；</li>
<li>github repository，用于保存评论（issues），没有可<a href="https://github.com/new">创建</a>；</li>
<li>github application授权，没有可<a href="https://github.com/settings/applications/new">创建</a>。</li>
</ul>
<p>进到Ghost后台 &gt; Settings &gt; Code injection，在Site Header增加以下代码：</p>
<pre><code class="language-html">&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css&quot;&gt;
&lt;style type=&quot;text/css&quot;&gt;
&lt;!-- 下面的代码是改变评论框内的背景颜色的，ghost默认的主题下gitalk的评论框文字白色、背景也是白色会导致文字看不清 --&gt;
.gt-container .gt-header-textarea {
	background-color: #24292e;
}
.gt-container .gt-header-textarea:hover {
    background-color: #303a3e;
}
</code></pre>
<p>再在Site Footer增加以下代码（按自己情况改下参数配置）：</p>
<pre><code class="language-html">&lt;!-- gitalk --&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
    var gitalkDiv = document.createElement(&quot;div&quot;);
    gitalkDiv.setAttribute(&quot;id&quot;, &quot;gitalk-container&quot;);
    if(document.querySelector('.read-next')){
    	document.querySelector('.read-next').appendChild(gitalkDiv)
    }
    
    var gitalk = new Gitalk({
      clientID: 'github application的clientID',
      clientSecret: 'github application的clientSecret',
      repo: 'repository的名称',
      owner: 'repository的拥有者',
      admin: ['允许创建评论issue的github账户'],
      id: location.pathname,      // Ensure uniqueness and length less than 50
      distractionFreeMode: false  // Facebook-like distraction free mode
    })
    
    gitalk.render('gitalk-container')
&lt;/script&gt;
</code></pre>
<p>后话：直接把clientID和clientSecret暴露在js代码的做法总觉得不安全。</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>