<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-cn"><generator uri="https://gohugo.io/" version="0.147.7">Hugo</generator><title type="html">有呀</title><link href="https://nuoea.com/tags/%E6%9C%8B%E5%8F%8B%E5%9C%88/" rel="alternate" type="text/html" title="html"/><link href="https://nuoea.com/tags/%E6%9C%8B%E5%8F%8B%E5%9C%88/index.xml" rel="alternate" type="application/rss+xml" title="rss"/><updated>2026-07-07T04:03:54+00:00</updated><id>https://nuoea.com/tags/%E6%9C%8B%E5%8F%8B%E5%9C%88/</id><entry><title type="html">部署轻量友链朋友圈</title><link href="https://nuoea.com/friend-circle-lite/" rel="alternate" type="text/html"/><id>https://nuoea.com/friend-circle-lite/</id><published>2024-12-11T20:17:21+08:00</published><updated>2024-12-11T20:17:21+08:00</updated><content type="html"><![CDATA[<h2 id="前言">前言</h2>
<p>这两天突然发现，之前使用极简模式部署好的友链朋友圈没法获取到数据了。看了Github仓库才知道原项目已经停止支持了，取而代之的就是这个轻量友链朋友圈。</p>
<p>不知道是不是因为这个项目是为了 <code>hexo</code> 打造的原因，项目看了很久，愣是没看明白。直到把详细文档研究了一通，才大概明白了运行的原理。</p>
<p>其实严格来讲，该项目主要分为三个步骤：</p>
<ul>
<li>获取朋友圈JSON</li>
<li>配置 Github Action</li>
<li>拿到朋友圈文章列表JSON</li>
</ul>
<h2 id="获取朋友圈json">获取朋友圈JSON</h2>
<p>顾名思义，该步骤通过以下代码，将指定页面上的友链信息，直接转换成为一个 <code>friend.json</code> 。</p>
<p>原代码如下：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-JavaScript" data-lang="JavaScript"><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">YML</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;yamljs&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">fs</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;fs&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">let</span> <span style="color:#a6e22e">friends</span> <span style="color:#f92672">=</span> [],
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">data_f</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">YML</span>.<span style="color:#a6e22e">parse</span>(<span style="color:#a6e22e">fs</span>.<span style="color:#a6e22e">readFileSync</span>(<span style="color:#e6db74">&#39;source/_data/link.yml&#39;</span>).<span style="color:#a6e22e">toString</span>().<span style="color:#a6e22e">replace</span>(<span style="color:#e6db74">/(?&lt;=rss:)\s*\n/g</span>, <span style="color:#e6db74">&#39; &#34;&#34;\n&#39;</span>));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">data_f</span>.<span style="color:#a6e22e">forEach</span>((<span style="color:#a6e22e">entry</span>, <span style="color:#a6e22e">index</span>) =&gt; {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> <span style="color:#a6e22e">lastIndex</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">2</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">index</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">lastIndex</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">filteredLinkList</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">entry</span>.<span style="color:#a6e22e">link_list</span>.<span style="color:#a6e22e">filter</span>(<span style="color:#a6e22e">linkItem</span> =&gt; <span style="color:#f92672">!</span><span style="color:#a6e22e">blacklist</span>.<span style="color:#a6e22e">includes</span>(<span style="color:#a6e22e">linkItem</span>.<span style="color:#a6e22e">name</span>));
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">friends</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">friends</span>.<span style="color:#a6e22e">concat</span>(<span style="color:#a6e22e">filteredLinkList</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>});
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 根据规定的格式构建 JSON 数据
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">friendData</span> <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">friends</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">friends</span>.<span style="color:#a6e22e">map</span>(<span style="color:#a6e22e">item</span> =&gt; {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> [<span style="color:#a6e22e">item</span>.<span style="color:#a6e22e">name</span>, <span style="color:#a6e22e">item</span>.<span style="color:#a6e22e">link</span>, <span style="color:#a6e22e">item</span>.<span style="color:#a6e22e">avatar</span>];
</span></span><span style="display:flex;"><span>    })
</span></span><span style="display:flex;"><span>};
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 将 JSON 对象转换为字符串
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">friendJSON</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">JSON</span>.<span style="color:#a6e22e">stringify</span>(<span style="color:#a6e22e">friendData</span>, <span style="color:#66d9ef">null</span>, <span style="color:#ae81ff">2</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 写入 friend.json 文件
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#a6e22e">fs</span>.<span style="color:#a6e22e">writeFileSync</span>(<span style="color:#e6db74">&#39;./source/friend.json&#39;</span>, <span style="color:#a6e22e">friendJSON</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#e6db74">&#39;friend.json 文件已生成。&#39;</span>);
</span></span></code></pre></div><p>比较遗憾的是，该代码仅适用于 <code>HEXO</code> 博客程序，如果想要用在<code>HUGO</code>中，需要做如下修改：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-JavaScript" data-lang="JavaScript"><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">cheerio</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;cheerio&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">fs</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;fs&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">path</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;path&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 获取项目根目录的路径
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">projectRoot</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">process</span>.<span style="color:#a6e22e">cwd</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 读取 HTML 文件内容
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">htmlFilePath</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">path</span>.<span style="color:#a6e22e">join</span>(<span style="color:#a6e22e">projectRoot</span>, <span style="color:#e6db74">&#39;public&#39;</span>, <span style="color:#e6db74">&#39;links&#39;</span>, <span style="color:#e6db74">&#39;index.html&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">htmlContent</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">fs</span>.<span style="color:#a6e22e">readFileSync</span>(<span style="color:#a6e22e">htmlFilePath</span>).<span style="color:#a6e22e">toString</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 使用 cheerio 解析 HTML
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">$</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">cheerio</span>.<span style="color:#a6e22e">load</span>(<span style="color:#a6e22e">htmlContent</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 创建一个空的 friends 数组
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">let</span> <span style="color:#a6e22e">friends</span> <span style="color:#f92672">=</span> [];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 假设在 HTML 中每个好友信息存储在 &lt;div class=&#34;friend-item&#34;&gt; 中，
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 并且每个条目包含 &lt;a class=&#34;username&#34;&gt;、&lt;img class=&#34;avatar&#34;&gt; 和 &lt;a class=&#34;link&#34;&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#a6e22e">$</span>(<span style="color:#e6db74">&#39;.friend-item&#39;</span>).<span style="color:#a6e22e">each</span>((<span style="color:#a6e22e">index</span>, <span style="color:#a6e22e">element</span>) =&gt; {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">username</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">$</span>(<span style="color:#a6e22e">element</span>).<span style="color:#a6e22e">find</span>(<span style="color:#e6db74">&#39;.username&#39;</span>).<span style="color:#a6e22e">text</span>().<span style="color:#a6e22e">trim</span>();  <span style="color:#75715e">// 提取用户名
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">link</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">$</span>(<span style="color:#a6e22e">element</span>).<span style="color:#a6e22e">find</span>(<span style="color:#e6db74">&#39;.link&#39;</span>).<span style="color:#a6e22e">attr</span>(<span style="color:#e6db74">&#39;href&#39;</span>);  <span style="color:#75715e">// 提取链接
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">avatar</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">$</span>(<span style="color:#a6e22e">element</span>).<span style="color:#a6e22e">find</span>(<span style="color:#e6db74">&#39;.avatar&#39;</span>).<span style="color:#a6e22e">attr</span>(<span style="color:#e6db74">&#39;src&#39;</span>);  <span style="color:#75715e">// 提取头像
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// 如果都存在，添加到 friends 数组
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">username</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">link</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">avatar</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">friends</span>.<span style="color:#a6e22e">push</span>({
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">name</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">username</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">link</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">link</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">avatar</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">avatar</span>
</span></span><span style="display:flex;"><span>        });
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>});
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 根据规定的格式构建 JSON 数据
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">friendData</span> <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">friends</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">friends</span>.<span style="color:#a6e22e">map</span>(<span style="color:#a6e22e">item</span> =&gt; {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> [<span style="color:#a6e22e">item</span>.<span style="color:#a6e22e">name</span>, <span style="color:#a6e22e">item</span>.<span style="color:#a6e22e">link</span>, <span style="color:#a6e22e">item</span>.<span style="color:#a6e22e">avatar</span>];
</span></span><span style="display:flex;"><span>    })
</span></span><span style="display:flex;"><span>};
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 将 JSON 对象转换为字符串
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">friendJSON</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">JSON</span>.<span style="color:#a6e22e">stringify</span>(<span style="color:#a6e22e">friendData</span>, <span style="color:#66d9ef">null</span>, <span style="color:#ae81ff">2</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 写入 friend.json 文件到根目录
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#a6e22e">fs</span>.<span style="color:#a6e22e">writeFileSync</span>(<span style="color:#a6e22e">path</span>.<span style="color:#a6e22e">join</span>(<span style="color:#a6e22e">__dirname</span>, <span style="color:#e6db74">&#39;friend.json&#39;</span>), <span style="color:#a6e22e">friendJSON</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#e6db74">&#39;friend.json 文件已生成。&#39;</span>);
</span></span></code></pre></div><p>将该代码文件保存在根目录Link.js文件中。运行：</p>
<pre tabindex="0"><code>node link.js
</code></pre><p>就可以得到 <code>friend.json</code> 文件。</p>
<p>需要注意的是，这里需要用到 <code>cheerio</code> 解析 HTML。所以在运行前，需要：</p>
<pre tabindex="0"><code>npm install cheerio
</code></pre><p>以下就是JSON格式文件示例：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-JSON" data-lang="JSON"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;friends&#34;</span>: [
</span></span><span style="display:flex;"><span>    [
</span></span><span style="display:flex;"><span>	    <span style="color:#e6db74">&#34;林木木&#34;</span>,
</span></span><span style="display:flex;"><span>	    <span style="color:#e6db74">&#34;https://immmmm.com&#34;</span>,
</span></span><span style="display:flex;"><span>	    <span style="color:#e6db74">&#34;https://cravatar.cn/avatar/ba83fa02fc4b2ba621514941307e21be.jpeg?s=400&#34;</span>
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>    [
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;山卜方&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;https://novcu.com&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;https://cravatar.cn/avatar/6ebab96f3131621c51c08370d3c996f0.jpeg?s=400&#34;</span>
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>    [
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;大大的小蜗牛&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;https://eallion.com&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;https://cravatar.cn/avatar/171e4c30959e8c077a6c58b958624b31.jpeg?s=400&#34;</span>
</span></span><span style="display:flex;"><span>    ]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">}</span> 
</span></span></code></pre></div><h2 id="配置-github-action">配置 Github Action</h2>
<p>在 fork 了仓库：<a href="https://github.com/willow-god/Friend-Circle-Lite">Friend-Circle-Lite</a> 之后，只需要修改仓库中的 <code>config.yaml</code> 文件</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-YAML" data-lang="YAML"><span style="display:flex;"><span><span style="color:#f92672">spider_settings</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">enable</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">json_url</span>: <span style="color:#e6db74">&#34;https://&lt;你的地址&gt;/friend.json&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">article_count</span>: <span style="color:#ae81ff">5</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">merge_result</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">enable</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">merge_json_url</span>: <span style="color:#e6db74">&#34;&lt;你的地址&gt;&#34;</span>
</span></span></code></pre></div><p>如果需要邮件推送功能的，跟随官方文档完成相应配置即可。</p>
<h2 id="拿到朋友圈文章列表json">拿到朋友圈文章列表JSON</h2>
<p>在完成所有配置后，就可以手动或者自动的运行 <code>Github Action</code> ，该Action就会根据我们提供的 <code>friend.json</code> 拿到友链中所有朋友更新的文章啦。最后会在page分支中，生成一个 <code>all.json</code> ，通过调用这个文件，就可以做前端渲染了。</p>
<p>大功告成。</p>]]></content><category scheme="https://nuoea.com/categories/%E6%8A%98%E8%85%BE" term="%E6%8A%98%E8%85%BE" label="折腾"/><category scheme="https://nuoea.com/tags/%E6%9C%8B%E5%8F%8B%E5%9C%88" term="%E6%9C%8B%E5%8F%8B%E5%9C%88" label="朋友圈"/><category scheme="https://nuoea.com/tags/%E8%BF%9E%E6%8E%A5" term="%E8%BF%9E%E6%8E%A5" label="连接"/></entry><entry><title type="html">极简模式部署友链朋友圈</title><link href="https://nuoea.com/hi-circle-of-friends/" rel="alternate" type="text/html"/><id>https://nuoea.com/hi-circle-of-friends/</id><published>2023-06-11T15:50:37+08:00</published><updated>2023-06-11T15:50:37+08:00</updated><content type="html"><![CDATA[<h2 id="前言">前言</h2>
<p>曾经我常常感觉到，每一个独立的博客都像是一座彼此独立的孤岛。所以现在，有了越来越多的工具，把大家连接起来，像Memos、Twikoo等等。而<code>友链朋友圈</code>也是如此。你可以随时获取朋友网站的更新内容，并了解朋友的活跃情况，以此来将大家紧密的连接起来。</p>
<h2 id="页面适配">页面适配</h2>
<p>首先，友链页的抓取是通过css选择器进行的，所以我们需要将友链页按照友链朋友圈提供的规则进行修改。如果与对应规则不匹配，可能会遇到获取文章为0、管理面板出现status code 500、start error等错误。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yml" data-lang="yml"><span style="display:flex;"><span><span style="color:#ae81ff">/* 规则一（common1）：*/</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">/*  avatar </span>: <span style="color:#e6db74">&#39;.cf-friends img::attr(src)&#39;</span>  <span style="color:#75715e">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">/*  link </span>: <span style="color:#e6db74">&#39;.cf-friends a::attr(href)&#39;</span>  <span style="color:#75715e">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">/*  name </span>: <span style="color:#e6db74">&#39;.cf-friends a::text&#39;</span>  <span style="color:#75715e">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">/* 规则二（common2）：*/</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">/*  avatar </span>: <span style="color:#e6db74">&#39;img.cf-friends-avatar&#39;</span>  <span style="color:#75715e">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">/*  link </span>: <span style="color:#e6db74">&#39;a.cf-friends-link&#39;</span>  <span style="color:#75715e">*/</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">/*  name </span>: <span style="color:#e6db74">&#39;.cf-friends-name&#39;</span>  <span style="color:#75715e">*/</span>
</span></span></code></pre></div><p>只要上述css选择器能够匹配到，就完成了适配。根据规则，你编写的友链页面的友链部分可以是这样：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span> &lt;<span style="color:#f92672">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;cf-friends&#34;</span>&gt;
</span></span><span style="display:flex;"><span>   &lt;<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>     &lt;<span style="color:#f92672">img</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://www.baidu.com&#34;</span> <span style="color:#a6e22e">alt</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;&#34;</span>&gt; <span style="color:#75715e">&lt;!-- 头像 --&gt;</span>
</span></span><span style="display:flex;"><span>     &lt;<span style="color:#f92672">a</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://www.baidu.com&#34;</span>&gt;xxxx的博客&lt;/<span style="color:#f92672">a</span>&gt; <span style="color:#75715e">&lt;!-- 链接 --&gt;</span>
</span></span><span style="display:flex;"><span>   &lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>   &lt;<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>     &lt;<span style="color:#f92672">img</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://www.baidu.com&#34;</span> <span style="color:#a6e22e">alt</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;&#34;</span>&gt;
</span></span><span style="display:flex;"><span>     &lt;<span style="color:#f92672">a</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://www.baidu.com&#34;</span>&gt;xxxx的博客&lt;/<span style="color:#f92672">a</span>&gt;
</span></span><span style="display:flex;"><span>   &lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>   &lt;<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>     &lt;<span style="color:#f92672">img</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://www.baidu.com&#34;</span> <span style="color:#a6e22e">alt</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;&#34;</span>&gt;
</span></span><span style="display:flex;"><span>     &lt;<span style="color:#f92672">a</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://www.baidu.com&#34;</span>&gt;xxxx的博客&lt;/<span style="color:#f92672">a</span>&gt;
</span></span><span style="display:flex;"><span>   &lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>   &lt;<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>     &lt;<span style="color:#f92672">img</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://www.baidu.com&#34;</span> <span style="color:#a6e22e">alt</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;&#34;</span>&gt;
</span></span><span style="display:flex;"><span>     &lt;<span style="color:#f92672">a</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://www.baidu.com&#34;</span>&gt;xxxx的博客&lt;/<span style="color:#f92672">a</span>&gt;
</span></span><span style="display:flex;"><span>   &lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span> &lt;/<span style="color:#f92672">div</span>&gt;
</span></span></code></pre></div><p>也可以是：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>  &lt;<span style="color:#f92672">a</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;cf-friends-link&#34;</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://www.baidu.com&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">img</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;cf-friends-avatar&#34;</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://www.baidu.com&#34;</span> <span style="color:#a6e22e">alt</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">span</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;cf-friends-name&#34;</span>&gt; xxxx的博客&lt;/<span style="color:#f92672">span</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;/<span style="color:#f92672">a</span>&gt;
</span></span></code></pre></div><p>使用时，只需要在fc_settings.yaml配置文件中配置为common1或者common2即可。</p>
<h2 id="部署">部署</h2>
<p>友链朋友圈提供了非常多的部署方式，可以根据自己的习惯选择自己喜欢的方式部署，让我觉得十分的贴心。而我选择了极简模式。</p>
<blockquote>
<p>极简模式旨在最简程度运行程序，并输出最简化结果。</p></blockquote>
<p>在极简模式下，友链朋友圈会使用 Github Action 抓取友链页中的连接，并将连接RSS中的文章输出为一个Data.json文件存放在Github仓库中。而我们只需要调用这个文件，做前端渲染就行了。</p>
<blockquote>
<p><a href="https://hexo-circle-of-friends-doc.vercel.app/#/simplemode">极简模式部署</a></p></blockquote>
<p>如果担心 <code>data.json</code>  放在Github仓库访问不稳定，也可以通过 <code>up to aliyun oss</code> 等Github Action 将文件推送到国内的CDN上进行访问。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yml" data-lang="yml"><span style="display:flex;"><span>- <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Setup aliyun oss</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">uses</span>: <span style="color:#ae81ff">manyuanrong/setup-ossutil@master</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">with</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">endpoint</span>: <span style="color:#ae81ff">oss-cn-hangzhou.aliyuncs.com</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">access-key-id</span>: <span style="color:#ae81ff">${{ secrets.ACCESS_KEY_ID }}</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">access-key-secret</span>: <span style="color:#ae81ff">${{ secrets.ACCESS_KEY_SECRET }}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>- <span style="color:#f92672">name</span>: <span style="color:#ae81ff">To aliyun</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">run</span>: <span style="color:#ae81ff">ossutil cp -rf data.json oss://${{ secrets.BUCKET }}/</span>
</span></span></code></pre></div><p>需要在仓库的setting&ndash;&gt;Secrets and variables&ndash;&gt;Actions&ndash;&gt;New repository secret</p>
<p>配置好Action所需要的变量。</p>
<h2 id="渲染">渲染</h2>
<p>部署成功后，应该就可以在你 <code>fork</code> 的仓库中看到 <code>data.json</code> 文件了。那么接下来，就是在前端渲染了。</p>
<p>直接上代码：</p>
<ul>
<li>HTML</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#f92672">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;links&#34;</span>&gt;&lt;/<span style="color:#f92672">div</span>&gt;
</span></span></code></pre></div><ul>
<li>JS</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#66d9ef">var</span> <span style="color:#a6e22e">linksUrl</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;https://&lt;你的Github仓库地址&gt;/data.json&#39;</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">var</span> <span style="color:#a6e22e">linksDom</span> <span style="color:#f92672">=</span> document.<span style="color:#a6e22e">querySelector</span>(<span style="color:#e6db74">&#39;.links&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">linksDom</span>) {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">getLinks</span>()
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">getLinks</span>() {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">fetch</span>(<span style="color:#a6e22e">linksUrl</span>).<span style="color:#a6e22e">then</span>(<span style="color:#a6e22e">res</span> =&gt; <span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">json</span>()).<span style="color:#a6e22e">then</span>(<span style="color:#a6e22e">resdata</span> =&gt; {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">updateHtml</span>(<span style="color:#a6e22e">resdata</span>.<span style="color:#a6e22e">article_data</span>);
</span></span><span style="display:flex;"><span>  });
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">updateHtml</span>(<span style="color:#a6e22e">data</span>){
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">result</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">resultAll</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;&#34;</span>;
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">i</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">i</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">data</span>.<span style="color:#a6e22e">length</span>; <span style="color:#a6e22e">i</span><span style="color:#f92672">++</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> <span style="color:#a6e22e">author</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">data</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">author</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">avatar</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">data</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">avatar</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">title</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">data</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">title</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">link</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">data</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">link</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">floor</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">data</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">floor</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">created</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">data</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">created</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">result</span> <span style="color:#f92672">+=</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;&lt;div class=&#34;col-12 mt-3&#34;&gt;&lt;div class=&#34;item-body flex-fill p-3&#34;&gt;&lt;div class=&#34;item-header d-flex mb-3&#34;&gt;&lt;div class=&#34;item-avatar mr-3&#34; style=&#34;background-image:url(&#39;</span><span style="color:#f92672">+</span> <span style="color:#a6e22e">avatar</span> <span style="color:#f92672">+</span><span style="color:#e6db74">&#39;)&#34;&gt;&lt;/div&gt;&lt;div class=&#34;item-sub&#34;&gt;&lt;div class=&#34;item-creator&#34;&gt;&#39;</span><span style="color:#f92672">+</span> <span style="color:#a6e22e">author</span> <span style="color:#f92672">+</span><span style="color:#e6db74">&#39;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class =&#34;item-content d-flex flex-fill flex-column&#34;&gt;&lt;div class=&#34;item-inner flex-fill my-2&#34;&gt;&lt;a href=&#34;&#39;</span><span style="color:#f92672">+</span><span style="color:#a6e22e">link</span><span style="color:#f92672">+</span><span style="color:#e6db74">&#39;&#34; target=&#34;_blank&#34;&gt;&#39;</span><span style="color:#f92672">+</span> <span style="color:#a6e22e">title</span><span style="color:#f92672">+</span><span style="color:#e6db74">&#39;&lt;/a&gt;&lt;/div&gt;&lt;div class=&#34;item-footer d-flex mt-2&#34;&gt;&lt;div class=&#34;item-time item-tag d-flex align-items-center px-2 text-xs&#34;&gt;&#39;</span><span style="color:#f92672">+</span><span style="color:#a6e22e">created</span><span style="color:#f92672">+</span><span style="color:#e6db74">&#39;&lt;/div&gt;&lt;div class=&#34;d-flex flex-fill justify-content-end&#34;&gt;&lt;div class=&#34;item d-flex align-items-center&#34;&gt;&lt;i class=&#34;iconfont iconthunderbolt&#34;&gt;&lt;/i&gt;&lt;span class=&#34;ml-1&#34;&gt;&#39;</span><span style="color:#f92672">+</span><span style="color:#a6e22e">floor</span><span style="color:#f92672">+</span><span style="color:#e6db74">&#39;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&#39;</span>;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">resultAll</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">result</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">linksDom</span>.<span style="color:#a6e22e">insertAdjacentHTML</span>(<span style="color:#e6db74">&#39;beforeend&#39;</span>, <span style="color:#a6e22e">resultAll</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>其中<code>result</code> 内的HTML结构请根据主题自行修改。</p>
<p>搞定收工～</p>]]></content><category scheme="https://nuoea.com/categories/%E6%8A%98%E8%85%BE" term="%E6%8A%98%E8%85%BE" label="折腾"/><category scheme="https://nuoea.com/tags/%E8%BF%9E%E6%8E%A5" term="%E8%BF%9E%E6%8E%A5" label="连接"/><category scheme="https://nuoea.com/tags/%E6%9C%8B%E5%8F%8B%E5%9C%88" term="%E6%9C%8B%E5%8F%8B%E5%9C%88" label="朋友圈"/></entry></feed>