<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>搁浅St的blog</title>
        <link>https://blog.huirongis.me/</link>
        <description>Recent content on 搁浅St的blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-CN</language>
        <lastBuildDate>Sun, 08 Nov 2026 16:13:21 +0000</lastBuildDate><atom:link href="https://blog.huirongis.me/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>xiaodu bridge 使用说明：把 Home Assistant 设备接进小度</title>
        <link>https://blog.huirongis.me/post/xiaodu-bridge-connect-home-assistant-devices/</link>
        <pubDate>Mon, 31 Aug 2026 23:40:00 +0800</pubDate>
        
        <guid>https://blog.huirongis.me/post/xiaodu-bridge-connect-home-assistant-devices/</guid>
        <description>&lt;p&gt;&lt;code&gt;xiaodu_bridge&lt;/code&gt; 是一个 Home Assistant 自定义集成。它把 HA 里已经接好的设备重新组织成 DuerOS 语义设备，再交给小度音箱和小度 App 发现、查询和控制。商店里的名字是 &lt;code&gt;xiaodu bridge&lt;/code&gt;，集成 domain 是 &lt;code&gt;xiaodu_bridge&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;它不是把 HA 实体一对一转成小度设备，而是有一个桥接层：一台浴霸可以把照明、取暖、换气等多个 HA 实体聚合成一台浴霸；一个房间也能从 HA 区域同步成小度房间分组。小度发来的控制请求先进入这个桥接层，再由它调用 HA 的实体服务。&lt;/p&gt;
&lt;p&gt;整体链路是：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TB
  subgraph home[&amp;#34;家里&amp;#34;]
    direction TB
    devices[&amp;#34;米家 / Zigbee / 蓝牙 / Matter&amp;#34;]
    ha[&amp;#34;Home Assistant&amp;lt;br/&amp;gt;实体 + 区域 + 能力&amp;#34;]
    bridge[&amp;#34;xiaodu bridge&amp;lt;br/&amp;gt;DuerOS 语义设备模型&amp;#34;]
    entry[&amp;#34;公网入口&amp;lt;br/&amp;gt;域名 / DDNS / NGINX&amp;#34;]
  end
  cloud[&amp;#34;小度云端&amp;#34;]
  speaker[&amp;#34;小度音箱&amp;#34;]
  app[&amp;#34;小度 App&amp;#34;]

  devices --&amp;gt;|&amp;#34;标准化实体&amp;#34;| ha
  ha --&amp;gt;|&amp;#34;选中设备&amp;#34;| bridge
  cloud --&amp;gt;|&amp;#34;OAuth / 控制请求&amp;#34;| entry
  entry --&amp;gt; bridge
  bridge --&amp;gt;|&amp;#34;发现 / 控制 / 查询&amp;#34;| ha
  bridge --&amp;gt;|&amp;#34;Change Report&amp;#34;| cloud
  cloud --&amp;gt; speaker
  cloud --&amp;gt; app
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;整套配置从 HA 侧往小度侧推，一次走完大致是：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
  a[&amp;#34;设备接进 HA&amp;lt;br/&amp;gt;改名字 / 分区域&amp;#34;]
  b[&amp;#34;安装 xiaodu bridge&amp;lt;br/&amp;gt;HACS 或手动&amp;#34;]
  c[&amp;#34;配置公网 HTTPS 入口&amp;lt;br/&amp;gt;DDNS + 证书 + 反向代理&amp;#34;]
  d[&amp;#34;小度后台创建智能家居技能&amp;#34;]
  e[&amp;#34;HA 里配置 Client / botId / Callback&amp;#34;]
  f[&amp;#34;选择暴露设备和能力&amp;lt;br/&amp;gt;开启 sync_areas&amp;#34;]
  g[&amp;#34;小度发现设备&amp;lt;br/&amp;gt;模拟测试 + 语音测试&amp;#34;]

  a --&amp;gt; b --&amp;gt; c --&amp;gt; d --&amp;gt; e --&amp;gt; f --&amp;gt; g
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;仓库地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/Jackroyal/xiaodu-bridge&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/Jackroyal/xiaodu-bridge&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;准备设备&#34;&gt;准备设备
&lt;/h1&gt;&lt;p&gt;装桥接之前，先把设备名字和房间理好。&lt;/p&gt;
&lt;p&gt;小度侧的设备名就是 HA 实体名，房间就是 HA 区域。&lt;code&gt;switch.switch_1&lt;/code&gt; 这种名字说不出来，小度也就没法控制了。改名字只做两件事：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1. 名字改成适合说话的：客厅吸顶灯、卧室空调、书房插座。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2. 房间分对：客厅就是客厅，卧室就是卧室。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;改名字最省事的位置是源头：小米的设备名和房间从米家 App 直接同步到 HA，HA 再同步给小度，一路下来不用重复修改，源头设置好后续链路可以自动同步。&lt;/p&gt;
&lt;p&gt;米家、蓝牙、美的空调 等设备都有各自的接入方式，Xiaomi Home、Sonoff、Midea Smart Home 这些集成我都在用，大家根据各自设备按需选择自己对应的集成，善用大模型或搜索。&lt;/p&gt;
&lt;h1 id=&#34;安装集成&#34;&gt;安装集成
&lt;/h1&gt;&lt;p&gt;要求 Home Assistant &lt;code&gt;2025.1.0&lt;/code&gt; 或更高版本。本文按 &lt;code&gt;xiaodu bridge&lt;/code&gt; v0.9.17 写。&lt;/p&gt;
&lt;h2 id=&#34;hacs-安装推荐&#34;&gt;HACS 安装（推荐）
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;xiaodu bridge&lt;/code&gt; 已经进了 HACS 默认商店，不用再加自定义仓库：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;HACS → Integrations，搜索 &lt;strong&gt;xiaodu bridge&lt;/strong&gt;，下载。&lt;/li&gt;
&lt;li&gt;重启 Home Assistant。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;HACS 下载只是把文件装到位。重启后还要去 &lt;strong&gt;设置 → 设备与服务 → 添加集成&lt;/strong&gt;，搜 &lt;code&gt;xiaodu bridge&lt;/code&gt; 添加一次——填 OAuth 凭证、botId、公网地址就在这一步。只下载不添加，集成不会生效。&lt;/p&gt;
&lt;h2 id=&#34;手动安装&#34;&gt;手动安装
&lt;/h2&gt;&lt;p&gt;不想用 HACS 就手动复制：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git clone https://github.com/Jackroyal/xiaodu-bridge.git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cp -R xiaodu-bridge/custom_components/xiaodu_bridge /config/custom_components/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;复制完检查路径，别多套一层：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;正确：/config/custom_components/xiaodu_bridge/manifest.json
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;错误：/config/custom_components/xiaodu_bridge/xiaodu_bridge/manifest.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;确认没套错后重启：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ha core restart
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;手动和 HACS 两条路到这里都只是「文件装好了」，最后一步是一样的：去 &lt;strong&gt;设置 → 设备与服务 → 添加集成&lt;/strong&gt;里搜 &lt;code&gt;xiaodu bridge&lt;/code&gt; 添加。&lt;/p&gt;
&lt;p&gt;添加完成后，集成列表里就能看到它：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/xiaodu-bridge/ha-integrations.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;集成列表里的 Xiaodu Bridge&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;点进详情页，会看到版本号、一个「小度中枢」设备，以及右上角的齿轮（配置）和三个点（菜单）按钮（截图停在 0.9.13，之后的版本界面没变）：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/xiaodu-bridge/ha-xiaodu-detail.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Xiaodu Bridge 详情页&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;配置公网访问&#34;&gt;配置公网访问
&lt;/h1&gt;&lt;p&gt;正式接入时，小度云端会回调 &lt;code&gt;xiaodu bridge&lt;/code&gt; 提供的三个 HTTPS 接口（必须按这个填写，写死的path）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/api/xiaodu/oauth/authorize
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/api/xiaodu/oauth/token
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/api/xiaodu/service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;所以纯内网地址完成不了正式接入，小度云端必须能从外面访问到 HA 的这几个路径。推荐结构：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;小度云端
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → 公网域名
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → 路由器端口转发
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → HAOS 反向代理
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → HA Core 8123
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  → xiaodu bridge
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我家里是电信光纤，有公网 IPv4，主路由是华硕路由器。华硕自带 DDNS，但它内置的服务商里只有花生壳这类要实名的，我常用的 cloudflare / dnspod 都不在里面。&lt;/p&gt;
&lt;p&gt;所以我在局域网的软路由上装了 iStoreOS，用它来做域名解析更新：软路由是长期开机的，在上面跑一个 ddns 插件，公网 IP 一变就调 cloudflare / dnspod 的 API 把 A 记录改掉。华硕路由器该干嘛干嘛，DDNS 这件事交给软路由，和 HAOS 在哪台机器上没关系。&lt;/p&gt;
&lt;h2 id=&#34;1-确认真的有公网-ipv4&#34;&gt;1. 确认真的有公网 IPv4
&lt;/h2&gt;&lt;p&gt;路由器 WAN IP 和手机流量看到的出口 IP 一致才算数。WAN IP 是 &lt;code&gt;100.x.x.x&lt;/code&gt;、&lt;code&gt;10.x.x.x&lt;/code&gt;、&lt;code&gt;172.16.x.x&lt;/code&gt;、&lt;code&gt;192.168.x.x&lt;/code&gt; 这些，就是运营商套了一层，说明你没有公网ip，别折腾端口转发了。&lt;/p&gt;
&lt;h2 id=&#34;2-域名和-ddns&#34;&gt;2. 域名和 DDNS
&lt;/h2&gt;&lt;p&gt;先准备一个域名，比如 &lt;code&gt;ha.example.com&lt;/code&gt;，在你使用的域名解析后台（cloudflare/dnspod/aliyun之类的）加一条 A 记录指向公网 IP。IP 会变就配 DDNS，公网 IP 一变，域名跟着变。&lt;/p&gt;
&lt;p&gt;我用的是 ddns-go。在 iStoreOS 的应用商店里搜「ddns-go」装上，装完它会起一个 Web 配置页，浏览器打开 &lt;code&gt;软路由IP:9876&lt;/code&gt; 就能看到面板，填完配置它会以服务形式常驻，公网 IP 一变就自动更新解析。&lt;/p&gt;
&lt;p&gt;面板上要填的就几项：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;配置项&lt;/th&gt;
          &lt;th&gt;填什么&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;DNS服务商&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;顶部单选，支持阿里云 / DnsPod / Cloudflare / 华为云 等二十来家&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;Token&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;对应服务商的 API 凭据（截图里 Cloudflare 就一个 Token 输入框，面板上还带生成令牌的指引链接）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;TTL&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;域名解析的缓存时间，默认「自动」即可；测试阶段可以设短一点，便于改动快速生效&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;域名&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;要更新的那条记录，比如 &lt;code&gt;ha.example.com&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;IP 获取方式&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;默认「通过接口获取」就行——软路由自己不持有公网 IP 时，靠本地网卡读不到真实出口地址，让它去外部接口查更准&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/xiaodu-bridge/ddns-go-panel.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;ddns-go 配置面板：DNS 服务商单选、Token、TTL&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;配完在面板上点「测试」或等一个更新周期，然后在电脑上用 &lt;code&gt;nslookup ha.example.com&lt;/code&gt; 或 &lt;code&gt;dig&lt;/code&gt; 看一眼解析结果对不对。DNS 记录用“仅 DNS”模式。&lt;/p&gt;
&lt;p&gt;平常用多个服务商的话，面板顶部有「配置切换」，可以建多套配置（比如一套 cloudflare、一套 dnspod），点「添加」新建、切换下拉选择，互不影响。
大致的原理，其实就是起个脚本监听ip变化，如果发生变化则调用cloudflare或者dnspod等的api接口更新一下域名对应的ip，变更肯定会有一定延迟，但够用了。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这里的 API Token 后面配证书还要用——HAOS 的 Let&amp;rsquo;s Encrypt add-on 走 DNS 校验，连的就是同一个 provider。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;3-端口转发&#34;&gt;3. 端口转发
&lt;/h2&gt;&lt;p&gt;家宽对 80 和 443 的入站管控挺常见，可以用 &lt;code&gt;8443&lt;/code&gt; 这种非标端口：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;外部协议：TCP
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;外部端口：8443
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;内部目标：HAOS 主机 IP，例如 192.168.1.10
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;内部端口：443
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;里面的 443 给 HAOS 反向代理监听。HA 的 8123 端口不要直接暴露，公网统一走 HTTPS，由反向代理转 8123。&lt;/p&gt;
&lt;p&gt;为了安全起见不建议使用DMZ开放过多内容，使用端口转发只开放一个端口，相对更安全。&lt;/p&gt;
&lt;p&gt;华硕路由器自身远程控制用的是8443（使用华硕的子域名，我要使用自定义域名，所以不复用8443），所以我使用的是8663端口。&lt;/p&gt;
&lt;h2 id=&#34;4-证书和反向代理&#34;&gt;4. 证书和反向代理
&lt;/h2&gt;&lt;p&gt;HAOS 可以直接用 Let&amp;rsquo;s Encrypt 和 NGINX SSL proxy 这两个 add-on。跑 Docker / Core 或其他安装方式的，这两个 add-on 用不了，需要在宿主机或容器旁边准备等价方案（Caddy、NGINX 或带 DNS 模块的 Caddy）。&lt;/p&gt;
&lt;p&gt;HAOS 上这两个 add-on 的证书走 DNS 校验，不依赖 80 端口，证书目录和文件名默认就是配套的，装完不用手动挪证书。&lt;/p&gt;
&lt;p&gt;Cloudflare DNS 的例子：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;challenge&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;dns&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;dns&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;provider&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;dns-cloudflare&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;cloudflare_api_token&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;&amp;lt;你的Cloudflare API Token&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;domains&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#ae81ff&#34;&gt;ha.example.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;email&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;&amp;lt;你的邮箱&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;NGINX SSL proxy 只需要配域名和其他选项：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;domain&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;ha.example.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;hsts&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;max-age=31536000; includeSubDomains&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;client_max_body_size_megabytes&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;cloudflare&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;反向代理只放行小度需要的那三个路径（前面列过），其他公网请求返回 404。&lt;/p&gt;
&lt;p&gt;别为了省事把整个 HA 管理页面开放到公网。&lt;/p&gt;
&lt;p&gt;然后到 HA 的 设置 → 系统 → 网络，外部地址填：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;https://ha.example.com:8443
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;外网请求返回 400、日志里出现 forwarded 或 trusted proxy 相关内容，多半是反向代理网段没进 &lt;code&gt;trusted_proxies&lt;/code&gt;。把 NGINX 所在网段加进去，并开启 &lt;code&gt;use_x_forwarded_for&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/xiaodu-bridge/ha-network-trusted-proxy.webp&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;HA 网络设置：信任 X-Forwarded-For 与受信任的代理&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;在小度后台建技能&#34;&gt;在小度后台建技能
&lt;/h1&gt;&lt;p&gt;登录小度开发者平台，创建智能家居技能。技能的「配置服务」里要填的东西，来自两个地方：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;小度后台基础信息页：
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  botId          技能 ID，后面要填回 HA 集成里
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HA 集成确认页给出的三个地址（这里用它们）：
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  授权地址        Authorize，HA 公网地址 + /api/xiaodu/oauth/authorize
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Token地址       HA 公网地址 + /api/xiaodu/oauth/token
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  WebService      HA 公网地址 + /api/xiaodu/service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;自己定义、两边配一致：
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Client_Id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ClientSecret
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;假设公网地址是 &lt;code&gt;https://ha.example.com:8443&lt;/code&gt;，三个地址就是把上面的路径拼在它后面，比如 &lt;code&gt;https://ha.example.com:8443/api/xiaodu/oauth/authorize&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;后台「配置服务」页填起来就长这样（授权地址 / Client_Id / 回调地址 / Token 地址 / ClientSecret / WebService）：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/xiaodu-bridge/dueros-config-service.webp&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;小度后台配置服务：授权地址、Token 地址、WebService 的填法&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;授权和设备发现的过程是：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;sequenceDiagram
  autonumber
  participant U as 用户 / 浏览器
  participant D as 小度云端
  participant X as 公网入口 / xiaodu bridge
  participant H as Home Assistant

  U-&amp;gt;&amp;gt;D: 开始绑定账号
  D-&amp;gt;&amp;gt;U: 打开 Authorize URL
  U-&amp;gt;&amp;gt;X: 访问授权页并同意
  X--&amp;gt;&amp;gt;D: 返回到小度 Callback
  D-&amp;gt;&amp;gt;X: 请求 Token URL
  X--&amp;gt;&amp;gt;D: 下发私有 Access / Refresh Token
  D-&amp;gt;&amp;gt;X: 调用 WebService 发现设备
  X-&amp;gt;&amp;gt;H: 读取已选实体、区域和能力
  H--&amp;gt;&amp;gt;X: 返回实体状态
  X--&amp;gt;&amp;gt;D: 返回 DuerOS 语义设备
  D--&amp;gt;&amp;gt;U: 展示可控制设备
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;两个容易搞混的点：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1. Client_Id 和 ClientSecret 是自己定义的，不是百度分配的，两边配一致就行。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   Secret 用长随机串，别用 123456 这种。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2. 回调地址不是你的 HA 地址，是小度平台生成的那个，填回 HA 集成里时要原样照抄。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;填写-oauth-配置&#34;&gt;填写 OAuth 配置
&lt;/h1&gt;&lt;p&gt;重启 HA 后打开：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;设置 → 设备与服务 → 添加集成 → xiaodu bridge
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;按下面填（界面是中文标签，括号里是它的含义）：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;界面字段&lt;/th&gt;
          &lt;th&gt;填什么&lt;/th&gt;
          &lt;th&gt;示例&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;Client_Id&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;自定义客户端 ID&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;dueros_xxx&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;ClientSecret&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;自定义随机密钥&lt;/td&gt;
          &lt;td&gt;一段长随机串&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;小度技能ID（botId）&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;小度后台技能 ID&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;12345678&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;回调地址&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;小度平台生成的地址，不可修改&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;https://xiaodu.baidu.com/...&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;公网访问地址（HTTPS）&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;HA 公网基础地址&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;https://ha.example.com:8443&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;保存后确认页会把授权地址、Token地址、WebService 三个地址直接列出来，照着填到小度后台就行，不用自己拼。&lt;code&gt;Client_Id&lt;/code&gt; / &lt;code&gt;ClientSecret&lt;/code&gt; 两边保持一致即可——它们是你自己定义的，不是百度分配的。&lt;/p&gt;
&lt;p&gt;回调地址不用操心调试环境：集成自动兼容小度的正式环境（&lt;code&gt;xiaodu.baidu.com&lt;/code&gt;）与调试环境（&lt;code&gt;xiaodu-dbp.baidu.com&lt;/code&gt;），后台只用填平台生成的那一个。&lt;/p&gt;
&lt;p&gt;填错了想改，打开集成条目右上角 &lt;code&gt;⋮&lt;/code&gt; →「重新配置」（OAuth 配置）就能重填，不用删掉集成。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/xiaodu-bridge/ha-single-instance.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;OAuth 配置&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;OAuth token 这块集成自己管：Access Token 有效期 7 天，Refresh Token 30 天，到期用 refresh_token 续。这个 token 是桥接层自己的私有不透明串，只能打小度桥接的接口，碰不到 HA 的 API。&lt;/p&gt;
&lt;h1 id=&#34;选择要暴露给小度的设备&#34;&gt;选择要暴露给小度的设备
&lt;/h1&gt;&lt;p&gt;添加成功后，打开集成条目 →「配置」，进入「小度中枢」页：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/xiaodu-bridge/ha-hub-menu.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;小度中枢：配置菜单&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;注意：从 v0.9.15 起，设备暴露改成按需选择。全新安装、或者从没保存过设备选项的实例，默认不会向小度发送任何设备，必须在这里选好并保存。&lt;/p&gt;
&lt;p&gt;建议别一次全选，先拿两三台练手：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;点「添加 / 移除设备」。&lt;/li&gt;
&lt;li&gt;选择要暴露的 HA 设备（列表按「房间 · 设备名」展示，重名的实体也能分清）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/xiaodu-bridge/ha-device-select.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;添加 / 移除设备：设备按房间分组&#34;
	
	
&gt;&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;点进某台设备，先选「设备能力」勾选能力；需要时再进「高级配置」限制能力、隐藏实体、绑定语义角色或改小度侧的展示名。&lt;/li&gt;
&lt;li&gt;保存后让小度重新发现。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;已选设备可以在「已选设备」列表里逐台检查：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/xiaodu-bridge/ha-device-selected.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;已选设备列表&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;设备默认暴露全部可用能力，想省事可以直接用默认；想精细控制再一台台进能力编辑。控制类设备的开关能力是强制的，温湿度这种只读能力按需勾。底部那个「同步 HA 房间到小度」开关打开后，HA 的区域会同步成小度的房间分组。&lt;/p&gt;
&lt;p&gt;暴露得越精准，后面误触发越少，不需要把 HA 里每个实体都丢给小度。&lt;/p&gt;
&lt;h1 id=&#34;测试&#34;&gt;测试
&lt;/h1&gt;&lt;p&gt;按这个顺序来：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;小度开发者后台触发设备发现。&lt;/li&gt;
&lt;li&gt;看设备有没有出现在小度侧。&lt;/li&gt;
&lt;li&gt;查询一个温湿度传感器。&lt;/li&gt;
&lt;li&gt;打开一个灯或插座，再关掉。&lt;/li&gt;
&lt;li&gt;手动动一下设备状态，看小度 App 是否同步。&lt;/li&gt;
&lt;li&gt;用音箱和 App 试真实语音。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;HAOS 上看日志：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ha core logs -f | grep --line-buffered &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Xiaodu access&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;成功的发现请求里能看到这样一段（实际是一行）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kind=dueros namespace=DuerOS.ConnectedHome.Discovery \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;name=DiscoverAppliancesRequest result=DiscoverAppliancesResponse status=200
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里连请求都没有，就别急着改 HA 配置，先查域名、端口转发、证书和反向代理。&lt;/p&gt;
&lt;p&gt;语音可以试这些：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;小度小度，打开客厅灯。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;小度小度，把卧室空调调到 26 度。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;小度小度，客厅温度是多少？
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;小度小度，明天早上八点打开书房插座。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;几个值得说的特性&#34;&gt;几个值得说的特性
&lt;/h1&gt;&lt;p&gt;这几个特性单独拎出来说。&lt;/p&gt;
&lt;h2 id=&#34;主动状态上报&#34;&gt;主动状态上报
&lt;/h2&gt;&lt;p&gt;可控设备状态一变，集成会主动推 Change Report 给小度，小度 App 里的状态会跟着刷新。纯只读传感器不上报，这类本来也没有“被控制”的状态可推。小度云端偶尔会拒绝一次（开机那波最常见），集成会在 60 秒窗口后补发一次，不会无限重试。&lt;/p&gt;
&lt;h2 id=&#34;房间分组&#34;&gt;房间分组
&lt;/h2&gt;&lt;p&gt;HA 区域同步成小度房间分组后，“打开客厅的灯”这类指令小度能自己圈范围，不用每台设备都指名道姓。前提还是第一步：房间得分对。&lt;/p&gt;
&lt;h2 id=&#34;定时开关&#34;&gt;定时开关
&lt;/h2&gt;&lt;p&gt;支持小度侧的 timingTurnOn 和 timingTurnOff。定时信息存在 HA Storage 里，HA 重启后任务仍然保留。&lt;/p&gt;
&lt;h2 id=&#34;语义设备模型&#34;&gt;语义设备模型
&lt;/h2&gt;&lt;p&gt;这是桥接层最核心的设计。它不是把 HA 实体一对一递给小度，而是先在桥接层把设备组装成 DuerOS 语义设备：浴霸就是一台浴霸，照明取暖换气都在它身上；洗衣机、晾衣杆、扫地机同理。小度协议定义了六十多种设备类型，这个集成实现了常用的十几种：灯、开关、插座、空调、窗帘、风扇、传感器、媒体播放器，外加浴霸、晾衣杆、扫地机、洗衣机四个专用档案。&lt;/p&gt;
&lt;p&gt;晾衣杆的语义按小度的实际模型处理：开关控制的是照明，升降走上升 / 下降动作；没有灯实体的机型回退为控制杆子本身。&lt;/p&gt;
&lt;h1 id=&#34;常见排查&#34;&gt;常见排查
&lt;/h1&gt;&lt;h2 id=&#34;集成搜索不到&#34;&gt;集成搜索不到
&lt;/h2&gt;&lt;p&gt;先看目录有没有多套一层，再看 &lt;code&gt;manifest.json&lt;/code&gt; 是否存在，然后重启 HA。HACS 里搜不到的话，先把 HACS 更新到最新版并刷新商店列表；还是没有就改用手动安装。&lt;/p&gt;
&lt;h2 id=&#34;ha-里正常小度发现不到&#34;&gt;HA 里正常，小度发现不到
&lt;/h2&gt;&lt;p&gt;按顺序查：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1. 小度后台 WebService 地址对不对。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2. 地址里的端口有没有少。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3. 公网能不能访问 HA。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4. 反向代理有没有放行 /api/xiaodu。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;5. HA 集成里有没有选中设备。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;6. HA 日志里有没有 Xiaodu access。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果小度云端访问不到 HA，音箱和后台都会持续失败，先把公网链路查完。&lt;/p&gt;
&lt;p&gt;授权页打不开也是同一类问题，从外面测一下入口通不通：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -I https://ha.example.com:8443/api/xiaodu/service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;能拿到 HTTP 状态码说明入口至少通了；TLS 都失败的话，先解决证书、DNS 和端口转发。&lt;/p&gt;
&lt;h2 id=&#34;米家设备状态不准&#34;&gt;米家设备状态不准
&lt;/h2&gt;&lt;p&gt;问题多半不在桥接层。先回 Xiaomi Home 或米家集成里看：HA 页面能不能控制，状态会不会变，实体有没有被禁用。HA 侧不稳，桥接写得再好也没办法。&lt;/p&gt;
&lt;h2 id=&#34;控制失败但发现成功&#34;&gt;控制失败但发现成功
&lt;/h2&gt;&lt;p&gt;能力没勾全，或设备类型映射不对。空调要有温度、模式、风速这些能力；窗帘要有打开、关闭能力。回集成选项里改完，再让小度重新发现。&lt;/p&gt;
&lt;h2 id=&#34;状态不同步&#34;&gt;状态不同步
&lt;/h2&gt;&lt;p&gt;先确认这台设备是可控设备，只读传感器本来就不主动上报。再手动动一下设备，看日志里有没有状态推送的记录。&lt;/p&gt;
&lt;h1 id=&#34;最后&#34;&gt;最后
&lt;/h1&gt;&lt;p&gt;这套方案的核心是让 HA 当统一中间层。桥接层把 HA 设备按 DuerOS 的语义组装好交给小度，状态变化也主动往小度推。小度 App 能拿到较新的状态，浴霸这类多实体设备也能当成一台设备控制。&lt;/p&gt;
&lt;p&gt;设备命名和房间分好，语音体验会顺很多。先暴露少量设备测试，稳定后再慢慢加。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>xiaodu bridge 折腾记：把米家和其他 HA 设备接进小度</title>
        <link>https://blog.huirongis.me/post/ha-xiaodu-connect-home-assistant-devices/</link>
        <pubDate>Fri, 28 Aug 2026 01:00:00 +0800</pubDate>
        
        <guid>https://blog.huirongis.me/post/ha-xiaodu-connect-home-assistant-devices/</guid>
        <description>&lt;p&gt;最近在整理家里的设备，米家有一部分，Zigbee有一部分，空调、窗帘、传感器又散在不同集成里。Home Assistant这边倒是能统一看，自动化也好写，但小度这边一直不够听话：有些设备发现不了，有些能力不全，状态还经常对不上。&lt;/p&gt;
&lt;p&gt;后来我把 HA 当中间层来用，做了一个自定义集成 &lt;code&gt;xiaodu bridge&lt;/code&gt;（domain &lt;code&gt;xiaodu_bridge&lt;/code&gt;）。简单说，它把 HA 里的设备映射成 DuerOS 认识的设备，再交给小度发现和控制。这个集成早先叫 &lt;code&gt;ha-xiaodu&lt;/code&gt;，后来改名并换了仓库，下面统一用新名字。链路大概是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;米家 / Zigbee / 蓝牙 / Matter / 其他 HA 集成
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Home Assistant 实体和房间
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;xiaodu bridge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;小度云端
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;小度音箱 / 小度 App
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;xiaodu bridge&lt;/code&gt; 的仓库在这里：&lt;a class=&#34;link&#34; href=&#34;https://github.com/Jackroyal/xiaodu-bridge&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/Jackroyal/xiaodu-bridge&lt;/a&gt;，已经收录进 HACS 默认商店。&lt;/p&gt;
&lt;p&gt;我建议不要一上来就改小度配置，先把 HA 里的设备搞稳，再装桥接层，最后解决小度云端访问 HA 的问题。公网入口这篇用 DDNS 举例；内网穿透后面有空再补。&lt;/p&gt;
&lt;h1 id=&#34;第一步先把设备接进-ha&#34;&gt;第一步：先把设备接进 HA
&lt;/h1&gt;&lt;p&gt;这一步比后面所有配置都重要。&lt;code&gt;xiaodu bridge&lt;/code&gt; 暴露的是 HA 里已有的实体。如果 HA 里点不开、状态不动、实体名乱七八糟，小度那边只会更乱。&lt;/p&gt;
&lt;h2 id=&#34;接米家&#34;&gt;接米家
&lt;/h2&gt;&lt;p&gt;我这里用 HA 的 Xiaomi Home 集成接米家。流程不复杂：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在 HACS 里安装 Xiaomi Home。&lt;/li&gt;
&lt;li&gt;打开 &lt;strong&gt;设置 -&amp;gt; 设备与服务 -&amp;gt; 添加集成&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;搜索 Xiaomi Home，登录米家账号。&lt;/li&gt;
&lt;li&gt;选择家庭，等设备同步进来。&lt;/li&gt;
&lt;li&gt;先在 HA 页面里手动开几次灯、空调、插座，确认状态能变。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;接完别急着下一步，先在 HA 设备页里看一遍。Xiaomi Home 可以直接把米家里的设备名称和房间同步过来，所以大部分设备不用在 HA 里重新起名。要确认的主要是两件事：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1. 名字改成适合说话的。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   比如：客厅吸顶灯、卧室空调、书房插座。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2. 房间分配。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   客厅就是客厅，卧室就是卧室。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   后面开小度房间同步会省很多事。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果发现某个设备没带上米家名称，或者变成了 &lt;code&gt;switch.switch_1&lt;/code&gt; 这种不好念的名字，再回米家 App 里改名，或者直接在 HA 里调整。这种名字直接丢给小度，语音体验会很差。&lt;/p&gt;
&lt;h2 id=&#34;其他设备怎么接&#34;&gt;其他设备怎么接
&lt;/h2&gt;&lt;p&gt;Zigbee2MQTT、ZHA、Matter、品牌集成都行，关键是它们最后要变成 HA 能控制的标准实体。&lt;/p&gt;
&lt;p&gt;常见对应关系大概这样：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;light          -&amp;gt; 开关、亮度、色温、颜色
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;switch         -&amp;gt; 开关
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;climate        -&amp;gt; 空调开关、温度、模式、风速
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cover          -&amp;gt; 窗帘打开、关闭、位置
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fan            -&amp;gt; 风扇开关、风速、模式
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sensor         -&amp;gt; 温度、湿度
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vacuum         -&amp;gt; 扫地机启动、暂停、回充
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;media_player   -&amp;gt; 播放、暂停、音量
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;有些设备没有现成的小度能力，比如某个自定义场景或私有协议设备。能包装成 &lt;code&gt;switch&lt;/code&gt; 的，就先在 HA 里做成一个开关实体，再让小度控制这个开关。不能包装的，就别硬塞进去。&lt;/p&gt;
&lt;h1 id=&#34;安装-xiaodu-bridge&#34;&gt;安装 xiaodu bridge
&lt;/h1&gt;&lt;p&gt;装法有两种。用 HACS 方便一点，手动复制更适合调试。&lt;/p&gt;
&lt;h2 id=&#34;hacs-安装&#34;&gt;HACS 安装
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;xiaodu bridge&lt;/code&gt; 已经进了 HACS 默认商店，不用再加自定义仓库（本文按 v0.9.17 写）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;HACS → Integrations，搜索 &lt;strong&gt;xiaodu bridge&lt;/strong&gt;，下载。&lt;/li&gt;
&lt;li&gt;重启 HA。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;手动安装&#34;&gt;手动安装
&lt;/h2&gt;&lt;p&gt;先把仓库拉下来，然后把 &lt;code&gt;custom_components/xiaodu_bridge&lt;/code&gt; 整个目录复制到 HA 的 &lt;code&gt;custom_components&lt;/code&gt; 下面：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git clone https://github.com/Jackroyal/xiaodu-bridge.git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cp -R xiaodu-bridge/custom_components/xiaodu_bridge /config/custom_components/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;用 HAOS 的 Terminal and SSH 时，也可以直接从电脑传：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;scp -r custom_components/xiaodu_bridge root@192.168.1.10:/config/custom_components/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里面的 &lt;code&gt;192.168.1.10&lt;/code&gt; 是我举的例子，换成你自己的 HAOS 内网地址。&lt;/p&gt;
&lt;p&gt;复制完检查一下路径：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;正确：/config/custom_components/xiaodu_bridge/manifest.json
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;错误：/config/custom_components/xiaodu_bridge/xiaodu_bridge/manifest.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;多套一层是老问题。确认没套错后重启：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ha core restart
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;小度为什么必须能访问-ha&#34;&gt;小度为什么必须能访问 HA
&lt;/h1&gt;&lt;p&gt;正式接入时，DuerOS 云端会回调 &lt;code&gt;xiaodu bridge&lt;/code&gt; 提供的几个 HTTPS 接口：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/api/xiaodu/oauth/authorize
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/api/xiaodu/oauth/token
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/api/xiaodu/service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;所以纯内网地址不能完成正式接入。小度云端不是运行在你家局域网里的，它必须能从外面访问到你 HA 里的这些路径。&lt;/p&gt;
&lt;p&gt;我的结构是这样：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;小度云端
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -&amp;gt; 公网域名
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -&amp;gt; 路由器端口转发
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -&amp;gt; HAOS 反向代理
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -&amp;gt; HA Core 8123
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -&amp;gt; xiaodu bridge
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;用-ddns-暴露公网入口&#34;&gt;用 DDNS 暴露公网入口
&lt;/h1&gt;&lt;p&gt;我这次走的是「有公网 IPv4 + DDNS」的路线。它不是唯一方案，只是对我来说最直接。没有公网 IP 的话可以看内网穿透，这部分这篇先不写。&lt;/p&gt;
&lt;h2 id=&#34;1-确认真的有公网-ipv4&#34;&gt;1. 确认真的有公网 IPv4
&lt;/h2&gt;&lt;p&gt;去路由器看 WAN IP，再用手机流量查一下出口 IP。两边一致才算比较靠谱。&lt;/p&gt;
&lt;p&gt;如果路由器 WAN IP 是 &lt;code&gt;100.x.x.x&lt;/code&gt;、&lt;code&gt;10.x.x.x&lt;/code&gt;、&lt;code&gt;172.16.x.x&lt;/code&gt; 或者 &lt;code&gt;192.168.x.x&lt;/code&gt;，基本就是运营商侧又套了一层，不是能直接入站的公网 IP。这种就先别折腾端口转发了。&lt;/p&gt;
&lt;h2 id=&#34;2-配域名和-ddns&#34;&gt;2. 配域名和 DDNS
&lt;/h2&gt;&lt;p&gt;准备一个自己的域名，比如 &lt;code&gt;ha.example.com&lt;/code&gt;。DNS 里加一条 A 记录：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ha.example.com.    A    你的公网IP
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;公网 IP 会变的话，就配 DDNS。路由器自带 DDNS、NAS 上的脚本、Cloudflare API 更新都可以，关键是 IP 变了以后域名要跟着变。&lt;/p&gt;
&lt;p&gt;测试阶段建议 DNS 用“仅 DNS”，别急着套 CDN，不然证书和回源问题会混在一起，排错会麻烦很多。&lt;/p&gt;
&lt;h2 id=&#34;3-端口转发&#34;&gt;3. 端口转发
&lt;/h2&gt;&lt;p&gt;国内家宽对 &lt;code&gt;80&lt;/code&gt; 和 &lt;code&gt;443&lt;/code&gt; 的入站管控挺常见，有的地区直接拦，有的时好时坏。所以我没把公网入口放在 &lt;code&gt;443&lt;/code&gt;，用的是 &lt;code&gt;8443&lt;/code&gt; 这种非标端口：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;外部协议：TCP
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;外部端口：8443
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;内部目标：HAOS 主机 IP，例如 192.168.1.10
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;内部端口：443
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;外面的 &lt;code&gt;8443&lt;/code&gt; 是给公网访问用的；里面的 &lt;code&gt;443&lt;/code&gt; 还是给 HAOS 反向代理监听。你的反向代理如果也能改成其他监听端口，也可以自己调整，但公网那一段尽量别用 &lt;code&gt;443&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;另外，不要把 HA 的 &lt;code&gt;8123&lt;/code&gt; 直接暴露出去。公网入口统一走 HTTPS，后面由反向代理转到 HA Core 的 &lt;code&gt;8123&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;4-证书和反向代理&#34;&gt;4. 证书和反向代理
&lt;/h2&gt;&lt;p&gt;HAOS 上可以用 Let&amp;rsquo;s Encrypt 和 NGINX SSL proxy。我用 DNS 校验，这样不依赖 80 端口。这两个 add-on 的证书目录和文件名默认就是配套的：Let&amp;rsquo;s Encrypt 签出来的证书放到 &lt;code&gt;/ssl&lt;/code&gt;，NGINX SSL proxy 默认也从 &lt;code&gt;/ssl&lt;/code&gt; 读同名文件。所以装完不需要手动挪证书，也不用改证书路径。&lt;/p&gt;
&lt;p&gt;Cloudflare DNS 的例子大概是这样：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;challenge&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;dns&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;dns&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;provider&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;dns-cloudflare&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;cloudflare_api_token&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;&amp;lt;你的Cloudflare API Token&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;domains&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#ae81ff&#34;&gt;ha.example.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;email&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;&amp;lt;你的邮箱&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;NGINX SSL proxy 只需要配域名和其他选项：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;domain&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;ha.example.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;hsts&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;max-age=31536000; includeSubDomains&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;client_max_body_size_megabytes&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;cloudflare&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;为了少暴露东西，我建议反向代理只放行小度需要的路径，其他公网请求直接 404。至少要放行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/api/xiaodu
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/api/xiaodu/oauth/authorize
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/api/xiaodu/oauth/token
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/api/xiaodu/service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果 HA 里还有别的 OAuth 回调路径，再按需放行，不要为了省事把整个 HA 管理页面开放到公网。&lt;/p&gt;
&lt;p&gt;然后到 HA 的 &lt;strong&gt;设置 -&amp;gt; 系统 -&amp;gt; 网络&lt;/strong&gt; 里设置外部地址：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;https://ha.example.com:8443
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果外网请求返回 400，HA 日志里又出现 forwarded 或 trusted proxy 相关内容，多半是反向代理网段没进 &lt;code&gt;trusted_proxies&lt;/code&gt;。把 NGINX 所在网段加进去，并开启 &lt;code&gt;use_x_forwarded_for&lt;/code&gt;。&lt;/p&gt;
&lt;h1 id=&#34;在小度后台建技能&#34;&gt;在小度后台建技能
&lt;/h1&gt;&lt;p&gt;登录小度开发者平台，创建一个智能家居技能。这里会用到几样东西：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;botId                 小度后台基础信息里的技能 ID
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;回调地址               小度平台生成的回调地址
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Client_Id             自己定义
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ClientSecret          自己定义
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;授权地址               HA 里的授权地址
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Token地址              HA 里的 token 地址
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;WebService            HA 里的小度服务地址
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;假设公网地址是 &lt;code&gt;https://ha.example.com:8443&lt;/code&gt;，那三个 HA 地址就是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;https://ha.example.com:8443/api/xiaodu/oauth/authorize
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;https://ha.example.com:8443/api/xiaodu/oauth/token
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;https://ha.example.com:8443/api/xiaodu/service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Client_Id&lt;/code&gt; 和 &lt;code&gt;ClientSecret&lt;/code&gt; 不是百度后台分配的，是自己定义，然后把两边配一致。Secret 别太短，别用 &lt;code&gt;123456&lt;/code&gt; 这种。&lt;/p&gt;
&lt;p&gt;还有一个容易搞反的地方：&lt;code&gt;回调地址&lt;/code&gt; 不是你的 HA 地址，而是小度平台生成出来的地址。它要填到 HA 集成里。&lt;/p&gt;
&lt;h1 id=&#34;在-ha-里配置-xiaodu-bridge&#34;&gt;在 HA 里配置 xiaodu bridge
&lt;/h1&gt;&lt;p&gt;重启 HA 后，打开：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;设置 -&amp;gt; 设备与服务 -&amp;gt; 添加集成 -&amp;gt; xiaodu bridge
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;按下面这些填：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;界面字段&lt;/th&gt;
          &lt;th&gt;填什么&lt;/th&gt;
          &lt;th&gt;示例&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Client_Id&lt;/td&gt;
          &lt;td&gt;自定义客户端 ID&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;dueros_xxx&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;ClientSecret&lt;/td&gt;
          &lt;td&gt;自定义随机密钥&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;&amp;lt;长随机字符串&amp;gt;&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;小度技能ID（botId，控制台基础信息页可见）&lt;/td&gt;
          &lt;td&gt;小度后台技能 ID&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;12345678&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;回调地址（小度平台生成，不可修改）&lt;/td&gt;
          &lt;td&gt;小度平台生成的地址&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;https://xiaodu.baidu.com/...&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;公网访问地址（HTTPS）&lt;/td&gt;
          &lt;td&gt;HA 公网基础地址&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;https://ha.example.com:8443&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;保存后集成会把授权地址、Token地址、WebService 显示出来。再对照小度后台检查一遍，尤其是端口：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;https://ha.example.com:8443/...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;用 &lt;code&gt;8443&lt;/code&gt; 后，所有相关地址都要带 &lt;code&gt;:8443&lt;/code&gt;。不能有些带端口，有些不带。&lt;/p&gt;
&lt;h1 id=&#34;选择要暴露给小度的设备&#34;&gt;选择要暴露给小度的设备
&lt;/h1&gt;&lt;p&gt;添加成功后，打开集成条目 →「配置」，会进入 &lt;strong&gt;小度中枢&lt;/strong&gt; 页。这里我建议别一次全选。&lt;/p&gt;
&lt;p&gt;注意：从 v0.9.15 起，设备暴露改成按需选择。全新安装、或者从没保存过设备选项的实例，默认不会向小度发送任何设备，必须在这里选好并保存。&lt;/p&gt;
&lt;p&gt;先拿两三台设备练手，比如客厅灯、卧室空调、一个插座。流程是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;点「添加 / 移除设备」。&lt;/li&gt;
&lt;li&gt;选择要暴露的 HA 设备，顺便决定要不要「同步 HA 房间到小度」。&lt;/li&gt;
&lt;li&gt;点进某个设备，先选「设备能力」勾选能力；需要时再进「高级配置」限制能力、隐藏实体、绑定语义角色或改小度侧的展示名。&lt;/li&gt;
&lt;li&gt;保存后让小度重新发现。&lt;/li&gt;
&lt;li&gt;用小度后台的模拟测试试一遍。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;能力大概可以这样理解：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;灯：开关、亮度、色温、颜色
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;插座：开关
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;空调：开关、目标温度、模式、风速
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;窗帘：打开、关闭、位置
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;传感器：温度、湿度
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;扫地机：启动、暂停、回充
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;开关能力始终启用，不能取消。温湿度这种只读能力按需勾。你不需要把 HA 里的每个实体都丢给小度，暴露得越精准，后面误触发越少。&lt;/p&gt;
&lt;h1 id=&#34;测试&#34;&gt;测试
&lt;/h1&gt;&lt;p&gt;我一般按这个顺序来：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;小度开发者后台触发设备发现。&lt;/li&gt;
&lt;li&gt;看设备有没有出现在小度侧。&lt;/li&gt;
&lt;li&gt;查询一个温湿度传感器。&lt;/li&gt;
&lt;li&gt;打开一个灯或插座。&lt;/li&gt;
&lt;li&gt;关掉它。&lt;/li&gt;
&lt;li&gt;再用音箱和 App 试试真实语音。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;HAOS 上可以看日志：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ha core logs -f | grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Xiaodu access&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;成功的发现请求会看到类似这样的内容：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kind=dueros
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;namespace=DuerOS.ConnectedHome.Discovery
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;name=DiscoverAppliancesRequest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;result=DiscoverAppliancesResponse
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;status=200
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果这里连请求都没有，就别急着改 HA 配置，先查域名、端口转发、证书和反向代理。&lt;/p&gt;
&lt;p&gt;语音可以试这些：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;小度小度，打开客厅灯。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;小度小度，把卧室空调调到 26 度。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;小度小度，关闭书房插座。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;小度小度，客厅温度是多少？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;我踩到的坑&#34;&gt;我踩到的坑
&lt;/h1&gt;&lt;h2 id=&#34;集成搜索不到&#34;&gt;集成搜索不到
&lt;/h2&gt;&lt;p&gt;先看目录有没有多套一层：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;错误：/config/custom_components/xiaodu_bridge/xiaodu_bridge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;正确：/config/custom_components/xiaodu_bridge
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;再看 &lt;code&gt;manifest.json&lt;/code&gt; 是否存在，然后重启 HA。&lt;/p&gt;
&lt;h2 id=&#34;ha-里正常小度发现不到&#34;&gt;HA 里正常，小度发现不到
&lt;/h2&gt;&lt;p&gt;按顺序查：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1. 小度后台 WebService 地址对不对。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2. 地址里的端口有没有少。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3. 公网能不能访问 HA。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4. 反向代理有没有放行 /api/xiaodu。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;5. HA 集成里有没有选中设备。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;6. HA 日志里有没有 Xiaodu access。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;别只盯音箱。正式链路里，小度云端访问不到 HA，音箱喊破天也没用。&lt;/p&gt;
&lt;h2 id=&#34;米家设备状态不准&#34;&gt;米家设备状态不准
&lt;/h2&gt;&lt;p&gt;这时候问题多半不在 &lt;code&gt;xiaodu bridge&lt;/code&gt;。先回 Xiaomi Home 或米家集成里看：HA 页面能不能控制，状态会不会变，实体有没有被禁用。HA 侧不稳定，桥接层写得再好也没办法。&lt;/p&gt;
&lt;h2 id=&#34;授权页打不开&#34;&gt;授权页打不开
&lt;/h2&gt;&lt;p&gt;多半是公网入口没通。可以从外面测：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -I https://ha.example.com:8443/api/xiaodu/service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;能拿到 HTTP 状态码，说明入口至少通了。TLS 都失败的话，先解决证书、DNS 和端口转发。&lt;/p&gt;
&lt;h2 id=&#34;控制失败但发现成功&#34;&gt;控制失败但发现成功
&lt;/h2&gt;&lt;p&gt;这类多半是能力没勾全，或者设备类型映射得不对。比如空调要有温度、模式、风速这些能力；窗帘要有打开、关闭能力。回集成选项里改完，再让小度重新发现。&lt;/p&gt;
&lt;h1 id=&#34;安全上要注意&#34;&gt;安全上要注意
&lt;/h1&gt;&lt;p&gt;公网入口开了以后，就别图省事了：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1. 只转发需要的非标端口，比如 8443。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2. 不把 HA 管理页面对公网开放。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3. ClientSecret 用长随机串。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4. Cloudflare Token 只给必要权限。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;5. Token、私钥、真实 IP 别提交到 Git。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;6. 定期更新 HA、Xiaomi Home、xiaodu bridge 和加载项。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;最后&#34;&gt;最后
&lt;/h1&gt;&lt;p&gt;这套东西的核心不是“米家转小度”，而是让 HA 当家里的统一中间层。米家、Zigbee、Matter、其他品牌集成都先进 HA，&lt;code&gt;xiaodu bridge&lt;/code&gt; 再把这些实体交给小度。&lt;/p&gt;
&lt;p&gt;设备命名和房间分好，后面语音体验会顺很多。先暴露少量设备测试，稳定后再慢慢加。&lt;/p&gt;
&lt;p&gt;这篇先记录到这，内网穿透那部分等后面补。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Archives</title>
        <link>https://blog.huirongis.me/page/archives/</link>
        <pubDate>Tue, 28 May 2019 00:00:00 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/page/archives/</guid>
        <description></description>
        </item>
        <item>
        <title>php学习笔记(3.6)--PHP中的引用</title>
        <link>https://blog.huirongis.me/post/php-learn-note-3-6/</link>
        <pubDate>Sun, 08 Jul 2018 17:40:28 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/php-learn-note-3-6/</guid>
        <description>&lt;p&gt;最近再看CI源码, 刚好有碰到引用相关问题, 索性又研究了下.&lt;/p&gt;
&lt;h1 id=&#34;1-什么是引用&#34;&gt;1 什么是引用
&lt;/h1&gt;&lt;p&gt;引用,第一感觉就是想到C语言中的指针,两个变量指向同一个内存地址.但是php中的引用其实应该是别名, 可以类比的是linux系统中的硬链接,两个文件名实际指向同一个文件.&lt;/p&gt;
&lt;h1 id=&#34;2-引用传值&#34;&gt;2 引用传值
&lt;/h1&gt;&lt;p&gt;我们在函数传参的时候可能会用到引用.在不同给的php版本中,写法也不同.&lt;/p&gt;
&lt;h2 id=&#34;21-例如在php52中我们可能用到以下写法&#34;&gt;2.1 例如,在php5.2中,我们可能用到以下写法.
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt;($var) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  $var&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;$a);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;$a:&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;$a&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;br&amp;gt;&amp;#34;&lt;/span&gt;;&lt;span style=&#34;color:#75715e&#34;&gt;//输出$a:1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但是在php5.3+中就不推荐这种写法了5.3会报warning,在更高版本中,会报fatal错误&lt;code&gt;Call-time pass-by-reference has been removed&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;22-推荐的写法是在定义函数的时候如果是引用在参数声明处直接标记为引用&#34;&gt;2.2 推荐的写法是,在定义函数的时候如果是引用,在参数声明处直接标记为引用.
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//在定义函数时,直接声明参数为引用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;$var) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  $var&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt;($a);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;$a:&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;$a&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;br&amp;gt;&amp;#34;&lt;/span&gt;;&lt;span style=&#34;color:#75715e&#34;&gt;//输出$a:1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;3-引用返回&#34;&gt;3 引用返回
&lt;/h1&gt;&lt;p&gt;除了引用传值,还有一种常见的情况是引用返回.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;$var) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  $var&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; $var;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$b&lt;span style=&#34;color:#f92672&#34;&gt;=&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt;($a);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$b&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;$a:&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;$a&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;br&amp;gt;&amp;#34;&lt;/span&gt;;&lt;span style=&#34;color:#75715e&#34;&gt;//输出$a:4
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;$b:&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;$b&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;br&amp;gt;&amp;#34;&lt;/span&gt;;&lt;span style=&#34;color:#75715e&#34;&gt;//输出$b:4
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;此处需要注意的是,函数定义处需要显示声明&lt;code&gt;function &amp;amp;foo&lt;/code&gt;,在调用函数的时候也需要显示声明&lt;code&gt;$b=&amp;amp;foo($a)&lt;/code&gt;.这个跟上面讲到的引用传值不同.
那么如果我调用函数的时候如果不加&lt;code&gt;&amp;amp;&lt;/code&gt;调用,会怎么样呢?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;$var) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  $var&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; $var;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$b&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt;($a);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$b&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;$a:&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;$a&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;br&amp;gt;&amp;#34;&lt;/span&gt;;&lt;span style=&#34;color:#75715e&#34;&gt;//输出$a:1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;$b:&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;$b&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;br&amp;gt;&amp;#34;&lt;/span&gt;;&lt;span style=&#34;color:#75715e&#34;&gt;//输出$b:4
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面例子中的引用传值只是为了突显这种差别. 也可以用对象来表现这个差别.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; $value &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;42&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;getValue&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; $this&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;value&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$obj &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;foo&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$myValue &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;$obj&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;getValue&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$obj&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;value&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; $myValue; &lt;span style=&#34;color:#75715e&#34;&gt;//输出2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面&lt;code&gt;public function &amp;amp;getValue() {&lt;/code&gt;或&lt;code&gt;$myValue = &amp;amp;$obj-&amp;gt;getValue();&lt;/code&gt;中的&lt;code&gt;&amp;amp;&lt;/code&gt;,无论少了谁,都不是引用返回,会导致最后输出&lt;code&gt;$myValue=42&lt;/code&gt;&lt;/p&gt;
&lt;h1 id=&#34;4-对象的赋值和传值&#34;&gt;4 对象的赋值和传值
&lt;/h1&gt;&lt;p&gt;在php5中,对象的赋值和参数传递并不是引用传递,实际传递的是对象标识符的拷贝.
上面已经讲到php中的引用其实是别名,对于对象而言,php5中对象变量并不直接指向对象内容,而是保存了一个对象标识符,通过标识符来访问对象的内容,在将对象变量赋值的时候,其实是将两个变量指向同一个标识符,下面看例子.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; $foo &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$b &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; $a;     &lt;span style=&#34;color:#75715e&#34;&gt;// $a ,$b都是同一个标识符的拷贝
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;             &lt;span style=&#34;color:#75715e&#34;&gt;// ($a) = ($b) = &amp;lt;id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             $c &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$d &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;$c;    &lt;span style=&#34;color:#75715e&#34;&gt;// $c ,$d是引用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;             &lt;span style=&#34;color:#75715e&#34;&gt;// ($c,$d) = &amp;lt;id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面的例子比较清晰表明了2者的区别,总结下:
对于普通变量而言:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$b &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;$a;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;变量$a直接指向内容,当产生引用(即别名),那么&lt;code&gt;$a&lt;/code&gt;和&lt;code&gt;$b&lt;/code&gt;都指向同一个内容;
对于对象而言,中间隔着标识符:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; $foo &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$b &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;$a;    &lt;span style=&#34;color:#75715e&#34;&gt;// $a ,$b是引用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;$c &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; $a;     &lt;span style=&#34;color:#75715e&#34;&gt;// $c和$a保存的是同一个标识符,保存在不同的地方
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;通俗的讲,我们可以把标识符理解为门牌号,$a和$c中保存的是同样的门牌号,但是并不是记录在同一个地方,是相同内容的拷贝,他们都可以找到同一个人;而$a和$b只是别名的关系,它俩实际指向同一个,记录在同一个地方.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$a的小本本记录门牌号A1234
$b的小本本(实际和$a是同一个小本本,彼此互为别名)记录门牌号A1234
$c的小本本记录门牌号A1234&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;一图胜千言&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;  $b ----&amp;gt;+      
                |
  $a ----&amp;gt;+
                |  
                v   
          +--------+      
          | object id   |--------+ 
          +--------+               |
                                          v
          +--------+      +--------------+
  $c --&amp;gt;| object id  | ---&amp;gt; | object(Class A) |
          +--------+      +--------------+
 
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;ol&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;http://php.net/manual/zh/language.references.pass.php&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;php引用传递&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;http://php.net/manual/zh/language.oop5.references.php&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;对象和引用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://segmentfault.com/a/1190000002928594&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;在PHP中对象真的是按引用传递的吗&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
        </item>
        <item>
        <title>修复ubuntu终端中文显示和输入的问题</title>
        <link>https://blog.huirongis.me/post/repair-chinese-input-in-ubuntu/</link>
        <pubDate>Mon, 24 Apr 2017 13:37:01 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/repair-chinese-input-in-ubuntu/</guid>
        <description>&lt;p&gt;我在管理服务器的时候,一般在win下面使用xshell和xftp两个软件,来进行管理和上传文件.不过一直有个头疼的问题:如果文件名是中文的,上传之后,在ftp软件中看到的是正常的,在xshell终端中看到的却是乱码;而且,在xshell中无法输入中文,所以我在vi中修改文件的时候一般只使用英文.&lt;/p&gt;
&lt;p&gt;昨晚没事,就查了一下资料,修复了这个问题.&lt;/p&gt;
&lt;h1 id=&#34;1-目标&#34;&gt;1 目标
&lt;/h1&gt;&lt;p&gt;本文的目标主要是修复中文文件名乱码和中文输入的问题,本文的目标不是把整个系统的所有语言体系都改成中文,只是单纯的修复中文输入问题和中文文件名显示问题.&lt;/p&gt;
&lt;h1 id=&#34;2-环境&#34;&gt;2 环境
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;服务器环境&lt;/strong&gt;: Ubuntu Server 16.04 lts
&lt;strong&gt;本地环境&lt;/strong&gt;: windows7
&lt;strong&gt;软件环境&lt;/strong&gt;: Xshell 和 Xftp&lt;/p&gt;
&lt;h1 id=&#34;3-修改配置&#34;&gt;3 修改配置
&lt;/h1&gt;&lt;p&gt;与中文编码相关的配置主要包括: 本地编码和服务器编码.我们首先设置服务器端编码:&lt;/p&gt;
&lt;h2 id=&#34;31-服务器编码配置&#34;&gt;3.1 服务器编码配置
&lt;/h2&gt;&lt;p&gt;首先,我们使用xshell连接登录服务器,然后在终端中输入&lt;code&gt;locale&lt;/code&gt;命令,得到结果如下:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ locale
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LANG&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LANGUAGE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;C:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_CTYPE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_NUMERIC&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_TIME&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_COLLATE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_MONETARY&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_MESSAGES&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_PAPER&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_NAME&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_ADDRESS&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_TELEPHONE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_MEASUREMENT&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_IDENTIFICATION&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_ALL&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;各个选项的含义如下:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;语言符号及其分类(LC_CTYPE)&lt;/li&gt;
&lt;li&gt;数字(LC_NUMERIC)&lt;/li&gt;
&lt;li&gt;比较和排序习惯(LC_COLLATE)&lt;/li&gt;
&lt;li&gt;时间显示格式(LC_TIME)&lt;/li&gt;
&lt;li&gt;货币单位(LC_MONETARY)&lt;/li&gt;
&lt;li&gt;信息主要是提示信息,错误信息, 状态信息, 标题, 标签, 按钮和菜单等(LC_MESSAGES)&lt;/li&gt;
&lt;li&gt;姓名书写方式(LC_NAME)&lt;/li&gt;
&lt;li&gt;地址书写方式(LC_ADDRESS)&lt;/li&gt;
&lt;li&gt;电话号码书写方式(LC_TELEPHONE)&lt;/li&gt;
&lt;li&gt;度量衡表达方式(LC_MEASUREMENT)&lt;/li&gt;
&lt;li&gt;默认纸张尺寸大小(LC_PAPER)&lt;/li&gt;
&lt;li&gt;对locale自身包含信息的概述(LC_IDENTIFICATION)。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于&lt;code&gt;locale&lt;/code&gt;更多的信息,请查看&lt;a class=&#34;link&#34; href=&#34;http://wiki.ubuntu.org.cn/Locale&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Locale-wiki&lt;/a&gt;
我们要修复的是中文文件名的显示和中文输入的问题,所以我们接下来只需要设置&lt;code&gt;LC_CTYPE&lt;/code&gt;即可.&lt;/p&gt;
&lt;p&gt;查看系统支持的编码方式:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;locale -a
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;看看输出内容中是否包含&lt;code&gt;zh_CN.utf-8&lt;/code&gt;,如果不包含的话,我们需要添加这个配置项&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo locale-gen zh_CN.utf-8
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;修改后,我的输出内容如下,已经包含&lt;code&gt;zh_CN.utf-8&lt;/code&gt;
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1fexql3wkdej2076047744.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;查看系统支持的编码方式&#34;
	
	
&gt;
接下来,修改&lt;code&gt;LC_CTYPE&lt;/code&gt;的值,使用&lt;code&gt;export LC_CTYPE=&#39;zh_CN.UTF-8&#39;&lt;/code&gt;,命令来修改.
直接执行&lt;code&gt;export LC_CTYPE=&#39;zh_CN.UTF-8&#39;&lt;/code&gt;那么只对当前会话有效,
&lt;strong&gt;所有用户(永久)&lt;/strong&gt;:修改/etc/profile
&lt;strong&gt;当前用户(永久)&lt;/strong&gt;:修改~/.bashrc&lt;/p&gt;
&lt;p&gt;建议直接修改&lt;code&gt;/etc/profile&lt;/code&gt;文件,这样所有用户都可以使用.
修改完成后,退出登录,重新登录一次,再输入&lt;code&gt;locale&lt;/code&gt;命令,可以得到如下输出:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LANG&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LANGUAGE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;C:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_CTYPE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;zh_CN.UTF-8
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_NUMERIC&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_TIME&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_COLLATE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_MONETARY&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_MESSAGES&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_PAPER&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_NAME&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_ADDRESS&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_TELEPHONE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_MEASUREMENT&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_IDENTIFICATION&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;POSIX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LC_ALL&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;应该就可以输入中文了&lt;/p&gt;
&lt;h2 id=&#34;32-本地配置&#34;&gt;3.2 本地配置
&lt;/h2&gt;&lt;p&gt;在windows中,中文的默认编码是GBK,所以为了避免出现在ftp中看着正常,在xshell中看着乱码的问题.我们要修改xftp中的编码方式.打开xftp,文件-&amp;gt;属性-&amp;gt;选项,勾选上&lt;code&gt;使用UTF-8编码&lt;/code&gt;.
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1fexreyc5kyj20c007wt8w.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;修改xftp编码方式&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;33-编码转换&#34;&gt;3.3 编码转换
&lt;/h2&gt;&lt;p&gt;上面的修改完成后,基本可以解决之前提到的目标.新上传的文件肯定是正常的,但是之前上传的文件依旧是乱码,所以我们需要使用工具转换一下.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt-get install convmv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;用法很简单:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;convmv -f GBK -t UTF-8 --notest ./*
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中,&lt;code&gt;-f&lt;/code&gt;表示源编码;&lt;code&gt;-t&lt;/code&gt;表示目标编码;如果没有&lt;code&gt;--notest&lt;/code&gt;选项,这条命令只会检测,不会执行;后面跟着需要操作的文件目录;如果需要递归执行,可以加上&lt;code&gt;-r&lt;/code&gt;选项.&lt;/p&gt;
&lt;p&gt;打完收工&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;http://wiki.ubuntu.org.cn/Locale&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Locale-wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://segmentfault.com/q/1010000000150673&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MacOS用iTerm连接到Linux上，不能输入中文&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>将hexo部署到自己的个人服务器上</title>
        <link>https://blog.huirongis.me/post/deploy-hexo-in-my-own-vps/</link>
        <pubDate>Sat, 08 Apr 2017 19:22:22 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/deploy-hexo-in-my-own-vps/</guid>
        <description>&lt;blockquote&gt;
&lt;p&gt;本文假设你已经配置好了hexo了,这是前提&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;前面两篇文章主要是用来配置自己的服务器.服务器部署完成后,后面就可以开始写博客了.但是每次&lt;code&gt;hexo d&lt;/code&gt;推送到gihub的服务器上了,还需要手动将文件复制到自己的服务器对应网站的根目录,对的,要手动,当然不能忍.&lt;/p&gt;
&lt;h1 id=&#34;1-ugly的解决办法&#34;&gt;1 ugly的解决办法
&lt;/h1&gt;&lt;p&gt;于是我写了一个脚本,在服务器上定时去访问我的github,如果检测到文件有变动,就把github的内容clone到服务器上,然后再布置到网站根目录.
代码很简单,就这几行.主要是检测&lt;code&gt;/archives/index.html&lt;/code&gt;这个文件的大小是否变化了,选择它,是由于这个文件较小,而且每次发布新文章大小都会发生变化.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;cd ~/blogsync
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;ls -l github.json| awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $5}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -o github.json  https://raw.githubusercontent.com/huirong/huirong.github.io/master/archives/index.html
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;newlength&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;ls -l github.json| awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $5}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;test $length -eq $newlength &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; exit &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;#if same so quit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git clone https://github.com/huirong/huirong.github.io.git huirongis_me
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rm -fr ~/www/huirongis_me
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mv huirongis_me ~/www/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样搞法,是不需要手动了,但是做不到实时,而且,如果你没有新增或删减文章,其他的改动,可能不会反应在&lt;code&gt;/archives/index.html&lt;/code&gt;,那他就不会自动去更新了.&lt;/p&gt;
&lt;h1 id=&#34;2-完美的搞法&#34;&gt;2 完美的搞法
&lt;/h1&gt;&lt;p&gt;既然有ugly的解决方法,自然有完美的解决方法.本文主要是参考 &lt;a class=&#34;link&#34; href=&#34;http://www.swiftyper.com/2016/04/17/deploy-hexo-with-git-hook/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;使用 Git Hook 自动部署 Hexo 到个人 VPS&lt;/a&gt;.
这个方法的原理,用一句话总结就是:&lt;strong&gt;在自己的服务器上搭建一个git服务器,然后依靠&lt;code&gt;git hook&lt;/code&gt;程序,将git仓库代码更新到自己的网站根目录&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;21-在vps上安装git&#34;&gt;2.1 在vps上安装git
&lt;/h2&gt;&lt;p&gt;我的服务器是ubuntu 16.04 lts,安装git服务非常简单&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt-get install git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;22-创建git用户&#34;&gt;2.2 创建git用户
&lt;/h2&gt;&lt;p&gt;这一步的原因是,我们需要一个小权限的账号来操作git.比如我们后面会限制这个git账号,不让他登录shell等等.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo adduser git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们在&lt;strong&gt;服务器&lt;/strong&gt;的ubuntu执行这条命令就好了,非常简单,而且还帮你在&lt;code&gt;home&lt;/code&gt;下建立了对应的目录.
接下来要配置&lt;code&gt;git&lt;/code&gt;用户的认证,有两种办法:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;给&lt;code&gt;git&lt;/code&gt;用户设置一个密码,以后每次执行&lt;code&gt;hexo d&lt;/code&gt;的时候,会要求你输入密码,才能继续操作&lt;/li&gt;
&lt;li&gt;给&lt;code&gt;git&lt;/code&gt;用户配置ssh证书,当把公钥传到服务器后,每次&lt;code&gt;hexo d&lt;/code&gt;免密,直接操作完成&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;23-设置密码登录&#34;&gt;2.3 设置密码登录
&lt;/h2&gt;&lt;p&gt;设置密码使用Linux命令&lt;code&gt;passwd&lt;/code&gt;即可&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo passwd git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上述命令执行完成后,按照提示输入两次密码,即配置完成&lt;/p&gt;
&lt;h2 id=&#34;24-配置ssh证书&#34;&gt;2.4 配置ssh证书
&lt;/h2&gt;&lt;p&gt;配置ssh证书,设置的时候比较麻烦,但是后面每次使用比较简单.后面再说原因.&lt;/p&gt;
&lt;h3 id=&#34;241-生成ssh证书&#34;&gt;2.4.1 生成ssh证书
&lt;/h3&gt;&lt;p&gt;首先,我们需要生成证书,这一步我们在自己本地电脑进行.&lt;strong&gt;注意&lt;/strong&gt;:生成证书不在服务器上操作,在自己&lt;strong&gt;本地电脑&lt;/strong&gt;上进行.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mac或者Linux&lt;/strong&gt;
对于Mac或者LInux用户,直接使用系统自带的终端就好
&lt;strong&gt;windows&lt;/strong&gt;:
对于windows用户,hexo配置完成后,你应该有一个执行shell命令的软件,比如我的是github desktop自带的shell程序,或者你自己安装的git shell,也是可以的,大概长这样
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1fefka44bdmj20gj094glp.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;git shell程序界面&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;首先,我们打开shell程序,输入以下命令&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-keygen -t rsa -b &lt;span style=&#34;color:#ae81ff&#34;&gt;4096&lt;/span&gt; -C &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;你的email地址&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;接着提示让我们输入文件保存的路径,如果你不输入就按照默认的保存,输入完成,回车
下一步,提示我们输入密码,这个密码只是证书的密码,即,当使用这个证书登录的时候要输入的密码,它不是服务器用户的密码,而是单纯给ssh证书设置的密码.
我这里选择不设置,直接回车,提示确认起码,再回车
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1fefkzl7f04j20eq07wq34.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;生成证书&#34;
	
	
&gt;
证书生成完毕.
我们进入刚才证书保存的目录,可以看到&lt;code&gt;id_rsa&lt;/code&gt;和&lt;code&gt;id_rsa.pub&lt;/code&gt;两个文件(也有可能是其他名字,反正一个有pub一个没pub),分别就是私钥和公钥.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PS&lt;/strong&gt;:其实生成证书这一步,在服务器上,或者任何一个机器上都可以,只要你最后把这个公钥传到服务器,用这个私钥链接你的服务器就行,这里为求简单,在本地的git shell中生成&lt;/p&gt;
&lt;h3 id=&#34;242-上传公钥&#34;&gt;2.4.2 上传公钥
&lt;/h3&gt;&lt;p&gt;接下来,我们还是在&lt;strong&gt;本地终端&lt;/strong&gt;操作.将上一步生成的&lt;code&gt;id_rsa.pub&lt;/code&gt;文件内容追加到服务器的&lt;code&gt;authorized_keys&lt;/code&gt;中.
OpenSSH提供了一个命令&lt;code&gt;ssh-copy-id&lt;/code&gt;,直接将文件添加到服务器,简直不能更方便
用法如下:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-copy-id git@yourserver
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;比如我输入&lt;code&gt;ssh-copy-id -i ~/.ssh/id_rsa.pub git@bblove.me&lt;/code&gt;,这里的yourserver可以输入域名或者ip,&lt;code&gt;-i&lt;/code&gt;用来指定具体的公钥文件,适用于存在多个公钥或者找不到公钥的情况,最好手动指定它.输入该命令后,会要求你输入服务器上&lt;code&gt;git&lt;/code&gt;用户的密码.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1feflmcy70yj20g5070ab1.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;authorized_keys文件内容&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;如果此法不通,你可以直接在服务器上编辑&lt;code&gt;authorized_keys&lt;/code&gt;文件,把&lt;code&gt;id_rsa.pub&lt;/code&gt;内容追加到文件后面即可
请务必确认&lt;code&gt;authorized_keys&lt;/code&gt;文件的权限是&lt;code&gt;rw-------&lt;/code&gt;,如果不是,使用&lt;code&gt;chmod 600 authorized_keys&lt;/code&gt;来修改.&lt;/p&gt;
&lt;h3 id=&#34;243-测试ssh连接&#34;&gt;2.4.3 测试ssh连接
&lt;/h3&gt;&lt;p&gt;接下来,我们还是在&lt;strong&gt;本地终端&lt;/strong&gt;操作.我们测试一下,看是否能成功连接到服务器.主要使用&lt;code&gt;ssh -T git@yourserver&lt;/code&gt;命令来测试,此处&lt;code&gt;git&lt;/code&gt;是指用户名,&lt;code&gt;yourserver&lt;/code&gt;填你的服务器域名或者ip即可.测试结果如下:
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1fek9m0bm0wj20fs0573yk.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;个人vps的ssh测试结果&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;如果测试不成功,他会返回给你错误提示.如果像我上图这样,那就是测试成功了,需要手动&lt;code&gt;ctr+c&lt;/code&gt;,让git终端回复到正常输入命令的状态.下面附上github的测试结果,与我的vps略有不同,反正都是成功的.
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1fek9nadydfj20g102adfr.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;github的测试结果&#34;
	
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;244-ssh测试失败&#34;&gt;2.4.4 ssh测试失败
&lt;/h3&gt;&lt;p&gt;如果你测试失败,可能有多方面的原因,客户端或者服务器都有可能.&lt;/p&gt;
&lt;h4 id=&#34;2441-客户端ssh配置&#34;&gt;2.4.4.1 客户端ssh配置
&lt;/h4&gt;&lt;p&gt;接下来,还是在&lt;strong&gt;本地终端&lt;/strong&gt;操作.我们首先检查一下客户端ssh的配置,文件的位置在&lt;code&gt;/etc/ssh/ssh_config&lt;/code&gt;,我们使用&lt;code&gt;vi /etc/ssh/ssh_config&lt;/code&gt;命令打开和编辑该文件.本文服务器域名是&lt;code&gt;bblove.me&lt;/code&gt;,请检查你的&lt;code&gt;ssh_config&lt;/code&gt;文件,是否存在一条&lt;code&gt;Host *&lt;/code&gt;记录,并且该记录的&lt;code&gt;IdentityFile&lt;/code&gt;值,是否是你刚才生成的那个私钥的地址.
这个配置文件的意思是,针对某个&lt;code&gt;Host&lt;/code&gt;,程序使用&lt;code&gt;IdentityFile&lt;/code&gt;指定的私钥文件去进行ssh连接.
如果我们上一步测试ssh连接失败,有可能就是针对我们自己的域名,我们未指定正确的私钥文件.附上我的&lt;code&gt;ssh_config&lt;/code&gt;文件的内容,
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1fefmq9g0tsj20gj094aad.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;修改ssh_config文件&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;这也就意味着,我们可以针对多个网站各自配置不同的ssh证书,比如我github一套,自己服务器一套.当然偷懒的话,也可以所有网站使用一套ssh证书.只需要添加配置&lt;code&gt;Host *&lt;/code&gt;的配置即可.你的配置文件内容可能和我的不同,关注下&lt;code&gt;host&lt;/code&gt;和&lt;code&gt;IdentityFile&lt;/code&gt;的内容就好.
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1fefmtf7x24j20ie0kxjsn.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;ubuntu中ssh_config文件&#34;
	
	
&gt;
&lt;strong&gt;PS&lt;/strong&gt;:如果host配置了&lt;code&gt;*&lt;/code&gt;,请务必保证它在其他域名配置的后面,因为系统是从前到后匹配,所以&lt;code&gt;*&lt;/code&gt;必须在具体域名的后面.&lt;/p&gt;
&lt;h4 id=&#34;2442-服务器ssh配置&#34;&gt;2.4.4.2 服务器ssh配置
&lt;/h4&gt;&lt;p&gt;接下来,我们在&lt;strong&gt;服务器&lt;/strong&gt;上操作.我们检查一下服务器端ssh配置是否有误.文件的位置在&lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;,我们使用&lt;code&gt;sudo vi /etc/ssh/sshd_config&lt;/code&gt;打开和编辑该文件.例如我的ubuntu虚拟机的内容经过修改后,就是这样的:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Package generated configuration file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# See the sshd_config(5) manpage for details&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# What ports, IPs and protocols we listen for&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#这个是用来指定ssh端口的,不用改&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Port &lt;span style=&#34;color:#ae81ff&#34;&gt;22&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Use these options to restrict which interfaces/protocols sshd will bind to&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#ListenAddress 10.105.224.192&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#ListenAddress 10.105.224.192&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Protocol &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# HostKeys for protocol version 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostKey /etc/ssh/ssh_host_rsa_key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostKey /etc/ssh/ssh_host_dsa_key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostKey /etc/ssh/ssh_host_ecdsa_key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostKey /etc/ssh/ssh_host_ed25519_key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#Privilege Separation is turned on for security&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;UsePrivilegeSeparation yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Lifetime and size of ephemeral version 1 server key&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;KeyRegenerationInterval &lt;span style=&#34;color:#ae81ff&#34;&gt;3600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ServerKeyBits &lt;span style=&#34;color:#ae81ff&#34;&gt;1024&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Logging&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SyslogFacility AUTH
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LogLevel INFO
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Authentication:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LoginGraceTime &lt;span style=&#34;color:#ae81ff&#34;&gt;120&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PermitRootLogin no
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;StrictModes yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RSAAuthentication yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PubkeyAuthentication yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;AuthorizedKeysFile	%h/.ssh/authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Don&amp;#39;t read the user&amp;#39;s ~/.rhosts and ~/.shosts files&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;IgnoreRhosts yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# For this to work you will also need host keys in /etc/ssh_known_hosts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RhostsRSAAuthentication no
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# similar for protocol version 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostbasedAuthentication no
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Uncomment if you don&amp;#39;t trust ~/.ssh/known_hosts for RhostsRSAAuthentication&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#IgnoreUserKnownHosts yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# To enable empty passwords, change to yes (NOT RECOMMENDED)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PermitEmptyPasswords no
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Change to yes to enable challenge-response passwords (beware issues with&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# some PAM modules and threads)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ChallengeResponseAuthentication no
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Change to no to disable tunnelled clear text passwords&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PasswordAuthentication yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Kerberos options&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#KerberosAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#KerberosGetAFSToken no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#KerberosOrLocalPasswd yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#KerberosTicketCleanup yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# GSSAPI options&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#GSSAPIAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#GSSAPICleanupCredentials yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;X11Forwarding yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;X11DisplayOffset &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PrintMotd no
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PrintLastLog yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;TCPKeepAlive yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#UseLogin no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#MaxStartups 10:30:60&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#Banner /etc/issue.net&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Allow client to pass locale environment variables&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;AcceptEnv LANG LC_*
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;AllowUsers chen git zhou
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Subsystem sftp /usr/lib/openssh/sftp-server
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Set this to &amp;#39;yes&amp;#39; to enable PAM authentication, account processing,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# and session processing. If this is enabled, PAM authentication will&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# be allowed through the ChallengeResponseAuthentication and&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# PasswordAuthentication.  Depending on your PAM configuration,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# PAM authentication via ChallengeResponseAuthentication may bypass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# the setting of &amp;#34;PermitRootLogin without-password&amp;#34;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# If you just want the PAM account and session checks to run without&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# PAM authentication, then enable this but set PasswordAuthentication&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# and ChallengeResponseAuthentication to &amp;#39;no&amp;#39;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;UsePAM yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Ciphers aes128-cbc,aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr,3des-cbc,arcfour128,arcfour256,arcfour,blowfish-cbc,cast128-cbc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmac-sha1-96,hmac-md5-96
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;KexAlgorithms diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group1-sha1,curve25519-sha256@libssh.org
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;UseDNS no
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们只需要重点关注下这几个值,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PermitRootLogin no&lt;/code&gt;,也就是不允许使用root登录,这是为了安全起见&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AuthorizedKeysFile	%h/.ssh/authorized_keys&lt;/code&gt;,指定公钥存放的文件,这个要重点关注下,注意去掉前面的注释&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其他的配置,基本不用修改.以上配置修改完成后,我们重启一下服务器端的ssh服务,使用命令&lt;code&gt;sudo service ssh restart&lt;/code&gt;即可.最后,我们再回到&lt;strong&gt;客户端&lt;/strong&gt;,测试一下ssh连接是否成功.&lt;code&gt;ssh -T git@yourserver&lt;/code&gt;.还不行的话,你就去google查一查错误&lt;/p&gt;
&lt;h2 id=&#34;25-配置服务器git仓库&#34;&gt;2.5 配置服务器git仓库
&lt;/h2&gt;&lt;p&gt;上一步,我们配置好了客户端ssh连服务器,这一步我们回到&lt;strong&gt;服务器&lt;/strong&gt;上去操作.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#在服务器新建一个文件夹,用来存放git仓库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo mkdir /home/chen/bblove
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd /home/chen/bblove
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#进入文件夹,对git仓库进行初始化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo git init --bare blog.git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#初始化完成后,进入hooks文件夹&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd /home/chen/bblove/blog.git/hooks
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#新建一个钩子程序,这个文件名可以自定义,我取名为post-receive&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vi post-receive
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们在post-receive中,写入如下代码&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;git --work-tree&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/home/chen/www/bblove_me --git-dir&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/home/chen/bblove/blog.git checkout -f
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;此处,&lt;code&gt;--work-tree&lt;/code&gt;指的是你的网站根目录,&lt;code&gt;--git-dir&lt;/code&gt;指的是你的git仓库的目录.
编辑完城后,&lt;code&gt;wq&lt;/code&gt;退出并保存&lt;code&gt;post-receive&lt;/code&gt;文件.下面给钩子程序加上可执行权限&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#给钩子程序加上可执行权限&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo chmod +x /home/chen/bblove/blog.git/hooks/post-receive
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最后,修改git仓库权限,否则客户端无法提交代码到这个仓库&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#接下来修改git仓库的权限&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo chown -R git:git blog.git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;此处还要注意一点,我们还要修改网站根目录的权限,否则钩子程序执行的时候,无法修改网站根目录的内容.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo chown -R git:git /home/chen/www/bblove_me
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;至此,服务器端配置完成&lt;/p&gt;
&lt;h2 id=&#34;26-修改hexo的配置文件&#34;&gt;2.6 修改hexo的配置文件
&lt;/h2&gt;&lt;p&gt;终于,走到了这一步.
我们打开我们自己hexo博客根目录的&lt;code&gt;_config.yml&lt;/code&gt;文件.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;deploy:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- type: git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  repo: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;https://github.com/Jackroyal/Jackroyal.github.io.git&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  branch: master
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- type: git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  repo: git@bblove.me:/home/git/bblove/blog.git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  branch: master
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;因为,hexo本身是支持多点发布的,所以我们每次deploy的时候,让他同时推到github和自己的服务器上去.
你只需要改&lt;code&gt;  repo: git@bblove.me:/home/git/bblove/blog.git&lt;/code&gt;这一行,&lt;code&gt;git@yourserver:/your-git-dir&lt;/code&gt;.
ok,大功告成啦,赶快&lt;code&gt;hexo d -g&lt;/code&gt;看看效果吧&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;http://www.swiftyper.com/2016/04/17/deploy-hexo-with-git-hook/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;使用 Git Hook 自动部署 Hexo 到个人 VPS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;http://blog.csdn.net/linghe301/article/details/8211305#&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Linux启动或禁止SSH用户及IP的登录&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Nginx上多站点的https配置</title>
        <link>https://blog.huirongis.me/post/nginx-https-setting-on-multiple-sites/</link>
        <pubDate>Wed, 05 Apr 2017 13:09:24 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/nginx-https-setting-on-multiple-sites/</guid>
        <description>&lt;p&gt;&lt;strong&gt;更新&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2017-06-13 修改证书生成目录,为方便后续的git push自动更新,将acme验证目录移出网站根目录&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此处接上篇&lt;a class=&#34;link&#34; href=&#34;https://bblove.me/2017/04/05/nginx-installation-and-setting-in-ubuntu-server&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;在ubuntu上安装和配置Nginx&lt;/a&gt;,本文在之前的基础上配置https.&lt;/p&gt;
&lt;h1 id=&#34;1-环境和目标&#34;&gt;1 环境和目标
&lt;/h1&gt;&lt;p&gt;服务器:ubuntu server 16.04.2 LTS
主要工具:xshell
本文的目标是使用Nginx的TLS SNI技术,使用一个服务器(即一个ip),给多个域名配置https.我有一个腾讯云服务器,买了两个域名,都指向这台服务器,我现在想两个域名都上https,而且&lt;code&gt;www.bblove.me&lt;/code&gt;跳转到&lt;code&gt;bblove.me&lt;/code&gt;,我只想使用&lt;code&gt;bblove.me&lt;/code&gt;这个较短的域名.
但是不是所有的浏览器都支持SNI,下面的截图来自屈大的博客
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1febqcpfjoaj20kv08mjrs.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;SNI支持情况&#34;
	
	
&gt;
由于是个人博客,随意折腾,所以不犹豫,直接上https.&lt;/p&gt;
&lt;h1 id=&#34;2-证书&#34;&gt;2 证书
&lt;/h1&gt;&lt;p&gt;我们使用Let&amp;rsquo;s Encrypt提供的免费证书,每次有90天的有效期,过期之后需要再更新,不过这对于程序员来说,根本就不是事儿对吧.点击&lt;a class=&#34;link&#34; href=&#34;https://github.com/Neilpang/acme.sh&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ACME&lt;/a&gt;,我们使用ACME来自动获取证书.主要步骤分三步:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;安装 acme.sh&lt;/li&gt;
&lt;li&gt;生成证书&lt;/li&gt;
&lt;li&gt;copy 证书到 nginx
具体步骤,参考github上的wiki  &lt;a class=&#34;link&#34; href=&#34;https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ACME使用说明&lt;/a&gt;
下面我简单说下我这边的配置:&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;21-安装acmesh&#34;&gt;2.1 安装acme.sh
&lt;/h2&gt;&lt;p&gt;安装的命令很简单&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl  https://get.acme.sh | sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;建议将脚本放在自己的home目录下,并且建立一个alias&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;acme.sh&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;~/.acme.sh/acme.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;操作的目录都只会在&lt;code&gt;~/acme.sh&lt;/code&gt;目录,不会污染系统其他的文件夹和目录&lt;/p&gt;
&lt;h2 id=&#34;22-生成证书&#34;&gt;2.2 生成证书
&lt;/h2&gt;&lt;p&gt;脚本安装好后,下一步开始生成证书,生成证书的过程中,Let&amp;rsquo;s Encrypt需要对域名的所有权进行验证,这个很好理解,证书发行机构需要确定你是否对该域名拥有所有权.验证的方式有两种:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用http验证
acme脚本会生成一个验证文件,并放到网站根目录,然后Let&amp;rsquo;s Encrypt会尝试访问这个文件,完成验证&lt;/li&gt;
&lt;li&gt;使用DNS验证
顾名思义,只需要在DNS设置中添加一条txt解析记录,即可&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本文采用的是http验证,DNS验证就不细说了,想使用DNS验证的直接看 &lt;a class=&#34;link&#34; href=&#34;https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ACME使用说明&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我一共有两个域名&lt;code&gt;bblove.me&lt;/code&gt;和&lt;code&gt;huirongis.me&lt;/code&gt;,主域名加上带&lt;code&gt;www&lt;/code&gt;的子域名,也就是一共有4个域名.
生成证书有下面三种思路:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;所有的4个域名都使用同一个证书,此法最简单,可以避免发生域名和证书不匹配的情况&lt;/li&gt;
&lt;li&gt;&lt;code&gt;www.bblove.me&lt;/code&gt;和&lt;code&gt;bblove.me&lt;/code&gt;使用同一个证书,另外一个域名同理,也就是总共使用两个证书&lt;/li&gt;
&lt;li&gt;使用4个不同的证书,这种情况比较复杂,如果想实现&lt;code&gt;www&lt;/code&gt;跳转到不带&lt;code&gt;www&lt;/code&gt;的,处理不好容易出现证书错误的问题&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;由于我最后只使用&lt;code&gt;https://bblove.me&lt;/code&gt;这个域名,验证方式选择的http方式,&lt;code&gt;bblove.me&lt;/code&gt;和&lt;code&gt;huirongis.me&lt;/code&gt;指向不同的根目录,为了方便后续管理和维护,所以我选择方案二,即&lt;code&gt;bblove.me&lt;/code&gt;和&lt;code&gt;www.bblove.me&lt;/code&gt;共用一个证书,&lt;code&gt;huirongis.me&lt;/code&gt;同理.
确定好方案后,下面开始生成证书,使用如下命令即可.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;acme.sh --issue -d bblove.me -d www.bblove.me -w /home/chen/www/nginx_acme/bblove_me/ --force
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中&lt;code&gt;-d&lt;/code&gt;表示域名,可以添加多个;&lt;code&gt;-w&lt;/code&gt;表示网站的根目录,一条命令执行完成,即可得到证书.
顺利的话,执行结果如下(此处配图输入命令未更新,输出结果是一致的):
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1fecw65xpvrj20lv0ll0vo.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;生成证书&#34;
	
	
&gt;
如果出错的话,在那条命令后面追加&lt;code&gt;--debug&lt;/code&gt;,查看详细的信息,我有遇到过文件权限的错误,只要网站根目录权限和当前home目录对应的用户权限一样就可以了;我还遇到过验证不通过的问题,大家可以在浏览器中访问那个路径,看是否正常,类似&lt;code&gt;http://bblove.me/.well-known/acme-challenge/dfdfdfdafdfdfdfdfdfdfdfd&lt;/code&gt;这样的格式&lt;/p&gt;
&lt;h2 id=&#34;23-安装证书&#34;&gt;2.3 安装证书
&lt;/h2&gt;&lt;p&gt;在上一步中,我们已经成功的生成了我们要的证书.这一步我们将它安装在我们域名所对应的根目录中,操作很简单.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;acme.sh --installcert -d bblove.me --keypath /home/chen/www/nginx_ssl/bblove_me/bblove_me.key --fullchainpath /home/chen/www/nginx_ssl/bblove_me/bblove_me.cer --reloadcmd &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;service nginx force-reload&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;执行结果如图所示:
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1fecwexr6nej20g606gaaf.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;安装证书&#34;
	
	
&gt;
至此,证书部分已经操作完成,第二个域名操作同理.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#生成证书&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;acme.sh --issue -d bblove.me -d www.bblove.me -w /home/chen/www/nginx_acme/bblove_me/ --force
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#安装证书&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;acme.sh --installcert -d bblove.me --keypath /home/chen/www/nginx_ssl/bblove_me/bblove_me.key --fullchainpath /home/chen/www/nginx_ssl/bblove_me/bblove_me.cer --reloadcmd &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;service nginx force-reload&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#生成证书&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;acme.sh --issue -d huirongis.me -d www.huirongis.me -w /home/chen/www/huirongis_me/ --force
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#安装证书&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;acme.sh --installcert -d huirongis.me --keypath /home/chen/www/nginx_ssl/huirongis_me/huirongis_me.key --fullchainpath /home/chen/www/nginx_ssl/huirongis_me/huirongis_me.cer --reloadcmd &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;service nginx force-reload&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;3-修改nginx配置&#34;&gt;3 修改Nginx配置
&lt;/h1&gt;&lt;p&gt;证书生成完成后,我们需要修改Nginx配置,主要就是启用之前注释掉的HTTPS相关的配置以及,修改对应的目录.
下面是我的第一个站点的配置:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;server &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    listen 80;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    server_name       www.bblove.me bblove.me;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    server_tokens     off;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    access_log /home/chen/www/nginx_log/bblove_me.log;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#access_log        /dev/null;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;$request_method !~ ^&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;GET|HEAD|POST&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;$ &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;        444;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    location ^~ /.well-known/acme-challenge/ &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        alias         /home/chen/www/nginx_acme/bblove_me/.well-known/acme-challenge/;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        try_files     $uri &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;404;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    location / &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        rewrite       ^/&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;.*&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;$ https://bblove.me/$1 permanent;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;server&lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        listen &lt;span style=&#34;color:#ae81ff&#34;&gt;443&lt;/span&gt; ssl http2 fastopen&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt; reuseport;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        server_name bblove.me;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        server_tokens   off;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        access_log /home/chen/www/nginx_log/bblove_me.log;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ssl_certificate /home/chen/www/nginx_ssl/bblove_me/bblove_me.cer;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ssl_certificate_key     /home/chen/www/nginx_ssl/bblove_me/bblove_me.key;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;#使用openssl dhparam -out dhparams.pem 2048命令生成该文件,将下面配置注释也许&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ssl_dhparam    /home/chen/www/nginx_ssl/dhparams.pem;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ssl_prefer_server_ciphers  on;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;#下面是推荐的加密算法配置,但是在我的机器上有bug,chacha20算法无法正常工作,所以我去掉了其中包含chacha20的算法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;# https://github.com/cloudflare/sslconfig/blob/master/conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    	&lt;span style=&#34;color:#75715e&#34;&gt;#ssl_ciphers                EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ssl_ciphers                EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ssl_session_cache          shared:SSL:50m;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ssl_session_timeout        1d;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ssl_session_tickets        on;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ssl_stapling    on;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ssl_stapling_verify     on;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ssl_trusted_certificate /home/chen/www/nginx_ssl/bblove_me/bblove_me.cer;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        resolver        114.114.114.114 valid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;300s;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        resolver_timeout        10s;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;$request_method !~ ^&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;GET|HEAD|POST|OPTIONS&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;$ &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;           444;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;$host !&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;bblove.me&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                rewrite ^/&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;.*&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;$ https://bblove.me/$1 permanent;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        location / &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                root /home/chen/www/bblove_me;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                index index.html index.htm;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                add_header               Strict-Transport-Security &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;max-age=31536000; includeSubDomains; preload&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                add_header               X-Frame-Options deny;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                add_header               X-Content-Type-Options nosniff;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                add_header               Cache-Control no-cache;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                add_header               x-xss-protection &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34; 1; mode=block&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                add_header               x-content-type-options nosniff;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;下面是我第二个站点的配置:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;server&lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	listen &lt;span style=&#34;color:#ae81ff&#34;&gt;443&lt;/span&gt; ssl http2;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	server_name www.huirongis.me huirongis.me;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	server_tokens	off;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	access_log /home/chen/www/nginx_log/huirongis_me.log;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ssl_certificate	/home/chen/www/nginx_ssl/huirongis_me/huirongis_me.cer;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ssl_certificate_key	/home/chen/www/nginx_ssl/huirongis_me/huirongis_me.key;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;#ssl_dhparam	/home/chen/www/nginx_ssl/huirongis_me/huirongis_me.cer;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ssl_ciphers                EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;#ssl_ciphers                EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ssl_prefer_server_ciphers  on;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ssl_session_cache          shared:SSL:50m;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ssl_session_timeout        1d;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ssl_session_tickets        on;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ssl_stapling	on;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ssl_stapling_verify	on;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ssl_trusted_certificate	/home/chen/www/nginx_ssl/huirongis_me/huirongis_me.cer;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	resolver	114.114.114.114 valid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;300s;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	resolver_timeout	10s;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;$request_method !~ ^&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;GET|HEAD|POST|OPTIONS&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;$ &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;           444;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;$host !&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;huirongis.me&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		rewrite ^/&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;.*&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;$ https://huirongis.me/$1 permanent;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	location / &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		root /home/chen/www/huirongis_me;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		index index.html index.htm;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	        add_header               Strict-Transport-Security &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;max-age=31536000; includeSubDomains; preload&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		add_header               X-Frame-Options deny;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	        add_header               X-Content-Type-Options nosniff;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		add_header               Cache-Control no-cache;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		add_header		 x-xss-protection &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34; 1; mode=block&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		add_header		 x-content-type-options nosniff;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;server &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    server_name       www.huirongis.me huirongis.me;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    server_tokens     off;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    access_log        /dev/null;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;$request_method !~ ^&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;GET|HEAD|POST&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;$ &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;        444;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    location ^~ /.well-known/acme-challenge/ &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        alias         /home/chen/www/nginx_acme/huirongis_me/.well-known/acme-challenge/;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        try_files     $uri &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;404;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    location / &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        rewrite       ^/&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;.*&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;$ https://huirongis.me/$1 permanent;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;该配置的主体内容,都是参考的屈大的配置,但是由于屈大的是单站点,所以为了对应多站点,做了一些改动.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;改动1: server的第一行listen &lt;code&gt;fastopen=3 reuseport&lt;/code&gt;的选项,只能用在一个站点上,不能两个站点都加这段配置&lt;/li&gt;
&lt;li&gt;改动2: ssl_dhparam	配置,另外一个站点我懒得弄了,你可以自己生成文件,两个站点都配上.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有些配置的含义和原理,屈大都给了详细的分析,想了解的可以去看看.&lt;/p&gt;
&lt;p&gt;再贴一下本站目录结构:
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1fgivj9x7g0j20nj0ert9g.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;本站目录设置&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;4-修改http资源为https&#34;&gt;4 修改http资源为https
&lt;/h1&gt;&lt;p&gt;ok,都这里基本都搞定了,应该可以看到小绿锁了.在chrome中按&lt;code&gt;F12&lt;/code&gt;-&amp;gt;&lt;code&gt;console&lt;/code&gt;,查看原因.如果你的网站中包含其他第三方http资源,可能会没有看到小绿锁,只需要将http资源修改为https的就行,比如图片资源,本站使用新浪微博图床,只需要将原来的http格式的图片加个s,变成https就可以了.如果资源没有https的,那就需要将资源下载到服务器本地.
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1fecyz408dqj20yc0ga431.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;小绿锁&#34;
	
	
&gt;
至此,整个网站的https配置完成.&lt;/p&gt;
&lt;h1 id=&#34;5-问题和优化&#34;&gt;5 问题和优化
&lt;/h1&gt;&lt;p&gt;现在还有问题没有解决:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;加密算法的问题,我的服务器配置chacha20算法不成功,只要客户端协商的算法中有chacha20,服务器就会返回&lt;code&gt;bad record mac&lt;/code&gt;错误,现在我只能把它禁用&lt;/li&gt;
&lt;li&gt;证书的自动更新问题,由于我后期还配置了其他的东西,所以证书自动更新一直不成功,需要我手动去更新&lt;/li&gt;
&lt;li&gt;将域名提交到https://hstspreload.org/,具体原理请参考&lt;a class=&#34;link&#34; href=&#34;https://imququ.com/post/sth-about-switch-to-https.html#toc-2&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;合理使用&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://imququ.com/post/sth-about-switch-to-https-2.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;关于启用 HTTPS 的一些经验分享（二）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://imququ.com/post/my-nginx-conf.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;本博客 Nginx 配置之完整篇&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://imququ.com/post/sth-about-switch-to-https.html#toc-2&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;关于启用 HTTPS 的一些经验分享（一）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>在ubuntu上安装和配置Nginx</title>
        <link>https://blog.huirongis.me/post/nginx-installation-and-setting-in-ubuntu-server/</link>
        <pubDate>Wed, 05 Apr 2017 10:51:24 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/nginx-installation-and-setting-in-ubuntu-server/</guid>
        <description>&lt;p&gt;废话:最近一直想写博客,憋了好几篇,但是一直没时间,从年前拖到了年后,一直拖到4月份,真是伤不起,不过,总算开动了&lt;/p&gt;
&lt;h1 id=&#34;1-系统环境&#34;&gt;1 系统环境
&lt;/h1&gt;&lt;p&gt;服务器:ubuntu server 16.04.2 LTS
主要工具:xshell&lt;/p&gt;
&lt;p&gt;我这个服务器是腾讯云的主机,装的最新的ubuntu server lts发行版,32位系统.&lt;/p&gt;
&lt;h1 id=&#34;2-系统安装&#34;&gt;2 系统安装
&lt;/h1&gt;&lt;p&gt;我这里是完全参考的屈大的教程,因为屈大教程会不断更新,所以我这里就不赘述,直接贴地址
&lt;a class=&#34;link&#34; href=&#34;https://imququ.com/post/my-nginx-conf.html&#34;  title=&#34;本博客Nginx配置之完整篇&#34;
     target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://imququ.com/post/my-nginx-conf.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ps:由于屈大的Nginx配置是https一步到位,我的建议是,刚开始玩的话,先把所以https相关的配置注释掉,等一切顺利跑起来了,后期再加上https的内容&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Nginx全局配置&lt;/code&gt;,直接抄屈大的就行,只需要把最后一行,改成你自己的服务器的路径&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    include            /home/jerry/www/nginx_conf/*.conf;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;web站点配置&lt;/code&gt;注释掉https相关内容后,如下(我修改了屈大部分目录的路径,原理一样的):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;server{
        listen 80;

        server_name bblove.me www.bblove.me;
        server_tokens   off;
        access_log /home/chen/www/nginx_log/bblove_me.log;


#        ssl_certificate /home/chen/www/nginx_ssl/bblove_me/bblove_me.cer;
#        ssl_certificate_key     /home/chen/www/nginx_ssl/bblove_me/bblove_me.key;
#        ssl_dhparam    /home/chen/www/nginx_ssl/dhparams.pem;
#        ssl_prefer_server_ciphers  on;
#        ssl_ciphers                EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

#       ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;

#       ssl_session_cache          shared:SSL:50m;
#        ssl_session_timeout        1d;

#       ssl_session_tickets        on;
#        ssl_stapling    on;
#        ssl_stapling_verify     on;
#        ssl_trusted_certificate /home/chen/www/nginx_ssl/bblove_me/bblove_me.cer;
        resolver        114.114.114.114 valid=300s;
        resolver_timeout        10s;
        if ($request_method !~ ^(GET|HEAD|POST|OPTIONS)$ ) {
                return           444;
        }
#        if ($host != &amp;#39;bblove.me&amp;#39;){
#                rewrite ^/(.*)$ https://bblove.me/$1 permanent;
#        }
        location / {
                root /home/chen/www/bblove_me;
                index index.html index.htm;
                add_header               Strict-Transport-Security &amp;#34;max-age=31536000; includeSubDomains; preload&amp;#34;;
                add_header               X-Frame-Options deny;
                add_header               X-Content-Type-Options nosniff;
                add_header               Cache-Control no-cache;
                add_header               x-xss-protection &amp;#34; 1; mode=block&amp;#34;;
                add_header               x-content-type-options nosniff;
        }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的配置完成后,使用&lt;code&gt;sudo service nginx reload&lt;/code&gt;,重新加载配置文件,如果没有生效,就重启一下服务器.如果服务出错,可以使用&lt;code&gt;sudo service nginx status&lt;/code&gt;查看是哪一行的配置出错,修改以后再reload.
到此步,服务器应该就配置好了,可以使用ip访问你的服务器了&lt;code&gt;http://x.x.x.x&lt;/code&gt;,此处如果无法访问,请查看
&lt;a class=&#34;link&#34; href=&#34;#4-%e7%bb%93%e5%b0%be&#34; &gt;安全组配置&lt;/a&gt;,检查是否开放了80端口&lt;/p&gt;
&lt;h1 id=&#34;3-修改dns配置&#34;&gt;3 修改DNS配置
&lt;/h1&gt;&lt;p&gt;我使用的DNSPOD的服务,直接去管理后台,添加两条解析记录,将&lt;code&gt;www&lt;/code&gt;和&lt;code&gt;@&lt;/code&gt;添加A记录,指向自己的服务器ip.
如果你不添加&lt;code&gt;www&lt;/code&gt;的话,那访问你的博客只能使用&lt;code&gt;bblove.me&lt;/code&gt;访问.添加两条记录的话,&lt;code&gt;www.bblove.me&lt;/code&gt;和&lt;code&gt;bblove.me&lt;/code&gt;都可访问你的博客.
而且,后面配置&lt;code&gt;https&lt;/code&gt;的时候,如果要上HSTS的功能,就必须要配置&lt;code&gt;www&lt;/code&gt;.
&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1febmtogaq5j20v904gglw.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;DNSPOD配置&#34;
	
	
&gt;
配置好之后,可能要等一会儿才会生效
到这一步,你的服务器应该就可以使用域名访问了,http://域名&lt;/p&gt;
&lt;h1 id=&#34;4-本站目录设置&#34;&gt;4 本站目录设置
&lt;/h1&gt;&lt;p&gt;本站因为后期会布置多站点,所以设置目录结构如下,&lt;code&gt;www&lt;/code&gt;目录下包含两个域名对应的网站根目录,同时还设置了配置文件的目录,日志文件的目录,https证书相关目录等,如图所示.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1fecyn6c5hyj20fg0hn0tc.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;本站目录设置&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;5-结尾&#34;&gt;5 结尾
&lt;/h1&gt;&lt;p&gt;我把多站点配置和https配置放到下一篇博客,这篇就简单讲这么多吧.&lt;/p&gt;
&lt;p&gt;小建议:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;配置Nginx的时候善用&lt;code&gt;sudo service nginx status&lt;/code&gt;,这个用来定位错误很方便&lt;/li&gt;
&lt;li&gt;如果使用云服务器,比如腾讯云的话,需要修改安全组策略,把80端口和443端口放开&lt;img src=&#34;https://ws1.sinaimg.cn/large/692869a3gy1febolh4yq0j21170fiq4b.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;安全组配置&#34;
	
	
&gt;&lt;/li&gt;
&lt;li&gt;如果想查看端口是否打开,可以使用&lt;a class=&#34;link&#34; href=&#34;http://tool.chinaz.com/port/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;站长工具-在线端口扫描&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>2016这过去的半年</title>
        <link>https://blog.huirongis.me/post/my-life-these-days/</link>
        <pubDate>Sun, 06 Nov 2016 15:39:32 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/my-life-these-days/</guid>
        <description>&lt;p&gt;时间真是匆匆啊,上一篇博客的时间是3月25,今天都已经是11月6号了,过去了7个多月.&lt;/p&gt;
&lt;h1 id=&#34;1-时光匆匆&#34;&gt;1 时光匆匆
&lt;/h1&gt;&lt;p&gt;自从上了初中开始,就发觉时间过得快来.接下来到了高中时间有是更快了,到了大学时间简直飞逝.
人生黄金的10年,转眼已经过了一般,but我依旧没有成为一个大神,还是辣么水水哒.基础知识还是不扎实,做事情总是知其然而不知其所以然,这是我所讨厌的,但是也没有实际的办法.
每次遇到一个事情,如果要刨根问底的去解决,就涉及太多的东西,短时间根本没法解决;可是如果选择一个快捷的方法,那么就只是解决了眼前的问题,但是没有实际去搞懂它.等到事情解决,每每又再提不起兴趣去解决.这真是一对矛盾,想快速解决就搞不懂原理,想搞懂原理但是时间又不允许.&lt;/p&gt;
&lt;h1 id=&#34;2-找实习&#34;&gt;2 找实习
&lt;/h1&gt;&lt;p&gt;今年有一个比较大的事情,也是对自己比较重要的事情,找实习.想来也是运气好,和老谭他们比起来真是好太多了.
还记得3月份第一个电话是海豚浏览器,我在官网发的邮件,因为海豚不招php没办法投的前端开发,但是一面(可能都不能算是一面),应该是hr面试的就把我刷掉了,额,有点心塞.
第二个好像是微博易,这个公司有点坑,技术面是CTO面试的.一般CTO啊CEO啊搞面试,说实话都觉得有点不靠谱,因为说明公司真心小,哭脸.这个技术面真心让我无语,一开始就告诉我这次面试要问几个技术问题,开场是我做个自我介绍,然后简单聊了一下自己的项目.接着事情就不可控了,他问我为什么要做技术,我说是因为自己对技术比较感兴趣,小时候看电影觉得黑客很酷,现在虽然做不成黑客,但是我喜欢电脑,喜欢敲代码.然后他接着问我为什么喜欢,觉得做技术最重要的是什么?我当时内心真是黑人问号了,这完全不按套路出牌啊,一直刨根问底.整个面试持续了1个小时,而且最后结束的时候并没有问任何技术问题,真是醉了.记得当时在实验室面试的,面完之后,我师弟开口问,师兄你刚才是HR面吗?你就知道这个面试有多坑了,这哪是技术面啊,工程师为啥会问这些问题?那要HR做什么?
再往后的面试就顺利多了,拿了盛大游戏的offer(内部应用系统开发),美图offer(这个职位应该是比较好的,但是在厦门),华米科技(这个是我打算去的,对小米的东西也比较有兴趣),百度地图offer.拿了百度的以后就没有再面试了.对于华米科技的那个面试官还是挺抱歉的,聊的也比较开心,因为华米科技算是创业公司应该还是能很好的锻炼,无奈百度的名气大,最后还是选择了百度,只能拒掉华米科技了.&lt;/p&gt;
&lt;h1 id=&#34;3-去实习&#34;&gt;3 去实习
&lt;/h1&gt;&lt;p&gt;拿到口头offer以后,在漫长的等待书面offer中.回家住了几天,和家人一起上了去天堂寨旅游了一把,放松一下.
最后出发北上的晚上,我最亲爱的请我吃了一顿烧烤,恩,我喜欢烧烤.我俩还喝了一瓶啤酒,哈哈.&lt;img src=&#34;https://ws4.sinaimg.cn/large/692869a3gw1f9ihai0a6nj21kw23u4qp.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;武汉出发时&#34;
	
	
&gt;
接着一路北上,我坐的硬座,额,必须是为了省钱,现在想想,也是蛮艰苦的.&lt;/p&gt;
&lt;h2 id=&#34;31-找房子&#34;&gt;3.1 找房子
&lt;/h2&gt;&lt;p&gt;刚到北京,北京的旅社真是贵,七天如家什么的一天要200-300多,我表示完全住不起啊,最后选择住青年旅社,一天80多块钱.幸亏我弟在北京念书,我可以把行李放在他那里,青年旅社自己带的东西不敢放,怕被偷.那也是我第一次住青年旅社,还是很紧张的,睡觉把书包都抱着.
找房子绝对是最艰难的事情,跑了两天,全是中介,根本就没有没有中介的地方,而且在五道口附加的房子真是贵,一间房子一不小心就要2000多,直逼三千,关键房子还不咋地.还好有同学在,雄风和国安他们先行来到北京,最痛苦的事他们已经趟过了,我在他们那里借住了几天.还好天无绝人之路,我在内网找了几天,总算找打合适的了,虽然离地铁站有点远,但是1600一个月,而且是2室1厅2卫,人少,住着舒服,附近有超市有菜场,生活很方便,室友人也很好,知道我是实习生很照顾我,房租什么的也没催我还说可以等发工资再交.&lt;/p&gt;
&lt;h2 id=&#34;32-百度第一天&#34;&gt;3.2 百度第一天
&lt;/h2&gt;&lt;p&gt;终于正式去百度实习了,因为上午8点就要开始入职了,所以那天起的很早.
上午就是入职流程,领东西然后去大厦听hr培训,然后再分到各个地方.我入职的地方是奎科大厦,不过说真的,还是更喜欢百度大厦或者科技园,哈哈,新修的大楼看起来爽多了,啥都是新的,更有归属感.
中午11点多的时候,来到了自己的工位,经理向大家介绍我,接着介绍每个人的名字,额,差不多一个都没记住,还好工位每个人都有明牌,哈哈.
下午的时候,就是熟悉一下环境,搭建开发环境申请开发机什么的,都是mentor在教我.
第一天的感觉,就是好累,可能早上起太早了,也可能是房子还没确定,当天下班的时候感觉好累,就拍了这一张照片.
&lt;img src=&#34;https://ws4.sinaimg.cn/large/692869a3gw1f9ih2uc5xhj20x617s45c.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;在百度的第一天&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;34-在百度&#34;&gt;3.4 在百度
&lt;/h2&gt;&lt;p&gt;之前做的项目,都算是小打小闹,这次进去公司实习确实有不一样的感受.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;要对自己的每一行代码负责&lt;/code&gt;:以前写代码都是只看最后的运行效果,出来了就行了,其实都没搞清楚每一行代码每一个变量的具体输出和值,测试也不充分.公司写代码,必须要自己对自己的代码负责,刚开始去就吃了这方面的苦,第一次代码上线都出了问题,所以后来排期的时候,代码自己review的时间都特别长,有时候和开发时间差不多.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;系统设计能力很重要&lt;/code&gt;:之前都是提了需求,考虑一下,就开始动手写代码了.不过一般来说,当一个需求确定的时候,我自己心里就有了一个大概的构图,有个谱了.到公司的感觉就是,同事之间的经验比我还是丰富很多,所以前期的时候很看重设计能力,还专门开会大家讨论,确定方案后,才动手写代码.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;多学习,多看书&lt;/code&gt;:同事空闲时候都在学习别的东西,看其他书籍,这是一个好习惯,我喜欢.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;35-与人相处&#34;&gt;3.5 与人相处
&lt;/h2&gt;&lt;p&gt;在公司和学校还是有很大区别的,学校每天都是和室友混在一起,一起吃饭,一起去实验室,一起玩游戏.到公司,刚开始感觉大家的感觉就疏远很多,大家彼此相互尊重,感觉就是少了学校同学的那份亲密.刚开始我还试图融入他们的圈子,不过因为自己不善言辞,做的并不好.
大概一个月过后,就觉悟了,在公司和在学校本来就不同,大家的关系也无法做到像学校那样,所以不必强求,大家友好和平共处,就是正确的处理方式.正如圣哥所说,大家其实都是过客.
后面的相处就自然的多,简简单单相处.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;2016-11-06 17:25  就先写到这,吃饭去的,等下食堂就没饭了&lt;/p&gt;
</description>
        </item>
        <item>
        <title>HTTP1.0和HTTP1.1的区别</title>
        <link>https://blog.huirongis.me/post/http-1-0-vs-1-1/</link>
        <pubDate>Fri, 25 Mar 2016 13:36:53 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/http-1-0-vs-1-1/</guid>
        <description>&lt;p&gt;今天研究了下HTTP,还是挺有意思的.
接下来,就比较一下两者的区别.&lt;/p&gt;
&lt;h1 id=&#34;1-长连接&#34;&gt;1 长连接
&lt;/h1&gt;&lt;p&gt;这个应该是变化最大的一个了.在1.0的版本中,如果客户端请求头没有设置&lt;code&gt;Connection: Keep-Alive&lt;/code&gt;的话,那么每次请求完成都会立即断开连接,然后客户端又要重新建立一个HTTP连接.假设一个网页包含了10个图片,那么为了请求图片,客户端必须要发送10次请求,无疑这对带宽和资源是极大的浪费,TCP的优势就没有体现出来.
在HTTP1.1中,&lt;code&gt;keep-Alive&lt;/code&gt;已经被弃用(但是大多数服务器和浏览器都还保留这个选项).在1.1的版本中,持久连接默认就是启用的,除非你显式在响应头部包含&lt;code&gt;Connection: close&lt;/code&gt;,客户端收到响应后才会关闭连接.&lt;/p&gt;
&lt;h1 id=&#34;2-host头域&#34;&gt;2 host头域
&lt;/h1&gt;&lt;p&gt;在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname).但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址.
HTTP1.1的请求消息和响应消息都应支持&lt;code&gt;Host&lt;/code&gt;头域,且请求消息中如果没有&lt;code&gt;Host&lt;/code&gt;头域会报告一个错误(400 Bad Request).此外,服务器应该接受以绝对路径标记的资源请求.&lt;/p&gt;
&lt;h1 id=&#34;3-请求方法&#34;&gt;3 请求方法
&lt;/h1&gt;&lt;p&gt;HTTP1.1增加了&lt;code&gt;OPTIONS&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;, &lt;code&gt;TRACE&lt;/code&gt;, &lt;code&gt;CONNECT&lt;/code&gt;这些Request方法.
Method         = &lt;strong&gt;&amp;ldquo;OPTIONS&amp;rdquo;&lt;/strong&gt;               ; Section 9.2
| &amp;ldquo;GET&amp;rdquo;                    ; Section 9.3
| &amp;ldquo;HEAD&amp;rdquo;                   ; Section 9.4
| &amp;ldquo;POST&amp;rdquo;                   ; Section 9.5
| &lt;strong&gt;&amp;ldquo;PUT&amp;rdquo;&lt;/strong&gt;                   ; Section 9.6
| &lt;strong&gt;&amp;ldquo;DELETE&amp;rdquo;&lt;/strong&gt;                 ; Section 9.7
| &lt;strong&gt;&amp;ldquo;TRACE&amp;rdquo;&lt;/strong&gt;               ; Section 9.8
| &lt;strong&gt;&amp;ldquo;CONNECT&amp;rdquo;&lt;/strong&gt;                ; Section 9.9
| extension-method
extension-method = token
HTTP1.1 增加的新的status code：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(HTTP1.0没有定义任何具体的1xx status code, HTTP1.1有2个)
100 Continue
101 Switching Protocols
203 Non-Authoritative Information
205 Reset Content
206 Partial Content
302 Found (在HTTP1.0中有个 302 Moved Temporarily)
303 See Other
305 Use Proxy
307 Temporary Redirect
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Timeout
409 Conflict
410 Gone
411 Length Required
412 Precondition Failed
413 Request Entity Too Large
414 Request-URI Too Long
415 Unsupported Media Type
416 Requested Range Not Satisfiable
417 Expectation Failed
504 Gateway Timeout
505 HTTP Version Not Supported
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;4-内容长度&#34;&gt;4 内容长度
&lt;/h1&gt;&lt;p&gt;通常,HTTP应答消息中发送的数据是整个发送的,&lt;code&gt;Content-Length&lt;/code&gt;消息头字段表示数据的长度.数据的长度很重要,因为客户端需要知道哪里是应答消息的结束,以及后续应答消息的开始.但是在一些动态网页中,由于网页是动态生成的,所以没法计算出准确的&lt;code&gt;Content-Length&lt;/code&gt;,这样导致的后果是:如果 &lt;code&gt;Content-Length&lt;/code&gt; 比实际长度短,会造成内容被截断;如果比实体内容长,会造成 pending,浏览器一直转圈圈.
所以在HTTP1.1中引入了&lt;code&gt;Transfer-Encoding&lt;/code&gt;,如果一个HTTP消息(请求消息或应答消息)的&lt;code&gt;Transfer-Encoding&lt;/code&gt;消息头的值为chunked,那么,消息体由数量未定的块组成,并以最后一个大小为0的块为结束.
ps:如果同时设置了&lt;code&gt;Content-Length&lt;/code&gt; 和&lt;code&gt;Transfer-Encoding&lt;/code&gt;,那么&lt;code&gt;Transfer-Encoding&lt;/code&gt;的优先级更高,&lt;code&gt;Content-Length&lt;/code&gt;会被忽略.&lt;/p&gt;
&lt;h1 id=&#34;5-缓存&#34;&gt;5 缓存
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;在HTTP/1.0中,使用&lt;code&gt;Expire&lt;/code&gt;头域来判断资源的&lt;code&gt;fresh&lt;/code&gt;或&lt;code&gt;stale&lt;/code&gt;,并使用条件请求(conditional request)来判断资源是否仍有效.例如,cache服务器通过&lt;code&gt;If-Modified-Since&lt;/code&gt;头域向服务器验证资源的&lt;code&gt;Last-Modefied&lt;/code&gt;头域是否有更新,源服务器可能返回304(Not Modified),则表明该对象仍有效;也可能返回200(OK)替换请求的Cache对象.&lt;/li&gt;
&lt;li&gt;此外,HTTP/1.0中还定义了&lt;code&gt;Pragma:no-cache&lt;/code&gt;头域,客户端使用该头域说明请求资源不能从cache中获取,而必须回源获取.&lt;/li&gt;
&lt;li&gt;HTTP/1.1在1.0的基础上加入了一些cache的新特性,当缓存对象的Age超过&lt;code&gt;Expire&lt;/code&gt;时变为&lt;code&gt;stale&lt;/code&gt;对象,cache不需要直接抛弃&lt;code&gt;stale&lt;/code&gt;对象,而是与源服务器进行重新激活(revalidation).&lt;/li&gt;
&lt;li&gt;HTTP/1.0中,&lt;code&gt;If-Modified-Since&lt;/code&gt;头域使用的是绝对时间戳,精确到秒,但使用绝对时间会带来不同机器上的时钟同步问题.而HTTP/1.1中引入了一个&lt;code&gt;ETag&lt;/code&gt;头域用于重激活机制,它的值&lt;code&gt;entity tag&lt;/code&gt;可以用来唯一的描述一个资源.请求消息中可以使用&lt;code&gt;If-None-Match&lt;/code&gt;头域来匹配资源的&lt;code&gt;entitytag&lt;/code&gt;是否有变化.&lt;/li&gt;
&lt;li&gt;为了使caching机制更加灵活,HTTP/1.1增加了&lt;code&gt;Cache-Control&lt;/code&gt;头域(请求消息和响应消息都可使用),它支持一个可扩展的指令子集：例如&lt;code&gt;max-age&lt;/code&gt;指令支持相对时间戳;&lt;code&gt;private&lt;/code&gt;和&lt;code&gt;no-store&lt;/code&gt;指令禁止对象被缓存;&lt;code&gt;no-transform&lt;/code&gt;阻止Proxy进行任何改变响应的行为.&lt;/li&gt;
&lt;li&gt;Cache使用关键字索引在磁盘中缓存的对象,在HTTP/1.0中使用资源的URL作为关键字.但可能存在不同的资源基于同一个URL的情况,要区别它们还需要客户端提供更多的信息,如&lt;code&gt;Accept-Language&lt;/code&gt;和&lt;code&gt;Accept-Charset&lt;/code&gt;头域.为了支持这种内容协商机制(content negotiation mechanism),HTTP/1.1在响应消息中引入了Vary头域,该头域列出了请求消息中需要包含哪些头域用于内容协商.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;HTTPs://imququ.com/post/transfer-encoding-header-in-HTTP.html&#34; &gt;HTTP 协议中的 Transfer-Encoding&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;http://blog.csdn.net/forgotaboutgirl/article/details/6936982&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;HTTP/1.1与HTTP/1.0的区别&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>解决倒水问题</title>
        <link>https://blog.huirongis.me/post/how-to-solve-the-water-problem/</link>
        <pubDate>Sat, 19 Mar 2016 12:48:58 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/how-to-solve-the-water-problem/</guid>
        <description>&lt;p&gt;有两个容器，容积分别为A升和B升，有无限多的水，现在需要C升水。
我们还有一个足够大的水缸，足够容纳C升水。起初它是空的，我们只能往水缸里倒入水，而不能倒出。
可以进行的操作是：
把一个容器灌满；
把一个容器清空（容器里剩余的水全部倒掉，或者倒入水缸）；
用一个容器的水倒入另外一个容器，直到倒出水的容器空或者倒入水的容器满。
问是否能够通过有限次操作，使得水缸最后恰好有C升水。&lt;/p&gt;
&lt;p&gt;这是很经典的智力题,各种倒水,求怎么倒.
网上有很多资料,我稍微总结下.&lt;/p&gt;
&lt;h1 id=&#34;1-是否有解&#34;&gt;1 是否有解
&lt;/h1&gt;&lt;p&gt;是的,不是任意的ABC值都是有解的,比如用4升和6升的容器,倒出5升水,这个方案就是无解的.
总结来说:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;倒水方案有解的,充要条件是:
C&amp;lt;=A+B并且
C能被A和B的最大公约数整除
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;比如上面的例子,4和6的公约数是2,5不能被2整除,所以是无解的.
具体证明过程请看文章后面的参考文献&lt;/p&gt;
&lt;h1 id=&#34;2-解法&#34;&gt;2 解法
&lt;/h1&gt;&lt;p&gt;有一个很简单的思路,在AB两个容器中,假设A&amp;lt;B,那么我们不停地用A往B中加水,溢出的时候,就把B清空,把A中多余部分导入B中.具体流程描述如下&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;A%B=x
2A%B=y
...
...
nA%B=z
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;知道最后余数z等于C,就停止
用一个具体的例子
&lt;code&gt;A=5&lt;/code&gt;,&lt;code&gt;B=9&lt;/code&gt;,&lt;code&gt;C=7&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;5%9=5
10%9=1
15%9=6
20%9=2
25%9=7
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;也就完成了查找
当然这个方法不是步数最少的解法&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;http://www.acmerblog.com/pour-water-problem-5615.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;倒水问题&lt;/a&gt;
&lt;a class=&#34;link&#34; href=&#34;http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;欧几里得和扩展欧几里得算法&lt;/a&gt;
&lt;a class=&#34;link&#34; href=&#34;http://www.cnblogs.com/drizzlecrj/archive/2007/09/14/892340.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;最大公约数的三种解法&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>php学习笔记(4)--php中cookie没有及时生效</title>
        <link>https://blog.huirongis.me/post/php-learn-note-5/</link>
        <pubDate>Sat, 19 Mar 2016 12:15:32 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/php-learn-note-5/</guid>
        <description>&lt;p&gt;update:2016/4/14 9:48:26
这是最近才在面试题中发现的一个问题,之前用的时候还没发现,仔细一想,有点意思.&lt;/p&gt;
&lt;h1 id=&#34;1-php中的cookie&#34;&gt;1 php中的cookie
&lt;/h1&gt;</description>
        </item>
        <item>
        <title>php学习笔记(4)--php使用mysqli连接数据库</title>
        <link>https://blog.huirongis.me/post/php-learn-note-4/</link>
        <pubDate>Sat, 12 Mar 2016 10:18:31 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/php-learn-note-4/</guid>
        <description>&lt;p&gt;long time no see,用上框架以后,好久没有写原生的sql处理了,想当年用的还是mysql_connect,如今,都已经换mysqli了.&lt;/p&gt;
&lt;h1 id=&#34;1-关于php的数据库连接方式&#34;&gt;1 关于php的数据库连接方式
&lt;/h1&gt;&lt;p&gt;当考虑连接到MySQL数据库服务器的时候，有三种主要的API可供选择：
1 PHP的MySQL扩展
2 PHP的mysqli扩展
3 PHP数据对象(PDO)&lt;/p&gt;
&lt;h2 id=&#34;11-什么是php的mysql扩展&#34;&gt;1.1 什么是PHP的MySQL扩展?
&lt;/h2&gt;&lt;p&gt;这是设计开发允许PHP应用与MySQL数据库交互的早期扩展。mysql扩展提供了一个面向过程 的接口，并且是针对MySQL4.1.3或更早版本设计的。因此，这个扩展虽然可以与MySQL4.1.3或更新的数据库服务端 进行交互，但并不支持后期MySQL服务端提供的一些特性。&lt;/p&gt;
&lt;h2 id=&#34;12-什么是php的mysqli扩展&#34;&gt;1.2 什么是PHP的mysqli扩展?
&lt;/h2&gt;&lt;p&gt;mysqli扩展，我们有时称之为MySQL增强扩展，可以用于使用MySQL4.1.3或更新版本中新的高级特性。mysqli扩展在PHP 5及以后版本中包含。
1   mysqli扩展有一系列的优势，相对于mysql扩展的提升主要有：
2   面向对象接口
3   prepared语句支持（译注：关于prepare请参阅mysql相关文档）
4   多语句执行支持
5   事务支持
6   增强的调试能力
7   嵌入式服务支持
在提供了面向对象接口的同时也提供了一个面向过程的接口。&lt;/p&gt;
&lt;h2 id=&#34;13-什么是pdo&#34;&gt;1.3 什么是PDO?
&lt;/h2&gt;&lt;p&gt;PHP数据对象，是PHP应用中的一个数据库抽象层规范。PDO提供了一个统一的API接口可以使得你的PHP应用不去关心具体要 连接的数据库服务器系统类型。也就是说，如果你使用PDO的API，可以在任何需要的时候无缝切换数据库服务器，比如从Firebird 到MySQL，仅仅需要修改很少的PHP代码。&lt;/p&gt;
&lt;p&gt;其他数据库抽象层的例子包括Java应用中的JDBC以及Perl中的DBI。&lt;/p&gt;
&lt;p&gt;当然，PDO也有它自己的先进性，比如一个干净的，简单的，可移植的API，它最主要的缺点是会限制让你不能使用 后期MySQL服务端提供所有的数据库高级特性。比如，PDO不允许使用MySQL支持的多语句执行。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1f1tvea7khyj20hm0dhac0.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;PHP中三种主要的MySQL连接方式的功能的比较&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>解决 Github Pages 禁止百度爬虫的方法2--从gitcafe迁移到coding.net</title>
        <link>https://blog.huirongis.me/post/migrate-pages-from-gitcafe-to-coding/</link>
        <pubDate>Sun, 06 Mar 2016 15:50:46 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/migrate-pages-from-gitcafe-to-coding/</guid>
        <description>&lt;p&gt;上一篇文章&lt;a class=&#34;link&#34; href=&#34;http://jackroyal.github.io/2015/11/25/how-to-solve-the-problem-that-github-blocks-the-baidu-spider/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;解决 Github Pages 禁止百度爬虫的方法&lt;/a&gt;,提到了解决百度爬虫被github禁用掉的方法.
&lt;code&gt;把博客同时发布到github pages和gitcafe pages.然后使用dnspod设置域名解析,国内线路解析到gitcafe,国外线路解析到github.&lt;/code&gt;
然后今天去上gitcafe,偶然看到这个
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1f1n79skvt3j20zl0m7k07.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;GitCafe 项目迁移至 Coding.net 公告&#34;
	
	
&gt;
额(⊙o⊙)…,holly shit.不过没办法,人家都被收购了,我们只能改变策略了.
话说,两家都是做代码托管的,这也是顺(bao)应(tuan)潮(qu)流(nuan)咩?&lt;/p&gt;
&lt;p&gt;思路跟原来差不多,就是我们把其中的gitcafe内容替换成coding.net就好,以下简称coding.
&lt;code&gt;把博客同时发布到github pages和coding pages.然后使用dnspod设置域名解析,国内线路解析到coding.net,国外线路解析到github.&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;注册coding账号&lt;/li&gt;
&lt;li&gt;新建一个项目,名字与你的用户名相同,比如我的名字是&lt;code&gt;Jackroyal&lt;/code&gt;,新建一个项目名为&lt;code&gt;Jackroyal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;添加ssh公钥&lt;/li&gt;
&lt;li&gt;新建coding-pages分支&lt;/li&gt;
&lt;li&gt;开启pages服务&lt;/li&gt;
&lt;li&gt;修改hexo配置&lt;/li&gt;
&lt;li&gt;修改dns设置&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&#34;1-注册coding账号&#34;&gt;1 注册coding账号
&lt;/h1&gt;&lt;p&gt;这个很简单不必说,注册需要填写用户名,邮箱和密码,比如我的用户名就是&lt;code&gt;Jackroyal&lt;/code&gt;&lt;/p&gt;
&lt;h1 id=&#34;2-新建和用户名同名的项目&#34;&gt;2 新建和用户名同名的项目
&lt;/h1&gt;&lt;p&gt;在注册好账号以后,我们就去新建一个项目,方法和gitcafe不同和gihub类似,就是和用户名同名,一模一样的就行.我的项目名是&lt;code&gt;Jackroyal&lt;/code&gt;,项目属性&lt;code&gt;公开&lt;/code&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1f1n8d42xljj20qb0hbmzc.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;新建同名项目&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;3-添加ssh公钥&#34;&gt;3 添加&lt;code&gt;ssh&lt;/code&gt;公钥
&lt;/h1&gt;&lt;p&gt;首先,我们提交代码库有两种方式,一种是https,一种是ssh,两种方式都可以,但是因为我们使用hexo来发布博客的时候是没有地方输入密码的,所以我们才考虑使用&lt;code&gt;ssh&lt;/code&gt;方式,不过也不一定,我们还是可以使用https方式来提交hexo的.&lt;/p&gt;
&lt;h2 id=&#34;31-使用ssh方式发布博客&#34;&gt;3.1 使用ssh方式发布博客
&lt;/h2&gt;&lt;p&gt;我们只需要找到本地的ssh公钥,然后上传到coding上去就行,点击&lt;a class=&#34;link&#34; href=&#34;https://coding.net/user/account/setting/keys&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这里&lt;/a&gt;设置.查看本地ssh公钥的方法和上篇博客一样.
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eye75djqo9j20gj09475k.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;使用git客户端查看ssh公钥私钥&#34;
	
	
&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eye7c2xpavj20if06dt9w.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;查看公钥&#34;
	
	
&gt;
复制那一段,然后在coding上添加上去就行&lt;/p&gt;
&lt;h2 id=&#34;32-使用https方式发布&#34;&gt;3.2 使用https方式发布
&lt;/h2&gt;&lt;p&gt;如果非要使用https方式,也是可以的,核心思路就是在本地做一次&lt;code&gt;push&lt;/code&gt;操作就行.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;我们先&lt;code&gt;git clone&lt;/code&gt;命令,我的项目就是&lt;code&gt;git clone https://git.coding.net/Jackroyal/Jackroyal.git&lt;/code&gt;得到coding上刚才新建的项目.&lt;/li&gt;
&lt;li&gt;克隆完成后,接着我们进到项目目录,我们新建一个文件或者修改一个文件&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git add .&lt;/code&gt;,把修改提交到暂存区&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git commit -m &amp;quot;测试提交&amp;quot;&lt;/code&gt;,将修改提交到本地仓库&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push&lt;/code&gt;,将修改提交到远程仓库&lt;/li&gt;
&lt;li&gt;接下来,会让你输入用户名和密码,你输入&lt;/li&gt;
&lt;li&gt;然后项目就会提交,因为这个状态会保留下来,你下次在提交就可以不用输入用户名和密码了,这样为我们使用hexo发布代码提供条件
ps:这种方式,可能过一段时间又不行了,报错&lt;code&gt;could not read Username for &#39;https://git.coding.net&#39;: Invalid argument&lt;/code&gt;,你再做一次上面的操作就行&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&#34;4-新建coding-pages分支&#34;&gt;4 新建coding-pages分支
&lt;/h1&gt;&lt;p&gt;当我们可以提交代码的时候,我们先来新建分支,和gitcafe差不多,它需要一个特别的分支名字,而不是像github默认的master分支,名字是&lt;code&gt;coding-pages&lt;/code&gt;,如下图所示
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1f1n965hcj0j210r0g3jvk.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;新建coding分支&#34;
	
	
&gt;
我们把它设为默认分支&lt;/p&gt;
&lt;h1 id=&#34;5-开启pages服务&#34;&gt;5 开启pages服务
&lt;/h1&gt;&lt;p&gt;接下来我们需要手动去开启pages服务.在项目主页的&lt;code&gt;pages&lt;/code&gt;选项卡,点击开启服务,同时我们,添加域名绑定
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1f1n98oezpej20sv0kxtdb.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;开启pages服务&#34;
	
	
&gt;
域名绑定我们还要去修改dns解析,我们先用它分配给我们的域名去访问&lt;a class=&#34;link&#34; href=&#34;http://jackroyal.coding.me/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://jackroyal.coding.me/&lt;/a&gt;,看看能不能正常访问&lt;/p&gt;
&lt;h1 id=&#34;5-修改hexo配置&#34;&gt;5 修改hexo配置
&lt;/h1&gt;&lt;p&gt;前面的准备工作做得差不多,我们修改博客的配置信息,打开博客根目录的&lt;code&gt;_config.yml&lt;/code&gt;文件,格式和之前github的差不多:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;deploy:
- type: git
  repo: &amp;#39;https://github.com/Jackroyal/Jackroyal.github.io.git&amp;#39;
  branch: master
- type: git
  repo: &amp;#39;https://git.coding.net/Jackroyal/Jackroyal.git&amp;#39;
  branch: coding-pages
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;尤其注意在配置的时候注意留空格,这种键值对,比如&lt;code&gt;type: git&lt;/code&gt;,其中的冒号后面到git,有个空格的,不然配置文件就会读取错误.
还要注意branch名称,分支必须是&lt;code&gt;coding-pages&lt;/code&gt;
**PS:如上面所说,我选择的是https方式发布,所以我的repo是https的,如果你选择ssh方式去认证,那么你的地址应该是类似这样的&lt;code&gt;git@git.coding.net:Jackroyal/Jackroyal.git&lt;/code&gt;
**&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1f1n9byao2wj20o00gqn0e.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;添加coding的repo信息&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;7-修改dns设置&#34;&gt;7 修改dns设置
&lt;/h1&gt;&lt;p&gt;就像第5步页面提示的,我们要绑定自己的域名,需要去修改dns解析记录,只需要添加一条CNAME指向你的&lt;code&gt;jackroyal.coding.me&lt;/code&gt;即可.
注意后面加个点,也就是正确的填法是&lt;code&gt;jackroyal.coding.me.&lt;/code&gt;,如下图所示.修改完成后大概等几分钟才能生效
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1f1n9m6me2ej20nv09c0us.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;修改dns设置&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;8-从gitcafe迁移&#34;&gt;8 从gitcafe迁移
&lt;/h1&gt;&lt;p&gt;如果我们选择从gitcafe迁移的话,他会把我们原来的博客迁移过来.为了适应coding,你只需要从上面第二步开始就好,尤其注意的是,&lt;code&gt;新建coding-pages分支&lt;/code&gt;,&lt;code&gt;新建coding-pages分支&lt;/code&gt;,&lt;code&gt;新建coding-pages分支&lt;/code&gt;,重要的事情说三遍,因为你迁移过来的分支名称是&lt;code&gt;gitcafe-pages&lt;/code&gt;.
也就是核心问题,必须有个和用户名同名的项目,项目必须有个分支是&lt;code&gt;coding-pages&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;其他没提的事情和上一篇是一样的.
最后执行&lt;code&gt;hexo d -g&lt;/code&gt;,打完收工&lt;/p&gt;
</description>
        </item>
        <item>
        <title>php学习笔记(3.5)--关于引用赋值和一般赋值</title>
        <link>https://blog.huirongis.me/post/php-learn-note-3-5/</link>
        <pubDate>Sat, 05 Mar 2016 13:52:28 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/php-learn-note-3-5/</guid>
        <description>&lt;p&gt;上一篇提到了,对象赋值的时候有两种赋值方式,一种是直接&lt;code&gt;$a=$b&lt;/code&gt;,第二种是引用赋值&lt;code&gt;$a=&amp;amp;$b&lt;/code&gt;.
不仅对象赋值的时候会有这两种情况,普通变量赋值也会有这两种情况,为了简单说明,我们先使用简单的普通变量来做说明.&lt;/p&gt;
&lt;h1 id=&#34;1-普通变量的结构&#34;&gt;1 普通变量的结构
&lt;/h1&gt;&lt;p&gt;在PHP中,所有的变量都是用一个结构zval来保存的,zval大概的结构如下所示:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; _zval_struct {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;/* Variable information */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        zvalue_value value;             &lt;span style=&#34;color:#75715e&#34;&gt;/* value */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        zend_uint refcount;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        zend_uchar type;        &lt;span style=&#34;color:#75715e&#34;&gt;/* active type */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        zend_uchar is_ref;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们这里主要用到的是两个变量,一个是refcount,即是引用计数,一个是is_ref,用来标记是否是引用.&lt;/p&gt;
&lt;h1 id=&#34;2-php环境的设置&#34;&gt;2 php环境的设置
&lt;/h1&gt;&lt;p&gt;我们在实验过程中,需要去查看refcount和is_ref的变化,所以需要使用php的
&lt;code&gt;xdebug_debug_zval&lt;/code&gt;函数,你的环境可能默认没有开启这个配置,你需要修改&lt;code&gt;php.ini&lt;/code&gt;文件开启这个配置.
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1f1m1ximwj1j20wn098dj6.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;修改php.ini文件&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;3-refcount和is_ref&#34;&gt;3 refcount和is_ref
&lt;/h1&gt;&lt;p&gt;我们通常的赋值方式:一般赋值和引用赋值.&lt;/p&gt;
&lt;h1 id=&#34;31-一般赋值&#34;&gt;3.1 一般赋值
&lt;/h1&gt;&lt;p&gt;当使用一般给新变量赋值的时候,php的内存策略,并不是重新申请一个新的空间,而是把原来的那个recount+1.比如下面的例子:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;aaa&amp;#39;&lt;/span&gt;;&lt;span style=&#34;color:#75715e&#34;&gt;//此时$a的recount=1,ref=0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;$b&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$a;&lt;span style=&#34;color:#75715e&#34;&gt;//赋值过后,$a的recount=2,ref=0,$b因为指向和$a一样,所以结果和$a一样
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xdebug_debug_zval&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;输出结果如下&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(refcount=2, is_ref=0),string &amp;#39;aaa&amp;#39; (length=3)
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;32-引用赋值&#34;&gt;3.2 引用赋值
&lt;/h1&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;aaa&amp;#39;&lt;/span&gt;;&lt;span style=&#34;color:#75715e&#34;&gt;//此时$a的recount=1,ref=0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;$c&lt;span style=&#34;color:#f92672&#34;&gt;=&amp;amp;&lt;/span&gt;$a;&lt;span style=&#34;color:#75715e&#34;&gt;//赋值过后,$a的recount=2,ref=0,$b因为指向和$a一样,所以结果和$a一样
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xdebug_debug_zval&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;);&lt;span style=&#34;color:#75715e&#34;&gt;//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;输出结果如下&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(refcount=2, is_ref=1),string &amp;#39;aaa&amp;#39; (length=3)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;由上面可知,也就是每次进行赋值的时候,refcount都会+1,如果是引用赋值,is_ref就会被置为一.&lt;/p&gt;
&lt;h1 id=&#34;33-两种赋值方式混合&#34;&gt;3.3 两种赋值方式混合
&lt;/h1&gt;&lt;p&gt;那如果我们混合上面的两种赋值方式呢?比如下面的代码&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;aaa&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$b&lt;span style=&#34;color:#f92672&#34;&gt;=&amp;amp;&lt;/span&gt;$a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$c&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xdebug_debug_zval&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;你猜输出结果是什么?&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;a: (refcount=2, is_ref=1),string &amp;#39;aaa&amp;#39; (length=3)

b: (refcount=2, is_ref=1),string &amp;#39;aaa&amp;#39; (length=3)

c: (refcount=1, is_ref=0),string &amp;#39;aaa&amp;#39; (length=3)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;为什么会这样呢?
我们一行一行的分析.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;首先第一行代码执行完以后,$a的结果应该是&lt;code&gt;(refcount=1, is_ref=0),string &#39;aaa&#39; (length=3)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;第二行代码执行引用赋值,因为refcount=1,所以$a的refcount直接+1,is_ref变成1,输出即是`(refcount=2, is_ref=1),string &amp;lsquo;aaa&amp;rsquo;&lt;/li&gt;
&lt;li&gt;第三行代码执行一般赋值,那我们是不是再把refcount+1呢?不是的,因为此时的refcount&amp;gt;1并且is_ref不为0,所以不能执行那个操作,而是直接把$a复制了另外一份,而不是修改$a的计数器.
所以,最后的输出结果,$c的refcount是1,因为它完全另外申请了一个副本&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我们把上面的代码换个位置&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;aaa&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$c&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$b&lt;span style=&#34;color:#f92672&#34;&gt;=&amp;amp;&lt;/span&gt;$a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xdebug_debug_zval&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;你再猜猜输出结果是什么?&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;a: (refcount=2, is_ref=1),string &amp;#39;aaa&amp;#39; (length=3)

b: (refcount=2, is_ref=1),string &amp;#39;aaa&amp;#39; (length=3)

c: (refcount=1, is_ref=0),string &amp;#39;aaa&amp;#39; (length=3)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;咦?结果是一样的哈?
对的,结果是一样的,不过执行的过程却是不同的,我们再来一行一行的分析下&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;首先第一行代码执行完以后,$a的结果应该是&lt;code&gt;(refcount=1, is_ref=0),string &#39;aaa&#39; (length=3)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;第二行代码执行一般赋值,同理,因为refcount=1,所以$a的refcount直接+1,is_ref不变,输出即是`(refcount=2, is_ref=0),string &amp;lsquo;aaa&amp;rsquo;&lt;/li&gt;
&lt;li&gt;第三行代码执行引用赋值,跟上面一样,因为refcount=2了,所以不能直接进行计数器+1,我们先检查is_ref,发现是0.这时,php首先做一个分离操作,也就是把上面一般赋值的那个值,给分离出去,分离后,$a的refcount减去1,也就是$c独立了,那么此时$a和$c的输出结果应该是&lt;code&gt;(refcount=1, is_ref=0),string &#39;aaa&#39; (length=3)&lt;/code&gt;.在分离操作完成后,再做引用赋值的问题,这时候就简单了,因为$a的refcount是1,所以我们直接refcount+1,is_ref=1就搞定&lt;/li&gt;
&lt;li&gt;最后输出结果就是上面的结果了&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;php把上面的过程叫做写时复制(copy on write),也就是说,一般赋值$c=$a时候,php并不是立即去申请一个新的变量空间.,而是等到执行引用赋值或者其他写操作的时候(比如这个时候修改$c的值),php才会去开辟一个新的空间给赋值后的变量,也就是分离操作.&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id=&#34;4-推广到对象&#34;&gt;4 推广到对象
&lt;/h1&gt;&lt;p&gt;上面普通变量的赋值,应该说清楚了哈.
其实对象的赋值和普通变量赋值是同一个道理.下面直接贴代码,不在赘述&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; $aa&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;我是类属性&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;刚执行完$a定义&amp;lt;br&amp;gt;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xdebug_debug_zval&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$b&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;刚执行完$b赋值&amp;lt;br&amp;gt;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xdebug_debug_zval&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$c&lt;span style=&#34;color:#f92672&#34;&gt;=&amp;amp;&lt;/span&gt;$a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;刚执行完$c赋值&amp;lt;br&amp;gt;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xdebug_debug_zval&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$d&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$b;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;刚执行完$d赋值&amp;lt;br&amp;gt;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xdebug_debug_zval&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;d&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;输出结果如下&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;刚执行完$a定义
a: 
(refcount=1, is_ref=0),
object(A)[1]
  public &amp;#39;aa&amp;#39; =&amp;gt; (refcount=1, is_ref=0),string &amp;#39;我是类属性&amp;#39; (length=15)

刚执行完$b赋值
b: 
(refcount=2, is_ref=0),
object(A)[1]
  public &amp;#39;aa&amp;#39; =&amp;gt; (refcount=1, is_ref=0),string &amp;#39;我是类属性&amp;#39; (length=15)

刚执行完$c赋值
c: 
(refcount=2, is_ref=1),
object(A)[1]
  public &amp;#39;aa&amp;#39; =&amp;gt; (refcount=1, is_ref=0),string &amp;#39;我是类属性&amp;#39; (length=15)

刚执行完$d赋值
a: 
(refcount=2, is_ref=1),
object(A)[1]
  public &amp;#39;aa&amp;#39; =&amp;gt; (refcount=1, is_ref=0),string &amp;#39;我是类属性&amp;#39; (length=15)

b: 
(refcount=2, is_ref=0),
object(A)[1]
  public &amp;#39;aa&amp;#39; =&amp;gt; (refcount=1, is_ref=0),string &amp;#39;我是类属性&amp;#39; (length=15)

c: 
(refcount=2, is_ref=1),
object(A)[1]
  public &amp;#39;aa&amp;#39; =&amp;gt; (refcount=1, is_ref=0),string &amp;#39;我是类属性&amp;#39; (length=15)

d: 
(refcount=2, is_ref=0),
object(A)[1]
  public &amp;#39;aa&amp;#39; =&amp;gt; (refcount=1, is_ref=0),string &amp;#39;我是类属性&amp;#39; (length=15)
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;5-关于debug_zval_dump函数&#34;&gt;5 关于debug_zval_dump函数
&lt;/h1&gt;&lt;p&gt;php中还有个关于计数的函数叫做&lt;code&gt;debug_zval_dump&lt;/code&gt;,它只返回refcount,不过这个函数好奇葩,输出的数据有时候跟想的都不一样.
比如:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;aaa&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$b&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;debug_zval_dump&lt;/span&gt;($a);&lt;span style=&#34;color:#75715e&#34;&gt;//输出3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;?&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;原因是:执行&lt;code&gt;debug_zval_dump&lt;/code&gt;相当于执行了一次一般赋值操作,所以,refcount会再加1
再比如&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;aaa&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$c&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$c&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;bbb&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;debug_zval_dump&lt;/span&gt;($a,$c);&lt;span style=&#34;color:#75715e&#34;&gt;//输出refcount=2,refcount=2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xdebug_debug_zval&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;);&lt;span style=&#34;color:#75715e&#34;&gt;//两个值完全相同,都是refcount=1, is_ref=0),string &amp;#39;bbb&amp;#39; (length=3)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;额,这是不是很奇葩?再来一波&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;aaa&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$b&lt;span style=&#34;color:#f92672&#34;&gt;=&amp;amp;&lt;/span&gt;$a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$c&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;debug_zval_dump&lt;/span&gt;($a,$b,$c);&lt;span style=&#34;color:#75715e&#34;&gt;//refcount分别是1,1,2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xdebug_debug_zval&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;);&lt;span style=&#34;color:#75715e&#34;&gt;//refcount和is_ref分别是(2,1),(2,1),(1,0)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这是什么鬼?我表示都看不懂
稍微总结了下,&lt;code&gt;debug_zval_dump&lt;/code&gt;这个函数,如果只是一般赋值,那么还比较正常,赋值一次就是refcount+1操作,最后调用&lt;code&gt;debug_zval_dump&lt;/code&gt;的再+1就好了
但是一旦涉及到引用赋值,这货就全变成1了,(引用赋值不+1就算了,说好的调用&lt;code&gt;debug_zval_dump&lt;/code&gt;的+1呢?被狗吃了?),完全搞不懂是在搞啥,还是&lt;code&gt;xdebug_debug_zval&lt;/code&gt;函数好.
打完收工
ps:其实我在知乎提了个问题,不过没人回答还&lt;a class=&#34;link&#34; href=&#34;http://www.zhihu.com/question/41044486&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;debug_zval_dump的计数问题?&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;http://www.laruence.com/2008/09/19/520.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;鸟哥的博客&amp;ndash;深入理解PHP原理之变量分离/引用&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;http://weizhifeng.net/write-php-extension-part2-2.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;PHP扩展编写第二步：参数，数组，以及ZVAL「续」&lt;/a&gt;
3 &lt;a class=&#34;link&#34; href=&#34;http://php.net/manual/zh/function.debug-zval-dump.php&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;php官方文档&amp;ndash;debug_zval_dump函数&lt;/a&gt;
4 &lt;a class=&#34;link&#34; href=&#34;https://derickrethans.nl/talks/phparch-php-variables-article.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;英文文档&amp;ndash;php变量&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>php学习笔记(3)</title>
        <link>https://blog.huirongis.me/post/php-learn-note-3/</link>
        <pubDate>Fri, 04 Mar 2016 10:06:40 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/php-learn-note-3/</guid>
        <description>&lt;p&gt;今天开始学习类和面向对象了.&lt;/p&gt;
&lt;h1 id=&#34;1-对象实例化&#34;&gt;1 对象实例化
&lt;/h1&gt;&lt;p&gt;在实例化对象的时候,必须使用&lt;code&gt;new&lt;/code&gt;关键字.如果该类属于一个名字空间,则必须使用其完整名称.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$instance &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;SimpleClass&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 也可以这样做：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;$className &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Foo&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$instance &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; $className(); &lt;span style=&#34;color:#75715e&#34;&gt;// Foo()
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;?&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;11-对象赋值&#34;&gt;1.1 对象赋值
&lt;/h2&gt;&lt;p&gt;我们创建一个对象的实例后,后面进行赋值的时候有两种赋值.
第一种是直接&lt;code&gt;$a=$b&lt;/code&gt;,第二种是引用赋值&lt;code&gt;$a=&amp;amp;$b&lt;/code&gt;.
这两个有什么区别呢?问题可深了,所以我决定单独写一篇文章来说这个问题.
&lt;a class=&#34;link&#34; href=&#34;http://jackroyal.github.io/2016/03/05/php-learn-note-3-5/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;php学习笔记(3.5)&amp;ndash;关于引用赋值和一般赋值&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;12-extends关键字&#34;&gt;1.2 extends关键字
&lt;/h2&gt;&lt;p&gt;一个类可以在声明中用 extends 关键字继承另一个类的方法和属性.&lt;em&gt;PHP不支持多重继承,一个类只能继承一个基类.&lt;/em&gt;
被继承的方法和属性可以通过用同样的名字重新声明被覆盖.但是如果父类定义方法时使用了 final,则该方法不可被覆盖.可以通过 parent:: 来访问被覆盖的方法或属性.
当覆盖方法时,参数必须保持一致否则 PHP 将发出 E_STRICT 级别的错误信息.但构造函数例外,构造函数可在被覆盖时使用不同的参数.&lt;/p&gt;
&lt;h1 id=&#34;2-属性&#34;&gt;2 属性
&lt;/h1&gt;&lt;p&gt;类的变量成员叫做属性,属性声明是由关键字public,protected或者private开头,然后跟一个普通的变量声明来组成,尤其需要注意的是,属性的变量可以初始化,但是初始化值必须是常数,也就是不能有表达式比如下面的就是错误的:
&lt;code&gt;public $var1 = &#39;hello &#39; . &#39;world&#39;;&lt;/code&gt;,&lt;code&gt;public $var3 = 1+2;&lt;/code&gt;.
在php5.3之后,nowdocs的结构也是可行的.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>php学习笔记(2)</title>
        <link>https://blog.huirongis.me/post/php-learn-note-2/</link>
        <pubDate>Thu, 25 Feb 2016 14:36:20 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/php-learn-note-2/</guid>
        <description>&lt;p&gt;今天看的是最基础的变量.&lt;/p&gt;
&lt;h1 id=&#34;1-php变量&#34;&gt;1 php变量
&lt;/h1&gt;&lt;p&gt;和其他语言类似,php中一个有效的变量名由字母或者下划线开头,后面跟上任意数量的字母,数字,或者下划线.按照正常的正则表达式,它将被表述为：&amp;rsquo;[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*&amp;rsquo;.
赋值的时候,变量默认总是&lt;code&gt;传值赋值&lt;/code&gt;.
在php中也可以用&lt;code&gt;引用赋值&lt;/code&gt;,也就是改动新的变量也会因想到原始变量,反之亦然.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$foo &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Bob&amp;#39;&lt;/span&gt;;              &lt;span style=&#34;color:#75715e&#34;&gt;// 将 &amp;#39;Bob&amp;#39; 赋给 $foo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;$bar &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;$foo;              &lt;span style=&#34;color:#75715e&#34;&gt;// 通过 $bar 引用 $foo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;$bar &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;My name is &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;$bar&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;;  &lt;span style=&#34;color:#75715e&#34;&gt;// 修改 $bar 变量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; $bar;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; $foo;                 &lt;span style=&#34;color:#75715e&#34;&gt;// $foo 的值也被修改
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;?&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ps:只有有名字的变量才可以使用引用赋值,也就是无法对一个表达式使用引用赋值.
使用&lt;code&gt;isset()&lt;/code&gt;来检测变量是否被初始化.&lt;/p&gt;
&lt;h1 id=&#34;2-预定义变量&#34;&gt;2 预定义变量
&lt;/h1&gt;&lt;p&gt;php会自动用下划线来替换所有的传入变量中的&lt;code&gt;.&lt;/code&gt;号,例子如下所示&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;example&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;com&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;page&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;php&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;?&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;chuck&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;norris&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;nevercries&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;you&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;can&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;reference&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;them&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;by&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;the&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;used&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;the&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;URI&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//INCORRECT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; $_GET[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;chuck.norris&amp;#39;&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;instead&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;you&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;must&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//CORRECT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; $_GET[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;chuck_norris&amp;#39;&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;?&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;3-变量范围&#34;&gt;3 变量范围
&lt;/h1&gt;&lt;p&gt;变量的范围即它定义的上下文背景（也就是它的生效范围）.大部分的 PHP 变量只有一个单独的范围.这个单独的范围跨度同样包含了 include 和 require 引入的文件.例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;include&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b.inc&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;?&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里变量 $a 将会在包含文件 b.inc 中生效.但是,在用户自定义函数中,一个局部函数范围将被引入.任何用于函数内部的变量按缺省情况将被限制在局部函数范围内.例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;/* global scope */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Test&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; $a; &lt;span style=&#34;color:#75715e&#34;&gt;/* reference to local scope variable */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Test&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;?&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个脚本不会有任何输出,因为 &lt;code&gt;echo&lt;/code&gt;语句引用了一个局部版本的变量$a,而且在这个范围内,它并没有被赋值.你可能注意到 PHP 的全局变量和 C 语言有一点点不同,在 C 语言中,全局变量在函数中自动生效,除非被局部变量覆盖.这可能引起一些问题,有些人可能不小心就改变了一个全局变量.PHP 中全局变量在函数中使用时必须声明为 &lt;code&gt;global&lt;/code&gt;.
PS:此处需要注意的是,php不存在类似C和java的块级作用域.比如你在循环中定义的一个变量,在循环外还是可以访问的&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt;($j&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; $j&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;; $j&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;($j &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        $a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; $a;&lt;span style=&#34;color:#75715e&#34;&gt;//此处将会输出4
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;?&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;32-静态变量&#34;&gt;3.2 静态变量
&lt;/h2&gt;&lt;p&gt;php还支持静态变量,静态变量&lt;code&gt;仅在局部函数域中&lt;/code&gt;存在,但当程序执行离开此作用域时,其值并不丢失.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Test&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    $a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;echo&lt;/span&gt; $a;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    $a&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;?&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;4-来自php之外的变量&#34;&gt;4 来自PHP之外的变量
&lt;/h1&gt;&lt;p&gt;此处主要指的是通过表单提交的变量,从cookie读取的变量&lt;/p&gt;
&lt;h2 id=&#34;41-图片提交表单&#34;&gt;4.1 图片提交表单
&lt;/h2&gt;&lt;p&gt;除了常用的通过表单按钮提交表单,我们还可以使用图片的形式提交表单,代码如下:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;input&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;image&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;src&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;image.gif&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;sub&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样在后端接收的时候,还会受到一个叫做&lt;code&gt;sub_x&lt;/code&gt;和&lt;code&gt;sub_y&lt;/code&gt;的变量,它包含了用户点击图片的坐标.此处如果你不定义&lt;code&gt;name&lt;/code&gt;为&lt;code&gt;sub&lt;/code&gt;,那么后端接收变量就是&lt;code&gt;x&lt;/code&gt;和&lt;code&gt;y&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&#34;42-php自动转换变量名&#34;&gt;4.2 PHP自动转换变量名
&lt;/h1&gt;&lt;p&gt;当我们通过表单提交变量的时候,如果表单项的名称包含空格,点号,左中括号,php就会自动把他们转换成下划线.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;input&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;userName.a&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;input&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;passWor[d&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;//输出[userName_a] =&amp;gt; [passWor_d] =&amp;gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;//都被转化成下划线了
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;chr(32) ( ) (space)
chr(46) (.) (dot)
chr(91) ([) (open square bracket)&lt;/p&gt;
&lt;p&gt;ps:ascll码值在128-159的字符是合法字符,所以并不会被转义成下划线&lt;/p&gt;
</description>
        </item>
        <item>
        <title>digitalocean下ubuntu切换内核,使用锐速</title>
        <link>https://blog.huirongis.me/post/digitalocean-switch-kernel/</link>
        <pubDate>Thu, 28 Jan 2016 16:59:10 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/digitalocean-switch-kernel/</guid>
        <description>&lt;p&gt;最近在网上看到,锐速可以用来给服务器加速,然后有人用这个软件来给翻墙服务器加速,据说效果还不错,今天就折腾一下.&lt;/p&gt;
&lt;p&gt;我去锐速官网注册了账号,可惜,在官方支持的linux版本中并没有我这个内核版本.我用的是&lt;code&gt;3.13.0-37-generic&lt;/code&gt;的&lt;code&gt;32&lt;/code&gt;位版本,锐速官网并没有支持.&lt;code&gt;32&lt;/code&gt;位版本支持的相对较少,支持的最新版本是&lt;code&gt;3.13.0-29-generic&lt;/code&gt;.
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1f0fbk1mp65j213c0ozdru.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;锐速官网linux支持列表&#34;
	
	
&gt;
所以没办法,只能把我的&lt;code&gt;ubuntu&lt;/code&gt;降级回去,还是小折腾了一下.下面就来说下降级&lt;/p&gt;
&lt;h1 id=&#34;实验环境&#34;&gt;实验环境：
&lt;/h1&gt;&lt;p&gt;digitalocean的云服务器
Linux OS:   Ubuntu
Version:    14.04
Kernel:     3.13.0-37-generic
Bits:       32-bit&lt;/p&gt;
&lt;h1 id=&#34;实验步骤&#34;&gt;实验步骤
&lt;/h1&gt;&lt;p&gt;ssh登录服务器,然后安装新内核,blablabla&amp;hellip;
你要是这样想就跟我一样,想错了.
因为我们使用的是&lt;code&gt;digitalocean&lt;/code&gt;的云服务器,不是普通的个人单机,所以那套方法不顶用,我照着那个方法,安装了新的内核,然后更新&lt;code&gt;grub&lt;/code&gt;,怎么弄都没用,最后才找到答案.
&lt;strong&gt;争取的做法:&lt;/strong&gt;
1 登录你的&lt;code&gt;digitalocean&lt;/code&gt;控制台
2 点击&lt;code&gt;setting-&amp;gt;kernel&lt;/code&gt;,效果如下图
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1f0fbvo209sj20vd0kkdkf.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;控制台的kernel页面&#34;
	
	
&gt;
3 点击下拉列表,找到你要的&lt;code&gt;kernel&lt;/code&gt;,比如我要的是&lt;code&gt;Ubuntu 14.04 x32 vmlinuz-3.13.0-29-generic&lt;/code&gt;,然后点击&lt;code&gt;change&lt;/code&gt;,等一会儿,页面会自动刷新,内核更新就成功了
4 重要的一步,我就是这步有点问题,又浪费了点时间.更新完内核,我们发现自己的服务器查看内核的时候并没有变化,我们首先想到的是重启服务器.我们直接在终端&lt;code&gt;sudo reboot&lt;/code&gt;.但是启动以后,你会发现还是没有变化,什么鬼?
真正的答案是,我们现在终端关机,也即是执行&lt;code&gt;sudo poweroff&lt;/code&gt;,先关机.然后我们在控制台的power选项卡中,有个&lt;code&gt;power on&lt;/code&gt;的按钮,我们启动服务器,就发现内核已经更新了.
ok 打完收工&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;https://www.digitalocean.com/community/tutorials/how-to-upgrade-ubuntu-12-04-lts-to-ubuntu-14-04-lts&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;How to Upgrade Ubuntu 12.04 LTS to Ubuntu 14.04 LTS&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;https://www.digitalocean.com/community/tutorials/how-to-update-a-digitalocean-server-s-kernel&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;How To Update a DigitalOcean Server&amp;rsquo;s Kernel&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>php学习笔记(1)</title>
        <link>https://blog.huirongis.me/post/php-learn-note-1/</link>
        <pubDate>Thu, 10 Dec 2015 15:46:03 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/php-learn-note-1/</guid>
        <description>&lt;p&gt;php文档学习笔记,正式开始连载了哈,终于开始学习了.&lt;/p&gt;
&lt;h1 id=&#34;布尔值&#34;&gt;布尔值
&lt;/h1&gt;&lt;p&gt;要明确地将一个值转换成 boolean，用 (bool) 或者 (boolean) 来强制转换。但是很多情况下不需要用强制转换，因为当运算符，函数或者流程控制结构需要一个 boolean 参数时，该值会被自动转换。
当转换为 boolean 时，以下值被认为是 FALSE：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;布尔值 &lt;strong&gt;FALSE&lt;/strong&gt; 本身&lt;/li&gt;
&lt;li&gt;整型值 &lt;strong&gt;0&lt;/strong&gt;（零）&lt;/li&gt;
&lt;li&gt;浮点型值 &lt;strong&gt;0.0&lt;/strong&gt;（零）&lt;/li&gt;
&lt;li&gt;空字符串，以及字符串 &lt;strong&gt;&amp;ldquo;0&amp;rdquo;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;不包括任何元素的数组&lt;/li&gt;
&lt;li&gt;不包括任何成员变量的对象（仅 PHP 4.0 适用）&lt;/li&gt;
&lt;li&gt;特殊类型 &lt;strong&gt;NULL&lt;/strong&gt;（包括尚未赋值的变量）&lt;/li&gt;
&lt;li&gt;从空标记生成的 &lt;strong&gt;SimpleXML&lt;/strong&gt; 对象&lt;/li&gt;
&lt;li&gt;所有其它值都被认为是 &lt;strong&gt;TRUE&lt;/strong&gt;（包括任何资源）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;PS:&lt;/strong&gt;
-1 和其它非零值（不论正负）一样，被认为是 &lt;strong&gt;TRUE&lt;/strong&gt;！
接下来我们可以试试,自己写一些常见的布尔值&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;var_dump&lt;/span&gt;((&lt;span style=&#34;color:#a6e22e&#34;&gt;bool&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;);        &lt;span style=&#34;color:#75715e&#34;&gt;//false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;var_dump&lt;/span&gt;((&lt;span style=&#34;color:#a6e22e&#34;&gt;bool&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;0.0&amp;#39;&lt;/span&gt;);      &lt;span style=&#34;color:#75715e&#34;&gt;//true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;var_dump&lt;/span&gt;((&lt;span style=&#34;color:#a6e22e&#34;&gt;bool&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;0.1&amp;#39;&lt;/span&gt;);      &lt;span style=&#34;color:#75715e&#34;&gt;//true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;var_dump&lt;/span&gt;((&lt;span style=&#34;color:#a6e22e&#34;&gt;bool&lt;/span&gt;)&lt;span style=&#34;color:#66d9ef&#34;&gt;array&lt;/span&gt;());    &lt;span style=&#34;color:#75715e&#34;&gt;//false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;var_dump&lt;/span&gt;((&lt;span style=&#34;color:#a6e22e&#34;&gt;bool&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;false&amp;#34;&lt;/span&gt;);    &lt;span style=&#34;color:#75715e&#34;&gt;//true,因为这个字符串不为空,所以为true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
        </item>
        <item>
        <title>那些年,我们玩过的离线安装</title>
        <link>https://blog.huirongis.me/post/offline-install/</link>
        <pubDate>Thu, 26 Nov 2015 13:34:46 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/offline-install/</guid>
        <description>&lt;p&gt;由于有些软件,都是下载一个安装器,然后在线安装,由于网速的原因,这种方式一旦失败,就只能重新安装,所以很坑,就找了些离线安装的方法&lt;/p&gt;
&lt;h1 id=&#34;1-adobe-reader离线安装&#34;&gt;1 Adobe reader离线安装
&lt;/h1&gt;&lt;p&gt;下载离线安装版adobe reader
&lt;a class=&#34;link&#34; href=&#34;https://get.adobe.com/cn/reader/enterprise/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://get.adobe.com/cn/reader/enterprise/&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;2-chrome离线安装&#34;&gt;2 chrome离线安装
&lt;/h1&gt;&lt;p&gt;Windows平台：&lt;/p&gt;
&lt;p&gt;Chrome 离线安装包（仅 Windows 可用）：
最新稳定版（Stable Channel）：
&lt;a class=&#34;link&#34; href=&#34;http://www.google.com/chrome/eula.html?hl=zh-CN&amp;amp;standalone=1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://www.google.com/chrome/eula.html?hl=zh-CN&amp;standalone=1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;最新测试版（Beta Channel）：
&lt;a class=&#34;link&#34; href=&#34;http://www.google.com/chrome/eula.html?hl=zh-CN&amp;amp;standalone=1&amp;amp;extra=betachannel&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://www.google.com/chrome/eula.html?hl=zh-CN&amp;standalone=1&amp;extra=betachannel&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;最新开发版（Dev Channel）：
&lt;a class=&#34;link&#34; href=&#34;http://www.google.com/chrome/eula.html?hl=zh-CN&amp;amp;standalone=1&amp;amp;extra=devchannel&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://www.google.com/chrome/eula.html?hl=zh-CN&amp;standalone=1&amp;extra=devchannel&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>解决 Github Pages 禁止百度爬虫的方法</title>
        <link>https://blog.huirongis.me/post/how-to-solve-the-problem-that-github-blocks-the-baidu-spider/</link>
        <pubDate>Wed, 25 Nov 2015 11:06:50 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/how-to-solve-the-problem-that-github-blocks-the-baidu-spider/</guid>
        <description>&lt;p&gt;&lt;em&gt;update&lt;/em&gt;:因为gitcafe在5月31号就关闭了,所以要将文章中的gitcafe换掉,我重新写了一篇,在这里&lt;a class=&#34;link&#34; href=&#34;http://jackroyal.github.io/2016/03/06/migrate-pages-from-gitcafe-to-coding/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;解决 Github Pages 禁止百度爬虫的方法2&amp;ndash;从gitcafe迁移到coding.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;最近,我的github student package里面送的一个namecheap域名终于下来了.That is to say:我终于有自己的域名了,这就是我的域名&lt;a class=&#34;link&#34; href=&#34;http://bblove.me&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://bblove.me&lt;/a&gt;,欢迎来访.&lt;/p&gt;
&lt;p&gt;有域名以后,就在想办法解决百度爬虫的问题.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Hi Jackroyal,

We are currently blocking the Baidu user agent from crawling GitHub Pages
sites in response to this user agent being responsible for an excessive amount
of requests, which was causing availability issues for other GitHub customers.
This is unlikely to change any time soon, so if you need the Baidu user agent
to be able to crawl your site you will need to host it elsewhere.

Cheers,
Scott
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这是我之前跟github反映百度spider无法抓取我的github pages,他们给我的回复邮件.也就是说他们把百度spider给禁掉了,桑不起.
直接说解决方法:
&lt;code&gt;把博客同时发布到github pages和gitcafe pages.然后使用dnspod设置域名解析,国内线路解析到gitcafe,国外线路解析到github.&lt;/code&gt;&lt;/p&gt;
&lt;h1 id=&#34;实现方法&#34;&gt;实现方法
&lt;/h1&gt;&lt;h1 id=&#34;1-准备条件&#34;&gt;1 准备条件
&lt;/h1&gt;&lt;p&gt;一共需要一下这几个东西:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个github账户&lt;/li&gt;
&lt;li&gt;一个gitcafe账户&lt;/li&gt;
&lt;li&gt;一个dnspod账号&lt;/li&gt;
&lt;li&gt;一个域名&lt;/li&gt;
&lt;li&gt;github for windows(或者git客户端也行)
没了,就这么多就行.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;2-初始操作&#34;&gt;2 初始操作
&lt;/h1&gt;&lt;p&gt;我们在github和gitcafe上面把自己的博客搭建起来,首先要建仓库.
&lt;strong&gt;github&lt;/strong&gt;:
首先登录你的github,然后新建一个公共仓库,仓库名是你的用户名加上&lt;code&gt;yourname.github.io&lt;/code&gt;,如下图所示,我的用户名是&lt;code&gt;Jackroyal&lt;/code&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eye6fpc3w8j20ue0idjv0.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;github新建仓库&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;gitcafe&lt;/strong&gt;:
操作方法差不多,不过有点区别是,gitcafe新建的公开项目,是和用户名一致的,比如我的用户名是&lt;code&gt;Jackroyal&lt;/code&gt;,那我新建的仓库名就是&lt;code&gt;Jackroyal&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;仓库新建成功后,你获取到的链接应该是类似下面的&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;https://github.com/Jackroyal/Jackroyal.github.io.git
https://gitcafe.com/Jackroyal/Jackroyal.git
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这就是你的两个page对应的仓库.&lt;/p&gt;
&lt;h1 id=&#34;3-搭建博客&#34;&gt;3 搭建博客
&lt;/h1&gt;&lt;h2 id=&#34;31-搭建github-pages&#34;&gt;3.1 搭建github pages
&lt;/h2&gt;&lt;p&gt;当你的仓库建好了,我们就开始搭建博客,因为之前的博客有写,具体过程就不赘述&lt;a class=&#34;link&#34; href=&#34;http://jackroyal.github.io/2015/06/16/hexo-3-0-update/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;安装和配置hexo 3.0&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;按照上面的教程一步一步,就能搭建好博客,然后你就可以访问你的gihub pages了,访问链接就是&lt;code&gt;http://yourname.github.io&lt;/code&gt;,比如我的即使&lt;code&gt;http://jackroyal.github.io&lt;/code&gt;.
现在我们开始搭建gitcafe上面的pages了.由于hexo现在已经支持多发布,所以很简单,我们只需要配置deploy的信息,修改&lt;code&gt;_config.yml&lt;/code&gt;.添加gitcafe的仓库信息.我的修改结果如下,&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;deploy:
- type: git
  repo: &amp;#39;https://github.com/Jackroyal/Jackroyal.github.io.git&amp;#39;
  branch: master
- type: git
  repo: &amp;#39;https://gitcafe.com/Jackroyal/Jackroyal.git&amp;#39;
  branch: gitcafe-pages
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;尤其需要注意的是,两个的branch是不同的,&lt;code&gt;github&lt;/code&gt;默认分支是&lt;code&gt;master&lt;/code&gt;,&lt;code&gt;gitcafe&lt;/code&gt;默认分支是&lt;code&gt;gitcafe-pages&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;32-添加gitcafe的ssh公钥&#34;&gt;3.2 添加gitcafe的ssh公钥
&lt;/h2&gt;&lt;p&gt;由于我使用的是&lt;code&gt;github for windows&lt;/code&gt;的终端界面,也就是github官方提供的客户端,他的好处是,我使用github的时候,不需要配置ssh公钥,密钥之类的东西.如果你用的不是这个,用的是git的客户端,那就需要配置ssh公钥,参考这里&lt;a class=&#34;link&#34; href=&#34;https://help.github.com/articles/generating-ssh-keys/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;github配置公钥&lt;/a&gt;.
对的,你猜到了,我们现在需要配置gitcafe的ssh公钥,因为&lt;code&gt;github for windows&lt;/code&gt;会自动帮我们上传公钥,gitcafe就只能手动了.&lt;/p&gt;
&lt;h3 id=&#34;321-查看本地公钥&#34;&gt;3.2.1 查看本地公钥
&lt;/h3&gt;&lt;p&gt;我们打开你使用的git终端,首先切回用户目录,然后进入&lt;code&gt;.ssh&lt;/code&gt;目录,里面就有公钥和私钥,如下图所示
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eye75djqo9j20gj09475k.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;使用git客户端查看ssh公钥私钥&#34;
	
	
&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eye78gs0hvj20it0ca761.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;使用github for windows查看ssh公钥私钥&#34;
	
	
&gt;
我们就是要读取后缀是&lt;code&gt;.pub&lt;/code&gt;的那个文件,比如我的读取命令就是&lt;code&gt;cat github_rsa.pub&lt;/code&gt;,执行结果如下
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eye7c2xpavj20if06dt9w.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;查看公钥&#34;
	
	
&gt;&lt;/p&gt;
&lt;h3 id=&#34;322-添加公钥到gitcafe&#34;&gt;3.2.2 添加公钥到gitcafe
&lt;/h3&gt;&lt;p&gt;我们在&lt;a class=&#34;link&#34; href=&#34;https://gitcafe.com/account/public_keys&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这里&lt;/a&gt;来设置gitcafe的公钥.
&lt;em&gt;PS:需要注意的是,公钥后面的chen@chen-pc是不需要的,我的带上以后,gitcafe说是公钥非法,不过不怕,gitcafe会帮你正确格式化&lt;/em&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eye7h4ha7dj20v105n0ve.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;正确的ssh格式&#34;
	
	
&gt;
反正就是把公钥加上去,就ok了&lt;/p&gt;
&lt;h2 id=&#34;34-同步博客到gitcafe&#34;&gt;3.4 同步博客到gitcafe
&lt;/h2&gt;&lt;p&gt;上面的配置好了以后,我们就可以把博客内容同步到gitcafe了,方法很简单,执行&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hexo d -g
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后就可以啦.&lt;/p&gt;
&lt;h1 id=&#34;4-配置域名&#34;&gt;4 配置域名
&lt;/h1&gt;&lt;p&gt;首先你得有个域名,像我一样,哈哈.&lt;/p&gt;
&lt;h2 id=&#34;41-修改域名注册的解析服务器&#34;&gt;4.1 修改域名注册的解析服务器
&lt;/h2&gt;&lt;p&gt;我们在要把域名解析服务,设置到dnspod,因为他是国内的,而且服务很好.我们登录自己的域名管理后台,选择对应的域名进行管理,然后找到&lt;code&gt;nameservers&lt;/code&gt;的设置,如图所示
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eye7orkymjj210j0i7tde.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;修改nameservers的设置&#34;
	
	
&gt;
修改的值是&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; f1g1ns1.dnspod.net
 f1g1ns2.dnspod.net
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;常见的域名注册商修改到dnspod,官方提供了教程,看&lt;a class=&#34;link&#34; href=&#34;https://support.dnspod.cn/Kb/guide/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这里&lt;/a&gt;-
改完以后可能要等一段时间才能生效,最多72小时
ok,改完以后,这边就完了,我们登录dnspod&lt;/p&gt;
&lt;h2 id=&#34;42-修改dnspod解析记录&#34;&gt;4.2 修改dnspod解析记录
&lt;/h2&gt;&lt;p&gt;我们登录dnspod,然后添加域名
如果4.1中的设置生效了,你的域名就会添加成功了,我们直接进行下一步,修改解析记录,上图
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eye9mfkri4j20mt0efad6.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;dns解析记录&#34;
	
	
&gt;
我们一共添加了5条记录,其中一条泛解析和www解析是针对国内的,所以执行gitcafe;2条泛解析和www解析是针对国外的,所以指向github.
就是添加&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@       A      默认  192.30.252.153
@       A      默认  192.30.252.154
@       CNAME  国内  gitcafe.io.
www     CNAME  默认  jackroyal.github.io.
www     CNAME  国内  gitcafe.io.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;其他设置项目默认就行了,上面的配置完了,如果你走国外ip访问你的域名的话,会出现404,因为我们还差一步.走国内线路访问一样会出错,都是没绑定的结果.&lt;/p&gt;
&lt;h2 id=&#34;43-添加github的cname文件添加gitcafe自定义域名&#34;&gt;4.3 添加github的CNAME文件,添加gitcafe自定义域名
&lt;/h2&gt;&lt;p&gt;现在只差最后一步了,我们先来配置github的CNAME文件,官网有个教程&lt;a class=&#34;link&#34; href=&#34;https://help.github.com/articles/adding-a-cname-file-to-your-repository/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;配置CNAME文件&lt;/a&gt;.说白了,就是在你的网站根目录,添加一个名为&lt;code&gt;CNAME&lt;/code&gt;的文件,里面的内容就是你的域名&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;bblove.me
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;没有任何多余的信息,如下图
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eyea41g3amj20uz0a4jtg.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;配置github的CNAME&#34;
	
	
&gt;
上面的配置现在访问没问题,但是你一重新发布博客,就需要重新手动添加&lt;code&gt;CNAME&lt;/code&gt;文件,太麻烦.
一劳永逸的方法,在你的&lt;code&gt;hexo&lt;/code&gt;目录下的&lt;code&gt;source&lt;/code&gt;目录中,新建一个&lt;code&gt;CNAME&lt;/code&gt;文件夹,然后他每次在你发布博客的时候,都会在你的网站根目录生成一个&lt;code&gt;CNAME&lt;/code&gt;文件.
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eyea9pgd8cj20ko06ct9v.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;添加CNAME的目录结构&#34;
	
	
&gt;
现在github的配置彻底结束.&lt;/p&gt;
&lt;p&gt;接下来配置gitcafe:
1 我们在gitcafe的项目主页,点击&lt;code&gt;项目设置&lt;/code&gt;,如下图(之所以截图,是因为我找半天才看到&amp;hellip;)
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eyeadedmh1j20z508eadm.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;gitcafe点击’项目设置’&#34;
	
	
&gt;
2 然后我们点击&lt;code&gt;pages服务&lt;/code&gt;标签,然后添加自己的域名,这些域名是我们之前在dnspod中设置了解析的
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eyeaftjlagj20sp0dvn1i.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;gitcafe配置自定义域名&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;彻底打完收工了&lt;/p&gt;
&lt;h1 id=&#34;5-总结&#34;&gt;5 总结
&lt;/h1&gt;&lt;p&gt;总算写完了,写到这里,我一共写了,141行了,写了个把小时.这次主要参考了下面的几篇文章,都写在友情链接里面了.参考了他们的思路,因为他们的方法里面需要自己单独购买vps或者购买CDN,共同的问题是增加了开销,买vps会导致你每次写博客都需要单独发布一次到vps上太麻烦.我后来在网上看到gitcafe也有&lt;code&gt;gitcafe pages&lt;/code&gt;服务,如果用这个来处理的话,一来,不会增加多余的开销,他们都是免费的;二来,由于hexo对于多部署的支持,多部署很简单,一次配置,以后就可以不用理会了.
ok,收工&lt;/p&gt;
&lt;h1 id=&#34;友情链接&#34;&gt;友情链接
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;http://jerryzou.com/posts/feasibility-of-allowing-baiduSpider-for-Github-Pages/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;解决 Github Pages 禁止百度爬虫的方法与可行性分析&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;http://www.dozer.cc/2015/06/github-pages-and-cdn.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;利用 CDN 解决百度爬虫被 Github Pages 拒绝的问题&lt;/a&gt;
3 &lt;a class=&#34;link&#34; href=&#34;https://help.gitcafe.com/manuals/help/pages-services&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;gitcafe官方文档&amp;ndash;pages服务&lt;/a&gt;
4 &lt;a class=&#34;link&#34; href=&#34;https://help.gitcafe.com/manuals/help/ssh-key&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;gitcafe官方文档&amp;ndash;配置ssh公钥&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>git使用笔记(2)</title>
        <link>https://blog.huirongis.me/post/my-git-note2/</link>
        <pubDate>Wed, 04 Nov 2015 16:52:25 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/my-git-note2/</guid>
        <description>&lt;p&gt;上一篇笔记,只写了些git的基础操作,这篇写一下稍微高阶一点的操作,实际项目的时候可能经常会用到.&lt;/p&gt;
&lt;h1 id=&#34;撤销操作&#34;&gt;撤销操作
&lt;/h1&gt;&lt;p&gt;撤销操作,我经常会用到,有时候写的代码没有考虑周全,或者有疏漏,需要重新提交什么的.&lt;/p&gt;
&lt;h1 id=&#34;1-撤销工作空间最近的修改&#34;&gt;1 撤销工作空间最近的修改
&lt;/h1&gt;&lt;p&gt;应用场景:比如上次push以后的完整干净的目录,工作空间没有任何修改,暂存区也没有任何修改,如下图:
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1exp9lmtz38j20cl0383yn.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;上一次提交后干净的工作目录&#34;
	
	
&gt;
这时候,你手贱,改了一下其中的一个文件,但是这次更改是没有意义的.我们继续使用&lt;code&gt;git status&lt;/code&gt;来查看
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1exp9ngk82jj20it07i75f.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;修改一个文件后执行git status的结果&#34;
	
	
&gt;
我们现在想撤销这次修改.
解决方法:现在这个修改只是工作区的修改,我们要撤销很简单执行&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git checkout a.txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;搞定&lt;/p&gt;
&lt;h1 id=&#34;2-撤销暂存区最近的修改&#34;&gt;2 撤销暂存区最近的修改
&lt;/h1&gt;&lt;p&gt;应用场景:假如在上面说的那种情况下,你手贱改错了文件,而且你没有撤销,你还执行&lt;code&gt;git add a.txt&lt;/code&gt;,将修改提交到暂存区了.具体情况如下图
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1expa1cbny2j20ge0790td.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;错误的修改被提交到了暂存区&#34;
	
	
&gt;
现在我们要从暂存区撤回那个修改
解决办法:我们使用&lt;code&gt;git reset HEAD a.txt&lt;/code&gt;,将文件从暂存区撤出来,又回到上面的工作空间被修改的状态,如图
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1expa3azt15j20hg09twft.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;从暂存区撤回&#34;
	
	
&gt;
ps:上面的命令也可以用下面的命令,语法格式是&lt;code&gt;git reset &amp;lt;path&amp;gt;&lt;/code&gt;,括号中填路径&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git reset a.txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;总的来说,&lt;code&gt;git reset &amp;lt;path&amp;gt;&lt;/code&gt;就是&lt;code&gt;git add &amp;lt;path&amp;gt;&lt;/code&gt;的反向操作&lt;/p&gt;
&lt;h1 id=&#34;3-撤销提交到本地仓库的修改&#34;&gt;3 撤销提交到本地仓库的修改
&lt;/h1&gt;&lt;p&gt;应用场景:假如你在&lt;code&gt;1.2&lt;/code&gt;还没有回头,一路手贱下去,将暂存区的修改&lt;code&gt;commit&lt;/code&gt;到本地仓库了
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1expa8o47yvj20fi087gmv.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;错误的修改被提交到本地仓库&#34;
	
	
&gt;
我们现在要从仓库撤销这次没用的提交
解决方法:&lt;/p&gt;
&lt;h4 id=&#34;131-方案一--再新建一次提交&#34;&gt;1.3.1 方案一  再新建一次提交
&lt;/h4&gt;&lt;p&gt;我们可以新建一次提交,然后让所修改的文件回到之前的状态,执行&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git revert HEAD
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;含义很简单,逆转,这样你的&lt;code&gt;log&lt;/code&gt;里面会多一次提交,然后文件也回到的之前的状态
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1expb97iondj20it0catb7.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;执行git revert 后的log&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;#3.2 方案二  干净的撤销上一次commit
上面的方案一对于一个强迫症来说,不能忍啊,本来就是一次错误的提交,为了弥补这个错误,我却还要多提交一次,完全不能忍受.
方案二,我们使用&lt;code&gt;git reset&lt;/code&gt;命令.我们执行&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;git reset HEAD^
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这个命令表示重置HEAD指针,我们要指向上一次提交(也就是取消最近的一次,HEAD表示当前指针,HEAD^是上一次,HEAD^^是上上次,HEAD^^^是上三次),&lt;code&gt;git reset&lt;/code&gt;命令可以添加&lt;code&gt;--mixed&lt;/code&gt;,&lt;code&gt;--soft&lt;/code&gt;,&lt;code&gt;--hard&lt;/code&gt;三种参数,&lt;code&gt;--soft&lt;/code&gt;程度最轻,只会撤销提交,对当前暂存区和当前工作空间不会有任何更改,默认的参数是&lt;code&gt;--mixed&lt;/code&gt;,他会将暂存区的文件撤销&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;git reset --soft :取消了commit  

git reset --mixed（默认） :取消了commit ，取消了add

git reset --hard :取消了commit ，取消了add，取消源文件修改
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;33-方案三--修改最后一次提交&#34;&gt;3.3 方案三  修改最后一次提交
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;首先强调,下面说的实在本地仓库的操作.&lt;/strong&gt;
应用场景:对于上面提到的错误的提交,我们还可以修改他的内容,删除我们错误的修改,将它恢复到原来的样子,我们可以使用&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git commit --amend
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个方法是将当前暂存区快照提交,也就是你后面的修改合在一起,然后再提交.最后查看&lt;code&gt;log&lt;/code&gt;的时候,会只有一次提交,前面的一次提交就被删除,在&lt;code&gt;log&lt;/code&gt;中只看到这次提交.
用具体例子来说.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git commit -m &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;这是第一次提交&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#commit完,我们修改工作空间的内容,然后再执行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git add b.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git commit --amend
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#这条命令会弹出一个编辑窗口,你可以修改提交信息&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#假设我们将提交信息修改为&amp;#34;这是第二次提交&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;接着当我们使用&lt;code&gt;git log&lt;/code&gt;来查看的时候,你只会看到提交信息是&amp;quot;这是第二次提交&amp;quot;.
解决方法:
我们先将文件内容恢复到上一次(当前是HEAD,上一次就是HEAD^)提交时候的样子,然后执行&lt;code&gt;git commit --amend&lt;/code&gt;,看到如下错误提示,就是说这次文件没有任何修改(废话,我已经恢复正确的样子了,当然一模一样了),默认是不允许空提交的,你只有强制使用&lt;code&gt;--allow-empty&lt;/code&gt;才行,或者执行方案二
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1expt5luwo4j20io06cq3w.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;执行git commit –amend内容没有变化的错误提示&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;4-总结&#34;&gt;4 总结
&lt;/h1&gt;&lt;p&gt;盗图一张,总结上面说的内容
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1exptkjlw1fj20jg09fq3k.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;工作空间,暂存区,本地仓库之间的关机和转换&#34;
	
	
&gt;
打完收工&lt;/p&gt;
&lt;h3 id=&#34;附言&#34;&gt;附言
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;PS&lt;/strong&gt;:现在再来解释开头说的,这是本地仓库的操作.
因为,我们本地仓库执行了&lt;code&gt;git commit&lt;/code&gt;后,所做的更改只会在本地,如果接着执行了&lt;code&gt;git push&lt;/code&gt;那么,所做的更改就会被提交到&lt;code&gt;git&lt;/code&gt;,在上面的例子中那么首先提交到github的就是&lt;code&gt;&amp;quot;这是第一次提交&amp;quot;&lt;/code&gt;.这时候,当你执行完&lt;code&gt;git commit --amend&lt;/code&gt;的时候,本地仓库的上次提交会被删除,也就是不存在提示信息为&lt;code&gt;&amp;quot;这是第一次提交&amp;quot;&lt;/code&gt;,此时本地仓库完成了修改,你想提交到github,就会报错了.如图所示
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1exp93i04qtj20it0cajua.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;本地执行–amend操作后直接提交到github报错&#34;
	
	
&gt;
解决方法就是,&lt;strong&gt;Force&lt;/strong&gt;
没错,强制提交&lt;code&gt;git push -f&lt;/code&gt;,这样他就会像本地一样,删除上一次提交,添加这一次提交&lt;/p&gt;
&lt;h1 id=&#34;友情链接&#34;&gt;友情链接
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;https://help.github.com/articles/changing-a-commit-message/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;修改提交信息&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;https://github.com/blog/2019-how-to-undo-almost-anything-with-git&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;如何撤销在git上的各种修改,好文&lt;/a&gt;
3 &lt;a class=&#34;link&#34; href=&#34;http://my.oschina.net/MinGKai/blog/144932&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;git revert和git reset的区别&lt;/a&gt;
4 &lt;a class=&#34;link&#34; href=&#34;https://marklodato.github.io/visual-git-guide/index-zh-cn.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;git常用命令介绍,带效果图的&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>git使用笔记(1)</title>
        <link>https://blog.huirongis.me/post/my-git-note1/</link>
        <pubDate>Wed, 04 Nov 2015 12:17:04 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/my-git-note1/</guid>
        <description>&lt;p&gt;git也用了一段时间了,还是写点笔记,记录一下.&lt;/p&gt;
&lt;h1 id=&#34;准备条件&#34;&gt;准备条件
&lt;/h1&gt;&lt;p&gt;首先假装你已经安装好了git&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在Linux下
我用的是&lt;code&gt;ubuntu&lt;/code&gt;,安装非常easy,使用&lt;code&gt;sudo apt-get install git&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在windows下
在windows下安装,就使用&lt;a class=&#34;link&#34; href=&#34;https://git-scm.com/downloads&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;git-downloads&lt;/a&gt;,点击下载,安装,就ok.
ps:如果你足够幸运,可以试试&lt;a class=&#34;link&#34; href=&#34;https://desktop.github.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;github的windows版&lt;/a&gt;,这个的好处是,带有图形化界面.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;1-初始化git设置&#34;&gt;1 初始化git设置
&lt;/h1&gt;&lt;p&gt;新装好git后,我们先配置个人的用户名和email,这两条配置很重要,因为在git的日志中,都会带上这两条信息.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git config --global user.name &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;John Doe&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git config --global user.email johndoe@example.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果用了&lt;code&gt;--global&lt;/code&gt;选项，那么更改的配置文件就是位于你用户主目录下的那个，以后你所有的项目都会默认使用这里配置的用户信息。如果要在某个特定的项目中使用其他名字或者电邮，只要去掉&lt;code&gt;--global&lt;/code&gt;选项重新配置即可，新的设定保存在当前项目的&lt;code&gt;.git/config&lt;/code&gt;文件里。&lt;/p&gt;
&lt;h1 id=&#34;2-新建第一个仓库&#34;&gt;2 新建第一个仓库
&lt;/h1&gt;&lt;p&gt;建立第一个仓库有两种方式,一种是完全新建一个仓库,第二种是克隆一个现有仓库.&lt;/p&gt;
&lt;h4 id=&#34;21-完全新建一个仓库&#34;&gt;2.1 完全新建一个仓库
&lt;/h4&gt;&lt;p&gt;你先切换到你想建项目的地方,比如&lt;code&gt;f:/blog/&lt;/code&gt;,然后执行&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git init
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;初始化后再在当前目录新建一个名为&lt;code&gt;.git&lt;/code&gt;的目录,git所有的东西都存在这里面.当然我们不用管.&lt;/p&gt;
&lt;h4 id=&#34;22-克隆一个现有仓库&#34;&gt;2.2 克隆一个现有仓库
&lt;/h4&gt;&lt;p&gt;这个也是很easy,直接一条命令搞定&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git clone https://github.com/Jackroyal/blog.git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;他会在你的当前目录新建一个&lt;code&gt;blog&lt;/code&gt;文件夹,在&lt;code&gt;blog&lt;/code&gt;文件夹里面他会把相关的文件都下载下来,就可以用了.&lt;/p&gt;
&lt;h1 id=&#34;3-提交更新&#34;&gt;3 提交更新
&lt;/h1&gt;&lt;h4 id=&#34;31-提交工作空间文件到暂存区&#34;&gt;3.1 提交工作空间文件到暂存区
&lt;/h4&gt;&lt;p&gt;执行&lt;code&gt;touch a.txt&lt;/code&gt;,我们在目录中新建一个文件名叫&lt;code&gt;a.txt&lt;/code&gt;,然后我们修改它的内容.
接下来,我们来查看下状态&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git status
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;执行结果如下图:
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1exoxiu5jyij20it0933zl.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;执行git status查看工作区文件状态&#34;
	
	
&gt;
就像图片中提示的,我们新加的&lt;code&gt;a.txt&lt;/code&gt;是未跟踪文件,我们执行&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git add a.txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们把&lt;code&gt;a.txt&lt;/code&gt;添加到暂存区,再次执行&lt;code&gt;git status&lt;/code&gt;,查看状态,执行结果如图所示
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1exoxp6duu1j20it07o0th.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;添加到暂存区后再次执行git status&#34;
	
	
&gt;&lt;/p&gt;
&lt;h4 id=&#34;32-将暂存区文件保存到本地仓库&#34;&gt;3.2 将暂存区文件保存到本地仓库
&lt;/h4&gt;&lt;p&gt;假如你要做的修改已经改完,已经保存到暂存区了,我们准备提交到本地仓库.执行&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;git commit -m &amp;#34;这是提交内容&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;参数&lt;code&gt;-m&lt;/code&gt;,就是添加说明,方便以后查看,你就可以知道自己做了哪些更改&lt;/p&gt;
&lt;h4 id=&#34;33-将本地仓库内容提交到远程仓库&#34;&gt;3.3 将本地仓库内容提交到远程仓库
&lt;/h4&gt;&lt;p&gt;上面的步骤都弄好以后,我们提交到远程仓库&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; git push origin master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后就行了,一个基本的流程就是这样.
推荐看看下面友情链接里面的那本书,pro git
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1exp17u1ltjj208r0boq38.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;pro git封面&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;友情链接&#34;&gt;友情链接
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;http://iissnan.com/progit/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;pro git中文书籍在线版&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>微信支付app支付3.0接口开发</title>
        <link>https://blog.huirongis.me/post/weixin-app-pay-v3-0/</link>
        <pubDate>Sun, 25 Oct 2015 21:30:03 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/weixin-app-pay-v3-0/</guid>
        <description>&lt;p&gt;最近在做微信支付,因为前段时间做了微信的公众账号支付,我以为是一个东西,结果发现不是,我真是醉了,竟然是独立的两套东西.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1exdqakso33j20ny0dptbi.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;微信支付架构图&#34;
	
	
&gt;
整个微信支付,分为三大平台,公众平台(就是公众账号那个),开发平台(主要针对app这块),商户平台(所有微信支付的结算,最终在这里).三个平台的账号都不同,而且必须不同,不然不让你注册.
其中,需要用户注册的是公众平台和开放平台,当你审核通过以后,就会给你分配一个对应的商户号.也就是说,你一个公司,申请一个公众号和一个开放平台账号,分别给你一个商户号,你就一共有两个商户号.这两个商户号不同,我之前就是拿着公众账号对应的商户号(客户给错了),去做app支付,一直说不对应.
下面进入正文,看看怎么开发&lt;/p&gt;
&lt;h1 id=&#34;准备工作&#34;&gt;准备工作
&lt;/h1&gt;&lt;p&gt;首先你需要注册&lt;a class=&#34;link&#34; href=&#34;https://open.weixin.qq.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;开放平台&lt;/a&gt;账号,然后添加一个app应用(里面包含你的appid和appkey),并且进行认证,然后就会收到一封邮件,里面包含了你分到的商户号.&lt;/p&gt;
&lt;h1 id=&#34;1-流程图&#34;&gt;1 流程图
&lt;/h1&gt;&lt;p&gt;接下来,我们需要搞清楚微信app支付开发的流程,如下图所示.
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1exgxrb07bfj20ou0sy453.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;微信app支付流程图&#34;
	
	
&gt;
其中,红色的部分是需要我们做的,具体分下来,客户端要做的事就比较少,生成预支付订单,返回签名的package这些都是服务端做的(开发客户端真爽),当然从另外一个角度来说,这些事情也确实应该放在服务器端来做,因为涉及到一些key和密钥之类的东西,放在客户端app中不安全,如果app被反编译就暴露了这些信息.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;商户系统和微信支付系统主要交互说明：
步骤1：用户在商户APP中选择商品，提交订单，选择微信支付。
步骤2：商户后台收到用户支付单，调用微信支付统一下单接口。参见【统一下单API】。
步骤3：统一下单接口返回正常的prepay_id，再按签名规范重新生成签名后，将数据传输给APP。参与签名的字段名为appId，partnerId，prepayId，nonceStr，timeStamp，package。注意：package的值格式为Sign=WXPay
步骤4：商户APP调起微信支付。api参见本章节【app端开发步骤说明】
步骤5：商户后台接收支付通知。api参见【支付结果通知API】
步骤6：商户后台查询支付结果。，api参见【查询订单API】
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;服务端要做的,就是步骤1235,客户端做步骤4就行了,步骤6看自己的需求,我们没有做.
首先,生成商户服务器订单,这个自不必说,只有生成订单,才有订单号,才能做后面的工作.
我们重点看下步骤2和步骤3&lt;/p&gt;
&lt;h1 id=&#34;2--调用统一下单接口&#34;&gt;2  调用统一下单接口
&lt;/h1&gt;&lt;p&gt;首先,我们需要看一下&lt;a class=&#34;link&#34; href=&#34;https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;统一下单接口&lt;/a&gt;文档,里面包含了请求的地址和要传的参数,顾名思义,那些必填字段是必须要填写的,这是我的请求参数列表&lt;code&gt;out_trade_no&lt;/code&gt;,&lt;code&gt;body&lt;/code&gt;,&lt;code&gt;total_fee&lt;/code&gt;,&lt;code&gt;time_start&lt;/code&gt;,&lt;code&gt;time_expire&lt;/code&gt;,&lt;code&gt;spbill_create_ip&lt;/code&gt;,&lt;code&gt;notify_url&lt;/code&gt;,&lt;code&gt;trade_type&lt;/code&gt;还有一个签名&lt;code&gt;sign&lt;/code&gt;,这就是所有的请求字段.&lt;/p&gt;
&lt;h2 id=&#34;签名&#34;&gt;签名
&lt;/h2&gt;&lt;p&gt;签名的思路是,把所有得除&lt;code&gt;sign&lt;/code&gt;字段以外的字段,按照参数名ASCII码从小到大排序,使用URL键值对的格式（即key1=value1&amp;amp;key2=value2…）拼接成字符串stringA。在stringA最后拼接上key得到stringSignTemp字符串，并对stringSignTemp进行MD5运算，再将得到的字符串所有字符转换为大写，得到sign值signValue。&lt;a class=&#34;link&#34; href=&#34;https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=4_3&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;官方文档&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;签名可能有点蛋疼,你可以看&lt;a class=&#34;link&#34; href=&#34;https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=4_3&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这个&lt;/a&gt;文档.微信也提供了签名的&lt;a class=&#34;link&#34; href=&#34;https://pay.weixin.qq.com/wiki/tools/signverify/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;在线调试工具&lt;/a&gt;,你把参数填进去,看看签名拿到的值是否和你签名的结果一样.&lt;/p&gt;
&lt;h2 id=&#34;调用unifiedorder&#34;&gt;调用unifiedOrder
&lt;/h2&gt;&lt;p&gt;由于统一下单接口,所有的支付方式都会调用,包括公众账号的几种支付方式,而且官方没有app支付的sdk代码,所以我们直接用公众号支付的js sdk代码.
sdk里面已经封装好了对统一下单接口的调用,包括签名,所以我们只需要调用这个就好了.&lt;/p&gt;
&lt;h2 id=&#34;整理参数&#34;&gt;整理参数
&lt;/h2&gt;&lt;p&gt;调用统一下单接口后,会返回很多数据,我们还是调用js sdk里面的处理函数,因为返回的是xml的内容,有些数据我们不要,(下面的结果是js api的,结果跟app除了trade_type不同,其他都是一样的)&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;xml&amp;gt;
   &amp;lt;return_code&amp;gt;&amp;lt;![CDATA[SUCCESS]]&amp;gt;&amp;lt;/return_code&amp;gt;
   &amp;lt;return_msg&amp;gt;&amp;lt;![CDATA[OK]]&amp;gt;&amp;lt;/return_msg&amp;gt;
   &amp;lt;appid&amp;gt;&amp;lt;![CDATA[wx2421b1c4370ec43b]]&amp;gt;&amp;lt;/appid&amp;gt;
   &amp;lt;mch_id&amp;gt;&amp;lt;![CDATA[10000100]]&amp;gt;&amp;lt;/mch_id&amp;gt;
   &amp;lt;nonce_str&amp;gt;&amp;lt;![CDATA[IITRi8Iabbblz1Jc]]&amp;gt;&amp;lt;/nonce_str&amp;gt;
   &amp;lt;sign&amp;gt;&amp;lt;![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]&amp;gt;&amp;lt;/sign&amp;gt;
   &amp;lt;result_code&amp;gt;&amp;lt;![CDATA[SUCCESS]]&amp;gt;&amp;lt;/result_code&amp;gt;
   &amp;lt;prepay_id&amp;gt;&amp;lt;![CDATA[wx201411101639507cbf6ffd8b0779950874]]&amp;gt;&amp;lt;/prepay_id&amp;gt;
   &amp;lt;trade_type&amp;gt;&amp;lt;![CDATA[JSAPI]]&amp;gt;&amp;lt;/trade_type&amp;gt;
&amp;lt;/xml&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的参数中,我们需要appid(就是你配置中的那个appid),prepay_id(预支付id,之前都是为了它),partnerid(就是你配置的商户号mch_id),其他的就没啥用了,我们接下来要给客户端返回一个数据包,全部的数据如下&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;{&amp;#34;appid&amp;#34;:&amp;#34;wx8c965dd8b4794241&amp;#34;,&amp;#34;noncestr&amp;#34;:&amp;#34;oxh4g98rfgbmugwbmxfg72ay6qpvieos&amp;#34;,&amp;#34;package&amp;#34;:&amp;#34;Sign=WXpay&amp;#34;,&amp;#34;partnerid&amp;#34;:&amp;#34;1277670101&amp;#34;,&amp;#34;prepayid&amp;#34;:&amp;#34;wx2015102014523449175fc2fd0939076028&amp;#34;,&amp;#34;timestamp&amp;#34;:&amp;#34;1445323951&amp;#34;,&amp;#34;sign&amp;#34;:&amp;#34;7F84997FDW40F6F15DD1C28A9E313122&amp;#34;}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;noncestr&lt;/code&gt;是重新生成的,&lt;code&gt;package&lt;/code&gt;是固定写法,里面的内容必须写&lt;code&gt;&amp;quot;Sign=WXpay&amp;quot;&lt;/code&gt;,&lt;code&gt;timestamp&lt;/code&gt;也是重新生成的,&lt;code&gt;sign&lt;/code&gt;是重新签名后的结果.
然后把数据返回给客户端就行了,客户端调起支付.&lt;/p&gt;
&lt;h1 id=&#34;3--支付回调&#34;&gt;3  支付回调
&lt;/h1&gt;&lt;p&gt;和支付宝原理一样,不过微信返回的数据不是标准的&lt;code&gt;post&lt;/code&gt;,所以你没法通过&lt;code&gt;$_POST[&#39;out_trade_no&#39;]&lt;/code&gt;这样来获取数据.
所以,我的做法还是调用js sdk里面的回调方法,把那个回调类继承了一下,我们只需要重写&lt;code&gt;NotifyProcess&lt;/code&gt;函数就行了,在这里面加入自己的逻辑,比如判断订单是否存在,订单是否已经处理过之类的.
至此,大流程已经走通了.&lt;/p&gt;
&lt;h1 id=&#34;4--优化&#34;&gt;4  优化
&lt;/h1&gt;&lt;p&gt;在调试过程中,我发现同一个订单号不能重复的去获取预支付的prepay_id,所以,我们在整理参数那一步后,需要将返回参数存到数据库,下次申请支付的时候,先去数据库查一下,有的话,就不用给微信服务器请求了&lt;/p&gt;
&lt;p&gt;打完收工.&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=11_1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;微信官方sdk下载&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>ubuntu下设置apache的目录映射</title>
        <link>https://blog.huirongis.me/post/ubuntu-lamp-alias-setting/</link>
        <pubDate>Thu, 15 Oct 2015 22:12:37 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/ubuntu-lamp-alias-setting/</guid>
        <description>&lt;p&gt;好吧,我的博客一不小心又荒废下来了,话不多说,进入正文.&lt;/p&gt;
&lt;p&gt;最近的项目一直在忙,发布代码的时候遇到一个麻烦事,由于所有项目代码都放在服务器的根目录,也就是&lt;code&gt;/var/www/html&lt;/code&gt;下;然后还有一个api的页面,我放在一个&lt;code&gt;api&lt;/code&gt;文件夹中,然后把整个&lt;code&gt;api&lt;/code&gt;文件夹放在&lt;code&gt;html&lt;/code&gt;目录下.由于每次发布代码都是替换整个根目录&lt;code&gt;html&lt;/code&gt;下的文件,你懂的,我每次发布项目代码后,&lt;code&gt;api&lt;/code&gt;就没了,需要我单独解压,再复制,blablabla,总之一个字,**  烦  **.
我突然想起来,phpmyadmin安装后就不在网站的根目录,但是访问的时候我却还是直接在ip后面跟目录,比如&lt;code&gt;http://127.0.0.1/phpmyadmin&lt;/code&gt;,这货应该是用了一个映射,我照着这个样子搞一个,不就行了,说干就干.&lt;/p&gt;
&lt;h1 id=&#34;1-使用的命令&#34;&gt;1 使用的命令
&lt;/h1&gt;&lt;p&gt;&lt;code&gt;Alias&lt;/code&gt; 这个是这次主要使用的命令,使用的方法很简单,如下所示&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Alias /api /home/ch/api
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;意思就是如果你在ip后面添加&lt;code&gt;/api&lt;/code&gt;后缀,也就是你在浏览器访问&lt;code&gt;http://127.0.0.1/api&lt;/code&gt;,那么实际就会访问到&lt;code&gt;/home/ch/api&lt;/code&gt;目录下&lt;/p&gt;
&lt;h1 id=&#34;2-使用方法&#34;&gt;2 使用方法
&lt;/h1&gt;&lt;h3 id=&#34;linux下&#34;&gt;Linux下
&lt;/h3&gt;&lt;p&gt;由于我用的是ubuntu,所以具体说下ubuntu下怎么用.
根据&lt;a class=&#34;link&#34; href=&#34;http://huirong.github.io/2015/04/01/installLamp/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;在Ubuntu上安装LAMP服务器并简单配置&lt;/a&gt;,这篇文章中关于&lt;code&gt;phpmyadmin&lt;/code&gt;的设置部分,以下为摘抄&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;配置Apache服务器
如果此时在浏览器中输入http://localhost/phpmyadmin，会提示404错误
此时应该进行简单的配置，将phpMyAdmin的配置文件，复制到Apache2下

cp /etc/phpmyadmin/apache.conf /etc/apache2/conf-enabled/phpmyadmin.conf
然后重启Apache服务器

service apache2 restart
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们得到启发,本来phpmyadmin也是不在&lt;code&gt;html&lt;/code&gt;根目录下的,上面的操作做了什么呢?
我们打开&lt;code&gt;/etc/apache2/conf-enabled/phpmyadmin.conf&lt;/code&gt;这个文件看看&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# phpMyAdmin default Apache configuration

Alias /phpmyadmin /usr/share/phpmyadmin

&amp;lt;Directory /usr/share/phpmyadmin&amp;gt;
    Options FollowSymLinks
    DirectoryIndex index.php

    &amp;lt;IfModule mod_php5.c&amp;gt;
        AddType application/x-httpd-php .php

        php_flag magic_quotes_gpc Off
        php_flag track_vars On
        php_flag register_globals Off
        php_admin_flag allow_url_fopen Off
        php_value include_path .
        php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp
        php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/php-gettext/:/usr/share/javascript/
    &amp;lt;/IfModule&amp;gt;

&amp;lt;/Directory&amp;gt;

# Authorize for setup
&amp;lt;Directory /usr/share/phpmyadmin/setup&amp;gt;
    &amp;lt;IfModule mod_authn_file.c&amp;gt;
    AuthType Basic
    AuthName &amp;#34;phpMyAdmin Setup&amp;#34;
    AuthUserFile /etc/phpmyadmin/htpasswd.setup
    &amp;lt;/IfModule&amp;gt;
    Require valid-user
&amp;lt;/Directory&amp;gt;

# Disallow web access to directories that don&amp;#39;t need it
&amp;lt;Directory /usr/share/phpmyadmin/libraries&amp;gt;
    Order Deny,Allow
    Deny from All
&amp;lt;/Directory&amp;gt;
&amp;lt;Directory /usr/share/phpmyadmin/setup/lib&amp;gt;
    Order Deny,Allow
    Deny from All
&amp;lt;/Directory&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;看看这个文件的第一行,soga,原来他用的也是&lt;code&gt;Alias&lt;/code&gt;命令,接下来我们继续往下走,下面的代码是什么意思呢?下面的代码是用来设置文件目录的权限的,就是&lt;code&gt;&amp;lt;Directory&amp;gt;&lt;/code&gt;标签里面的内容.
关于这里的设置,我们可以参考[apache官网](&lt;a class=&#34;link&#34; href=&#34;https://httpd.apache.org/docs/2.2/mod/mod_authz_host.html#&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://httpd.apache.org/docs/2.2/mod/mod_authz_host.html#&lt;/a&gt; order)上的描述.简而言之
&lt;code&gt;Order Deny,Allow&lt;/code&gt;其实是Allow优先,举个例子&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Order Deny,Allow
Allow from All
Deny from All
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;由于&lt;code&gt;Deny&lt;/code&gt;规则在&lt;code&gt;Allow&lt;/code&gt;之前(Order规定的),所以先Deny所有的请求,然后&lt;code&gt;Allow&lt;/code&gt;规则在其后,最后的结果就是所有的人都可以随意访问.假设你要对访问进行限制,建议按照下面这样设置&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Order Deny,Allow
Allow from 192.168.1.122
Deny from All
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;也就是指允许ip为&lt;code&gt;192.168.1.122&lt;/code&gt;的用户去访问,其他的用户都会被&lt;code&gt;Deny&lt;/code&gt;&lt;/p&gt;
&lt;h1 id=&#34;3-最后的结果&#34;&gt;3 最后的结果
&lt;/h1&gt;&lt;p&gt;结合上面的分析,给出我最后的结果&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Alias /api /var/www/api
&amp;lt;Directory /var/www/api&amp;gt;
 Options FollowSymLinks Includes -Indexes

  AllowOverride None
  Order allow,deny
  allow from all
&amp;lt;/Directory&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这里的&lt;code&gt;-Indexes&lt;/code&gt;选项的意思是,不要列出目录
打完收工&lt;/p&gt;
</description>
        </item>
        <item>
        <title>php中的bool值和类型转换</title>
        <link>https://blog.huirongis.me/post/php-boolean-value/</link>
        <pubDate>Mon, 20 Jul 2015 14:23:21 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/php-boolean-value/</guid>
        <description>&lt;p&gt;最近在写php,发现有个问题一直无法避免,那就是关于php的bool值和类型转换.
以前每次遇到要校验一个变量&lt;code&gt;$a&lt;/code&gt;,是否为空,都是使用&lt;code&gt;$a==&#39;&#39;&lt;/code&gt;去判断,感觉不是很懂,反正一直这样用,也没出太多纰漏,而没有理会什么NUll,&amp;rsquo;&amp;rsquo;,0之类的其他值.今天决定研究下,把它彻底搞清楚.&lt;/p&gt;
&lt;h1 id=&#34;1-php的数据类型&#34;&gt;1 php的数据类型
&lt;/h1&gt;&lt;p&gt;php支持原始的8总数据类型.
4总标量类型:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;boolean&lt;/li&gt;
&lt;li&gt;integer&lt;/li&gt;
&lt;li&gt;float(也称作double类型)&lt;/li&gt;
&lt;li&gt;string
2种复合类型&lt;/li&gt;
&lt;li&gt;array(数组)&lt;/li&gt;
&lt;li&gt;object(对象)
2种特殊类型&lt;/li&gt;
&lt;li&gt;resource(资源)&lt;/li&gt;
&lt;li&gt;NULL(无类型)
实际上 double 和 float 是相同的，由于一些历史的原因，这两个名称同时存在。
变量的类型通常不是由程序员设定的，确切地说，是由PHP根据该变量使用的上下文在运行时决定的。
前面几种类型很好理解,现在重点看一下resource类型和NULL类型&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;resource&lt;/code&gt; 是一种特殊变量，保存了到外部资源的一个引用。资源是通过专门的函数来建立和使用的。由于资源类型变量保存有为打开文件、数据库连接、图形画布区域等的特殊句柄，因此将其它类型的值转换为资源没有意义。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NULL&lt;/code&gt;,特殊的NULL值表示一个变量没有值。NULL类型唯一可能的值就是 NULL。在下列情况下一个变量被认为是NULL：&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;被赋值为 NULL。&lt;/li&gt;
&lt;li&gt;尚未被赋值。&lt;/li&gt;
&lt;li&gt;被 unset()。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;2-常用的比较函数&#34;&gt;2 常用的比较函数
&lt;/h1&gt;&lt;h3 id=&#34;empty&#34;&gt;empty()
&lt;/h3&gt;&lt;p&gt;这个函数最近经常见到,它比较有特点.
如果 var 是非空或非零的值，则empty()返回&lt;code&gt;FALSE&lt;/code&gt;。
换句话说，&amp;quot;&amp;quot;、0、&amp;ldquo;0&amp;rdquo;、NULL、FALSE、array()、var $var以及没有任何属性的对象都将
被认为是空的，返回 TRUE。
如果变量没有赋值,empty()也不会报错.&lt;/p&gt;
&lt;h3 id=&#34;is_set&#34;&gt;is_set()
&lt;/h3&gt;&lt;p&gt;这个函数和is_null()刚好相反,如果一个函数的is_null()返回&lt;code&gt;true&lt;/code&gt;,那么它的is_set()则必定返回相反值,&lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;is_null&#34;&gt;is_null()
&lt;/h3&gt;&lt;p&gt;所有的&lt;code&gt;is_&lt;/code&gt;开头的函数,都不会进行类型转换,例如is_bool(&amp;lsquo;0&amp;rsquo;),返回false,因为&#39;0&amp;rsquo;不是一个布尔类型的值.
详细对比看下图
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1euak04nwitj20nf0i2432.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;使用 PHP 函数对变量 $x 进行比较&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;更多更详细的比较,大家看这里&lt;a class=&#34;link&#34; href=&#34;http://php.net/manual/zh/types.comparisons.php&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;php类型比较表&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>ubuntu 14.04配置thinkphp路由,隐藏index.php</title>
        <link>https://blog.huirongis.me/post/ubuntu-14-04-setting-about-thinkphp-url-rewrite/</link>
        <pubDate>Mon, 29 Jun 2015 20:16:17 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/ubuntu-14-04-setting-about-thinkphp-url-rewrite/</guid>
        <description>&lt;p&gt;今天把代码发布到服务器上去,发现服务器的rewrite有问题,无法实现隐藏index.php的功能.&lt;/p&gt;
&lt;h1 id=&#34;环境&#34;&gt;环境
&lt;/h1&gt;&lt;p&gt;服务器:ubuntu 14.04 lts
apache:2.4.7
php:5.5.9-
mysql:5.5.43&lt;/p&gt;
&lt;h1 id=&#34;开启rewrite模块&#34;&gt;开启rewrite模块
&lt;/h1&gt;&lt;p&gt;在ubuntu中,开启很简单,执行以下bash命令即可&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo a2enmod rewrite
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;添加htaccess支持&#34;&gt;添加.htaccess支持
&lt;/h1&gt;&lt;p&gt;默认apache会忽视所有的规则重写,即使添加了&lt;code&gt;.htaccess&lt;/code&gt;文件,他不认.
在ubuntu 14.04中设置,跟其他版本的ubuntu有点不同
核心操作还是修改 &lt;code&gt;AllowOverride None&lt;/code&gt;为&lt;code&gt; AllowOverride All&lt;/code&gt;.
问题是这个文件到底在哪儿.
在网上找的教程中,有的说是在&lt;code&gt;/etc/apache2/sites-available/000-default.conf&lt;/code&gt;中,在我这个版本的apache中,它不在这里.
他在&lt;code&gt;/etc/apache2/apache2.conf&lt;/code&gt;中.
我们打开这个文件,大概在166行.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;Directory /var/www/&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        Options Indexes FollowSymLinks
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        AllowOverride All
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        Require all granted
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/Directory&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;重启apache服务器&#34;&gt;重启apache服务器
&lt;/h1&gt;&lt;p&gt;ok,都改完了,就剩一步,重启apache服务器.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo service apache2 restart
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;搞定!
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1etl9v3c6wzj20go09dmx6.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;热疯了,空调房都热&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;http://www.dev-metal.com/enable-mod_rewrite-ubuntu-14-04-lts/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>digitalocean配置ipv6</title>
        <link>https://blog.huirongis.me/post/digitalocean-support-google-scholar-by-ipv6/</link>
        <pubDate>Tue, 16 Jun 2015 22:24:18 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/digitalocean-support-google-scholar-by-ipv6/</guid>
        <description>&lt;p&gt;之前配置了ubuntu的shadowsocks,用来做代理翻墙.不过,google scholar一直无解,因为digitalocean的ipv4的地址都被google scholar墙掉了.今天(其实离现在已经好多天了),看到一篇文章,很受启发,决定使用ipv6来试试.&lt;/p&gt;
&lt;h1 id=&#34;前提条件&#34;&gt;前提条件
&lt;/h1&gt;&lt;p&gt;首先你得有一台digitalocean的vps,建议选择洛杉矶的服务器,
选个5美元的就够了.&lt;/p&gt;
&lt;h1 id=&#34;1-新建droplet&#34;&gt;1 新建droplet
&lt;/h1&gt;&lt;p&gt;如果你以前没有搭建droplet,今天新建的话,比较简单,我们直接启用ipv6支持.
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1etfo3h9svlj211h1tidny.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;新建droplet,尤其注意勾选ipv6&#34;
	
	
&gt;
注意勾选ipv6,后面的步骤,请参考第3步&lt;/p&gt;
&lt;h1 id=&#34;2-修改droplet&#34;&gt;2 修改droplet
&lt;/h1&gt;&lt;p&gt;我的droplet已经搭建好了,所以只能修改,添加ipv6的支持.
你打开droplet的&lt;code&gt;setting&lt;/code&gt;,在&lt;code&gt;network&lt;/code&gt;中应该可以看到&lt;code&gt;enable ipv6&lt;/code&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1etfosgf63kj207w05ujrn.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;带有启用ipv6选项的页面&#34;
	
	
&gt;
启用后,稍后片刻,页面如下.
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1etfohrljtmj20se0i2tb7.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;在droplet的setting中启用ipv6后的页面&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;3-设置ipv6&#34;&gt;3 设置ipv6
&lt;/h1&gt;&lt;p&gt;当我们启用ipv6支持以后,还需要对服务器进行设置.&lt;/p&gt;
&lt;h2 id=&#34;第一步--我们把ipv6的地址添加到网卡中&#34;&gt;第一步  我们把ipv6的地址添加到网卡中
&lt;/h2&gt;&lt;p&gt;我们编辑&lt;code&gt;/etc/network/interfaces&lt;/code&gt;这个文件,使用命令&lt;code&gt;sudo vi /etc/network/interfaces&lt;/code&gt;
修改后内容如下&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# This file describes the network interfaces available on your
# system and how to activate them. For more information, see
# interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet static
        address 你的ipv4
        netmask 255.255.192.0
        gateway 你的ipv4网关
        dns-nameservers 8.8.8.8 8.8.4.4
# 以上内容不需要修改,只需要添加下面的部分
iface eth0 inet6 static
    address 上图中的ipv6地址
    netmask 64
    gateway 网关地址
    autoconf 0
    dns-nameservers 2001:4860:4860::8844 2001:4860:4860::8888 209.244.0.3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;修改完成后,我们重启下服务器(因为我的重启网络服务没有效果,所以我重启了),&lt;!-- raw HTML omitted --&gt;如果你看到如下图片,就表示你的ipv6配置好了,我们后面来测试一下
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1etfp7pj65dj20hs04fzlv.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;ipv6成功启用后&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;第二步-测试ipv6-是否配置成功&#34;&gt;第二步 测试ipv6 是否配置成功
&lt;/h2&gt;&lt;p&gt;我们使用ping命令来测试,ping是测试ipv4的,测试ipv6是用ping6,命令如下:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ping6 ipv6.google.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PING ipv6.google.com&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;nuq04s29-in-x0e.1e100.net&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;56&lt;/span&gt; data bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; bytes from nuq04s29-in-x0e.1e100.net: icmp_seq&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; ttl&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;57&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;2.23 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; bytes from nuq04s29-in-x0e.1e100.net: icmp_seq&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; ttl&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;57&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1.97 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; bytes from nuq04s29-in-x0e.1e100.net: icmp_seq&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt; ttl&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;57&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1.95 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; bytes from nuq04s29-in-x0e.1e100.net: icmp_seq&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt; ttl&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;57&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;2.14 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; bytes from nuq04s29-in-x0e.1e100.net: icmp_seq&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt; ttl&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;57&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1.93 ms
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果发包成功,那就可以进行下一步了&lt;/p&gt;
&lt;h1 id=&#34;4-修改hosts&#34;&gt;4 修改hosts
&lt;/h1&gt;&lt;p&gt;因为ipv4无法访问google scholar,所以我们配置下hosts,让所有对访问google学术的,都使用ipv6去访问.执行命令如下:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo vi /etc/hosts
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们在hosts文件的后面,添加如下内容:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;2607:f8b0:4007:805::100f scholar.google.cn
2607:f8b0:4007:805::100f scholar.google.com
2607:f8b0:4007:805::100f scholar.google.com.hk
2607:f8b0:4007:805::100f scholar.l.google.com
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ok,打完收工,睡觉&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;https://www.v2ex.com/t/163133&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;一个解决 Google Scholar block DigitalOcean SFO IP 的方法&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;https://www.digitalocean.com/community/tutorials/how-to-enable-ipv6-for-digitalocean-droplets&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;How To Enable IPv6 for DigitalOcean Droplets&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>安装和配置hexo 3.0</title>
        <link>https://blog.huirongis.me/post/hexo-3-0-update/</link>
        <pubDate>Tue, 16 Jun 2015 22:22:43 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/hexo-3-0-update/</guid>
        <description>&lt;p&gt;update：2015-06-24 16:56
额，谁会相信，其实这篇文章是拖了一周之后才写的。&lt;/p&gt;
&lt;p&gt;因为最近换回了win7，所以之前搭建的hexo环境都没了，需要重新搭建。在网上看到hexo 3.0 还可以，而且，我妹子也换3.0了，so  我也换成hexo 3.0的。&lt;/p&gt;
&lt;h1 id=&#34;安装环境&#34;&gt;安装环境
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;操作系统&lt;/strong&gt;：win7
&lt;strong&gt;相关版本&lt;/strong&gt;：&lt;br&gt;
hexo-cli: 0.1.7
os: Windows_NT 6.1.7601 win32 x64
node: 0.12.4&lt;/p&gt;
&lt;h1 id=&#34;安装过程&#34;&gt;安装过程
&lt;/h1&gt;&lt;h1 id=&#34;-1-安装github-for-windows&#34;&gt;# 1. 安装Github for windows
&lt;/h1&gt;&lt;p&gt;因为我之前就在用Github,所以早就安装了这个.已经装过的同学请忽略这一段.
下载 &lt;a class=&#34;link&#34; href=&#34;https://windows.github.com/&#34;  title=&#34;Github for windows&#34;
     target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Github for windows&lt;/a&gt; 并执行即可完成安装(&lt;em&gt;在线安装,会有点慢&lt;/em&gt;)。这个软件的的好处是有一个带GUI的界面,还有一个终端界面.如图所示
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3jw1emplp1lz31j204w033mx0.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Github for windows&#34;
	
	
&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1empluh6hvej210b0j741r.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;GUI and Bash&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;-2-安装nodejs&#34;&gt;# 2. 安装Node.js
&lt;/h1&gt;&lt;p&gt;在 Windows 环境下安装 &lt;a class=&#34;link&#34; href=&#34;http://nodejs.org/&#34;  title=&#34;Node.js 官网&#34;
     target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Node.js&lt;/a&gt; 非常简单，仅须下载安装文件并执行即可完成安装。（win下建议下载msi格式的，因为这样可以不用配置环境变量之类的）&lt;/p&gt;
&lt;h1 id=&#34;-3-测试nodejs是否安装&#34;&gt;# 3. 测试node.js是否安装
&lt;/h1&gt;&lt;p&gt;在任何控制台输入(可以按windows键+R,输入cmd,然后输入npm,一般来说不会有问题)&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;npm
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;返回值如下&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Usage: npm &amp;lt;command&amp;gt;

where &amp;lt;command&amp;gt; is one of:
    add-user, adduser, apihelp, author, bin, bugs, c, cache,
    completion, config, ddp, dedupe, deprecate, docs, edit,
    explore, faq, find, find-dupes, get, help, help-search,
    home, i, info, init, install, isntall, issues, la, link,
    list, ll, ln, login, ls, outdated, owner, pack, prefix,
    prune, publish, r, rb, rebuild, remove, repo, restart, rm,
    root, run-script, s, se, search, set, show, shrinkwrap,
    star, stars, start, stop, submodule, t, tag, test, tst, un,
    uninstall, unlink, unpublish, unstar, up, update, v,
    version, view, whoami

npm &amp;lt;cmd&amp;gt; -h     quick help on &amp;lt;cmd&amp;gt;
npm -l           display full usage info
npm faq          commonly asked questions
npm help &amp;lt;term&amp;gt;  search for help on &amp;lt;term&amp;gt;
npm help npm     involved overview

Specify configs in the ini-formatted file:
    C:\Users\chenhao\.npmrc
or on the command line via: npm &amp;lt;command&amp;gt; --key value
Config info can be viewed via: npm help config

npm@1.4.28 D:\Program Files (x86)\nodejs\node_modules\npm
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;看到这个结果,就表示你的node.js已经安装上去了
*感谢我们家笨笨的反馈：*此处如果npm无效，首先确定win下你采用的是msi格式的安装文件，然后&lt;strong&gt;重启&lt;/strong&gt;下电脑，应该就正常了。&lt;/p&gt;
&lt;h1 id=&#34;-4-安装hexo&#34;&gt;# 4. 安装hexo
&lt;/h1&gt;&lt;p&gt;接下来的操作我都是用&lt;strong&gt;Github for windows&lt;/strong&gt;自带的Bash来完成的,因为后面会涉及到SSH,用&lt;strong&gt;Github for windows&lt;/strong&gt;,就可以避免这个问题.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在Bash中输入以下命令&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;npm install hexo-cli -g
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;创建hexo文件夹
创建你hexo放置的文件夹,先用Bash进入到目标文件夹,比如我的是F:/blog/,接下来初始化hexo,自动生成相关的文件,在F:/blog/环境下,输入&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd /f/blog  # 这个命令表示当前进入目录为f：/blog/
hexo init
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;安装依赖包&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;本地预览,做完以上操作,可以本地预览一下&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;hexo g
hexo s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;以上两条命令的意思是:
生成相关文件(就是生成目标html,静态博客嘛,就是很多html组成)
打开本地服务器预览(node.js就是干这事的,点击访问&lt;a class=&#34;link&#34; href=&#34;http://localhost:4000&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://localhost:4000&lt;/a&gt;,就可以看到了)
**update-2015-09-29:**在3.0版本中将&lt;code&gt;hexo server&lt;/code&gt;(简写命令就是&lt;code&gt;hexo s&lt;/code&gt;),独立成模块,需要手动安装,不然你执行&lt;code&gt;hexo s&lt;/code&gt;,就会出现无法识别这个命令
安装方法和后面配置模块一样&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;npm install hexo-server --save
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;ok到这里博客搭建基本完成现在要做的就是把它发布到你的github上去&#34;&gt;&lt;strong&gt;ok&lt;/strong&gt;,到这里,博客搭建基本完成,现在要做的就是把它发布到你的Github上去
&lt;/h2&gt;&lt;p&gt;接下来,教你怎么发布到Github上去&lt;/p&gt;
&lt;h1 id=&#34;注册github&#34;&gt;注册Github
&lt;/h1&gt;&lt;p&gt;这一步没什么说的,如果你连简单的注册都不会,我也不会教你╮(╯▽╰)╭&lt;/p&gt;
&lt;h1 id=&#34;创建公共库&#34;&gt;创建公共库
&lt;/h1&gt;&lt;p&gt;在自己Github主页右下角，创建一个新的repository(&lt;a class=&#34;link&#34; href=&#34;https://github.com/new&#34;  title=&#34;点我新建&#34;
     target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;点这里&lt;/a&gt;)。比如我的Github账号是Jackroyal，那么我应该创建的repository名字应该是Jackroyal.github.io(注意你的repository名字就是Jackroyal.github.io,我之前用的是Jackroyal怎么尝试都不行)。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;PS:有个大小写的问题其实我注册的是Jackroyal,大写的J,但是我访问的时候特别是带https的链接,他会自动转为小写访问.怎么说呢?简单点,你就按照你的用户名来,该大写大写,该小写小写&lt;/p&gt;&lt;/blockquote&gt;
&lt;h1 id=&#34;部署&#34;&gt;部署
&lt;/h1&gt;&lt;p&gt;现在万事俱备,只差部署了.
hexo3.0,跟2.0不同,deploy插件我们需要手动去安装,执行如下命令:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;npm install hexo-deployer-git --save
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;接下来,我们来配置deploy的信息,修改&lt;code&gt;_config.yml&lt;/code&gt;.
这个文件在路径是F:/blog/_config.yml.
用编辑器把它打开,修改最后一段&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;deploy:
  type: git
  repo: https://github.com/Jackroyal/Jackroyal.github.io.git
  branch: master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;照着我的这个格式修改就好了,把我里面的用户名替换成你的.
至此基本完成所有搭建步骤.&lt;/p&gt;
&lt;h1 id=&#34;上传&#34;&gt;上传
&lt;/h1&gt;&lt;p&gt;我们开始上传项目的代码,再重复一次,我一直以来用的工具都是_Github for windows_自带的Bash,所以我没有配置SSH,如果你用的windows自带的终端或者其他比如msysgit,可能需要配置SSH,不然无法使用Github(点击&lt;a class=&#34;link&#34; href=&#34;https://help.github.com/articles/generating-ssh-keys/&#34;  title=&#34;https://help.github.com/articles/generating-ssh-keys/&#34;
     target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;这里&lt;/code&gt;&lt;/a&gt;查看官方教程).
我们输入以下命令&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;hexo g
hexo d
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;或者偷个懒&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;hexo d -g
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ok,现在就可以去看看你的个人主页了,逼格满满有木有.
如果发布不成功,继续往下面看.&lt;/p&gt;
&lt;h1 id=&#34;配置hexo&#34;&gt;配置hexo
&lt;/h1&gt;&lt;p&gt;上面的内容和之前一样,接下来写,配置hexo 3.0的步骤.&lt;/p&gt;
&lt;h2 id=&#34;1-安装rss支持&#34;&gt;1 安装rss支持
&lt;/h2&gt;&lt;p&gt;执行如下命令:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;npm install hexo-generator-feed --save
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们接下来修改配置文件,编辑&lt;code&gt;_config.yml&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;feed:
  type: atom
  path: atom.xml
  limit: 20
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;2-安装sitemap支持&#34;&gt;2 安装sitemap支持
&lt;/h2&gt;&lt;p&gt;执行如下命令:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;npm install hexo-generator-sitemap --save
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们接下来修改配置文件,编辑&lt;code&gt;_config.yml&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sitemap:
    path: sitemap.xml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;PS:类似的,还可以安装其他的插件,尤其注意&lt;code&gt;hexo-deployer-git&lt;/code&gt;这个插件,如果你发布不成功,可能是这个插件没有装&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;npm install hexo-generator-index --save
npm install hexo-generator-archive --save
npm install hexo-generator-category --save
npm install hexo-generator-tag --save
npm install hexo-deployer-git --save
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;3-最终修改后的配置文件&#34;&gt;3 最终修改后的配置文件
&lt;/h2&gt;&lt;p&gt;我把我的配置文件分享出来给大家参考下:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# Hexo Configuration
# # Docs: http://hexo.io/docs/configuration.html
# # Source: https://github.com/hexojs/hexo/

# Site
title: 搁浅St的blog
subtitle: 我最喜欢笨笨
description: jackroyal 博客 搁浅St 笨笨
author: 搁浅St
author: John Doe
language: zh-CN
timezone:

# URL
# # If your site is put in a subdirectory, set url as &amp;#39;http://yoursite.com/child&amp;#39; and root as &amp;#39;/child/&amp;#39;
url: http://jackroyal.github.io
root: /
permalink: :year/:month/:day/:title/
permalink_defaults:

# Directory
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
i18n_dir: :lang
skip_render:

# Writing
new_post_name: :title.md # File name of new posts
default_layout: post
titlecase: false # Transform title into titlecase
external_link: true # Open external links in new tab
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
future: true
highlight:
  enable: true
  line_number: true
  auto_detect: true
  tab_replace:

# Category &amp;amp; Tag
default_category: uncategorized
category_map:
tag_map:

# Date / Time format
# # Hexo uses Moment.js to parse and display date
# # You can customize the date format as defined in
# # http://momentjs.com/docs/# /displaying/format/
date_format: YYYY-MM-DD
time_format: HH:mm:ss

# Pagination
# # Set per_page to 0 to disable pagination
per_page: 10
pagination_dir: page


# Extensions
# # Plugins: http://hexo.io/plugins/

index_generator:
  per_page: 10 ## 首页默认10篇文章标题 如果值为0不分页

archive_generator:
    per_page: 10 ## 归档页面默认10篇文章标题
    yearly: true  ## 生成年视图
    monthly: true ## 生成月视图

tag_generator:
    per_page: 10 ## 标签分类页面默认10篇文章

category_generator:
    per_page: 10 ### 分类页面默认10篇文章

sitemap:
    path: sitemap.xml

feed:
  type: atom
  path: atom.xml
  limit: 20

duoshuo_shortname: jackroyal  ## 这里填写你的多说的短网址
# # Themes: http://hexo.io/themes/
theme: light   ## 主题的名称,我用的是light,默认的是landscape

# Deployment
# # Docs: http://hexo.io/docs/deployment.html
deploy:
  type: git
  repo: https://github.com/Jackroyal/Jackroyal.github.io.git
  branch: master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;hexo 3.0有一些新的特性,插件的封装更好了,插件安装和管理很方便.
hexo还支持多发布,可以同时发布到github和gitcafe.&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;https://hexo.io/zh-cn/docs/server.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;hexo 服务器&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>给hexo配置上评论和访问量</title>
        <link>https://blog.huirongis.me/post/hexo-setting-with-comments-and-visitors/</link>
        <pubDate>Sat, 30 May 2015 14:08:49 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/hexo-setting-with-comments-and-visitors/</guid>
        <description>&lt;p&gt;哈哈,我们家笨笨,绝对是我学习技术的很大很大很大大的动力.更开始用github pages的时候,就觉得没法看访问量和评论数量这事,很蛋疼,不过也没折腾.
今天上午,我们家笨笨说没有评论和访问量不好,都不知道多少人看了.妹子都发话了,果断要搞定.&lt;/p&gt;
&lt;p&gt;google一番找到解决方法:&lt;/p&gt;
&lt;h4 id=&#34;1-关于评论数量的显示我们可以直接使用多说官网提供的方法很简单&#34;&gt;1 关于评论数量的显示,我们可以直接使用多说官网提供的方法,很简单
&lt;/h4&gt;&lt;h4 id=&#34;2-关于访问量统计这事儿不太好搞我找到了这个不蒜子这位非著名码农自己做的访问统计哈哈点个赞&#34;&gt;2 关于访问量统计这事儿,不太好搞,我找到了这个&lt;a class=&#34;link&#34; href=&#34;http://ibruce.info/2015/04/04/busuanzi/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;不蒜子&lt;/a&gt;,这位非著名码农自己做的访问统计,哈哈,点个赞
&lt;/h4&gt;&lt;h4 id=&#34;3-今天还看到了font-awesome可以显示一些小图标为了显示效果更好一并加上去&#34;&gt;3 今天还看到了font-awesome,可以显示一些小图标,为了显示效果更好,一并加上去
&lt;/h4&gt;&lt;p&gt;先展示一下最终的效果:&lt;!-- raw HTML omitted --&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1esm9snxfcuj20su0ad74x.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;页底关于整站访问量的显示&#34;
	
	
&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1esm9tcczdij20r00doq4t.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;文章页面关于访问量和评论数量的显示&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;下面,开始动手&lt;/p&gt;
&lt;h1 id=&#34;1-配置评论数量的显示&#34;&gt;1 配置评论数量的显示
&lt;/h1&gt;&lt;p&gt;首先,确认你的评论系统用的是多说,如果不是,那就不用继续往下看了(参考&lt;a class=&#34;link&#34; href=&#34;http://localhost:4000/2014/11/28/custom-hexo/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这里&lt;/a&gt;配置多说).
我使用的主题是&lt;code&gt;light&lt;/code&gt;,其他主题原理类似.我们打开&lt;code&gt;themes/light/layout/_partial/article.ejs&lt;/code&gt;,我们在&lt;code&gt;header&lt;/code&gt;标签的尾部添加上下面的代码:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;% if (item.excerpt &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; index){ %&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;% } else { %&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;busuanzi_container_page_pv&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;head-plus&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fa fa-user&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;busuanzi_value_page_pv&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fa fa-spinner fa-spin&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;次访问
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;head-plus&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fa fa-comments&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ds-thread-count&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;data-thread-key&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;%= page.layout %&amp;gt;-&amp;lt;%= page.slug %&amp;gt;&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fa fa-spinner fa-spin&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;条评论
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;% } %&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最终效果如图&lt;!-- raw HTML omitted --&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1esmas5d58oj20x50jc46f.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;修改后的article.ejs&#34;
	
	
&gt;
以上代码,是最终成型的代码,我加入了一些美化的东西,最核心的就是&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ds-thread-count&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;data-thread-key&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;%= page.layout %&amp;gt;-&amp;lt;%= page.slug %&amp;gt;&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;尤其注意&lt;code&gt;data-thread-key&lt;/code&gt;的设置,他和你之前配置多说的时候是一致的,每篇文章有一个独一无二的key,你可以去你的&lt;code&gt;themes/light/layout/_partial/comment.ejs&lt;/code&gt;里找到关于data-thread-key的内容,直接复制过来即可.&lt;/p&gt;
&lt;p&gt;Ps:这里我们可能还需要配置下数据显示的格式,在你的多说后台管理里面,进入设置界面如图
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1esmayan2utj20w50mx0ya.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;多说后台设置&#34;
	
	
&gt;
我们找到&lt;code&gt;暂无评论&lt;/code&gt;,&lt;code&gt;1条评论&lt;/code&gt;,&lt;code&gt;{num}条评论&lt;/code&gt;,这几个设置,修改成自己要的格式,也可以参照我的修改,&lt;code&gt;0&lt;/code&gt;,&lt;code&gt;1&lt;/code&gt;,&lt;code&gt;{num}&lt;/code&gt;&lt;/p&gt;
&lt;h1 id=&#34;2-配置文章访问量的显示&#34;&gt;2 配置文章访问量的显示
&lt;/h1&gt;&lt;p&gt;这个更简单了,按照作者的说法,只需要引入一个js,再添加一个span就完成了.由于js一般放置在页面的最底部,所以我们找到&lt;code&gt;themes/light/layout/_partial/after_footer.ejs&lt;/code&gt;,我们在最后添加上下面的代码:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;script&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;async&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;src&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/script&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面就完成了js文件的引入,我们再在要显示访问量的地方添加一个span就行了.比如我想显示在标题的下面,那就打开&lt;code&gt;themes/light/layout/_partial/article.ejs&lt;/code&gt;,添加的代码,就是&lt;code&gt;第一步&lt;/code&gt;里面添加的那个.如果你想简洁一点,也可以只添加下面核心代码就行:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;本站总访问量&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;busuanzi_value_site_pv&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;次
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;本站访客数&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;busuanzi_value_site_uv&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;人次
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;本文总阅读量&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;busuanzi_value_page_pv&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;次
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;3--经过美化后最终的代码&#34;&gt;3  经过美化后最终的代码
&lt;/h1&gt;&lt;p&gt;如果只用官方提供的代码,没有优化,很丑,我优化了下,分享一下.&lt;/p&gt;
&lt;p&gt;1.修改&lt;code&gt;themes/light/layout/_partial/article.ejs&lt;/code&gt;,在header标签的末尾添加以下代码&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;% if (item.excerpt &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; index){ %&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;% } else { %&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;busuanzi_container_page_pv&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;head-plus&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fa fa-user&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;busuanzi_value_page_pv&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fa fa-spinner fa-spin&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;次访问
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;head-plus&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fa fa-comments&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ds-thread-count&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;data-thread-key&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;%= page.layout %&amp;gt;-&amp;lt;%= page.slug %&amp;gt;&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fa fa-spinner fa-spin&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;条评论
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;% } %&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1esmas5d58oj20x50jc46f.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;修改后的article.ejs&#34;
	
	
&gt;&lt;!-- raw HTML omitted --&gt;2.修改&lt;code&gt;themes/light/layout/_partial/footer.ejs&lt;/code&gt;,下面是footer.ejs的&lt;strong&gt;全部代码&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;alignleft&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;% if (config.author){ %&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;amp;copy; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;%= new Date().getFullYear() %&amp;gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;%= config.author %&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;% } else { %&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;amp;copy; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;%= new Date().getFullYear() %&amp;gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;%= config.title %&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;lt;&lt;/span&gt;% } %&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;busuanzi_container_site_pv&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fa fa-flag&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt;&amp;gt;    你是第&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;busuanzi_value_site_pv&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fa fa-spinner fa-spin&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;i&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;个到访的小伙伴
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;clearfix&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;!-- raw HTML omitted --&gt;3.修改&lt;code&gt;themes/light/layout/_partial/after_footer.ejs&lt;/code&gt;,我们在&lt;strong&gt;最后&lt;/strong&gt;添加上下面的代码:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;script&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;async&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;src&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/script&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;4.修改&lt;code&gt;themes\light\source\css\_partial\article.styl&lt;/code&gt;,我们在第124行,在&lt;code&gt;.entry&lt;/code&gt;之前添加上以下代码,尤其注意与左右的间距,因为它是一个树形结构,它与左侧的距离,影响着它的层级.我们这里应该和entry平级,下面代码应该与&lt;code&gt;.entry&lt;/code&gt;对齐&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;  .busuanzi_container_page_pv
      margin:20px 0
      color: # 817C7C
      font-size: 12px
  # busuanzi_value_page_pv
      padding-left:4px
  .head-plus
      padding-left:4px
  .ds-thread-count
      padding-left:4px
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;最终效果如图:
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1esmajbsx38j20k30gwadu.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;添加css,注意左对齐&#34;
	
	
&gt;&lt;!-- raw HTML omitted --&gt;5.修改&lt;code&gt;themes\light\source\css\_partial\footer.styl&lt;/code&gt;,在最后添加上以下代码&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# busuanzi_value_site_pv
  color:black
  padding:4px
# busuanzi_container_site_pv
  padding-left:2em
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;6.修改&lt;code&gt;themes\light\source\css\_partial\variable.styl&lt;/code&gt;,在最后添加以下代码&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;@import url(&amp;#34;http://libs.useso.com/js/font-awesome/4.2.0/css/font-awesome.min.css&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ok  打完收工&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 博客访问技术工具&amp;ndash;不蒜子 &lt;a class=&#34;link&#34; href=&#34;http://ibruce.info/2015/04/04/busuanzi/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://ibruce.info/2015/04/04/busuanzi/&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;http://dev.duoshuo.com/docs/5016427f77cf5fa30500000e&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;多说-代码显示【文章评论数】方法&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;致谢&#34;&gt;致谢
&lt;/h1&gt;&lt;p&gt;这里，要感谢我最亲爱的笨笨&lt;a class=&#34;link&#34; href=&#34;http://huirong.github.io&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://huirong.github.io&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>基于python的requests库，模拟登录csdn博客</title>
        <link>https://blog.huirongis.me/post/python-requests-login-csdn-blog/</link>
        <pubDate>Sat, 23 May 2015 19:06:04 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/python-requests-login-csdn-blog/</guid>
        <description>&lt;p&gt;还是继续我的python学习。以前写的爬虫用的urllib2来实现，也用过scrapy的爬虫框架，这次试试requests，刚开始用，用起来确实比urllib2好，封装的更好一些，使用起来简单方便很多。&lt;/p&gt;
&lt;h1 id=&#34;安装requests库&#34;&gt;安装requests库
&lt;/h1&gt;&lt;p&gt;在ubuntu下面安装很简单&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install requests
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;就搞定了&lt;/p&gt;
&lt;h1 id=&#34;快速上手的小例子&#34;&gt;快速上手的小例子
&lt;/h1&gt;&lt;p&gt;下面给个快速入门，最简单的例子&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; requests
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; requests&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;http://www.baidu.com&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;text
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这段代码，很简单。
第一行，引入requests库，这是必然的。
第二行，通过get方式获取baidu首页的内容。
第三行，把返回的response内容，输出出来&lt;/p&gt;
&lt;p&gt;果然很简单，这样就可以发送一个get请求，同理，你还可以使用
&lt;code&gt;requests.post&lt;/code&gt;,&lt;code&gt;requests.put&lt;/code&gt;,&lt;code&gt;requests.options&lt;/code&gt;,&lt;code&gt;requests.head&lt;/code&gt;，发送请求，没错就是这么简单，果然比urllib2好用。&lt;/p&gt;
&lt;h1 id=&#34;模拟登录csdn&#34;&gt;模拟登录csdn
&lt;/h1&gt;&lt;p&gt;我们需要其他的辅助工具&lt;/p&gt;
&lt;h3 id=&#34;浏览器firefox&#34;&gt;浏览器：Firefox
&lt;/h3&gt;&lt;h3 id=&#34;浏览器插件tamper-datafirebug&#34;&gt;浏览器插件：tamper data，firebug
&lt;/h3&gt;&lt;p&gt;我们需要tamper data来拦截请求，因为chrome没有这个功能的插件，所以这个只能使用firefox来做（除了拦截请求chrome没有，其他的工作都可以用chrome，看个人喜好吧）。&lt;/p&gt;
&lt;h1 id=&#34;分析登录过程&#34;&gt;分析登录过程
&lt;/h1&gt;&lt;h2 id=&#34;1-打开登录页面&#34;&gt;1 打开登录页面
&lt;/h2&gt;&lt;p&gt;我们首先打开csdn的登录页面&lt;code&gt;https://passport.csdn.net/account/login?ref=toolbar&lt;/code&gt;
这个链接，前面部分是登录的网址，问号后面的参数，顾名思义，referer，就是你从哪里跳过来的，也许是一个页面跳转到登录的，toolbar就是我自己点击顶部导航栏，然后跳转到登录页面的。&lt;/p&gt;
&lt;h2 id=&#34;2-清除相关的cookie&#34;&gt;2 清除相关的cookie
&lt;/h2&gt;&lt;p&gt;为了排除不必要的干扰，我们先清除掉所有的相关的cookie，这样方便我们分析哪些参数是必须的。
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1esegc1itw2j20qu075779.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;firefox中，清除cookie&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;3-登录过程分析&#34;&gt;3 登录过程分析
&lt;/h2&gt;&lt;p&gt;清除了cookie后，我们刷新一下页面&lt;code&gt;https://passport.csdn.net/account/login?ref=toolbar&lt;/code&gt;，重新获取对应的cookie。
然后我们就开始用tamper data来拦截请求。
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1esegfztiz7j20s40ftdjw.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;使用tamper data&#34;
	
	
&gt;
我们点击&lt;code&gt;start tamper&lt;/code&gt;，在网页中填写用户名和密码。点击&lt;code&gt;登录&lt;/code&gt;，会发出一个请求，然后tamper data会拦截下这个请求，询问我们是否拦截，点击tamper，我们可以在这个请求提交之前，查看请求的内容，还可以做删改。
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1esegkslypyj20y20gntdt.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;发出第一个登录请求前拦截下来，查看表单内容&#34;
	
	
&gt;
csdn的登录过程比较简单，发送一个登录表单过去，就登录成功了，不过记得修改headers，这是后话。&lt;/p&gt;
&lt;h2 id=&#34;4-开始模拟登录&#34;&gt;4 开始模拟登录
&lt;/h2&gt;&lt;p&gt;知道登录过程了，我们就开始写登录的代码。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; requests
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 使用beautifulsoup来处理获取的html内容，这个库需要安装，还是使用pip install beautifulsoup4来安装&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; bs4 &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; BeautifulSoup &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; bs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 这个函数使用来提取流水号的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;toJson&lt;/span&gt;(str):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    提取lt流水号，将数据化为一个字典
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    soup &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; bs(str)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tt &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# 提取form表单中所有的input标签，以字典的形式来保存name：value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; inp &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; soup&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;form&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;find_all(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;input&amp;#39;&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; inp&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            tt[inp&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;)] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;inp&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; tt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 这行代码，是用来维持cookie的，你后续的操作都不用担心cookie，他会自动带上相应的cookie&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;s &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; requests&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Session()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 我们需要带表单的参数,这里面有个参数lt,登录操作的流水号，我们需要从html页面中进行提取&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;payload &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;username&amp;#39;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;jackroyal&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;password&amp;#39;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;123456&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;lt&amp;#39;&lt;/span&gt;:soup[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;lt&amp;#34;&lt;/span&gt;],&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;execution&amp;#39;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;e1s1&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;_eventId&amp;#39;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;submit&amp;#39;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; s&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;post(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http://passport.csdn.net/account/login&amp;#34;&lt;/span&gt;,data&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;payload,headers&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;header)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;text
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ok，至此，登录就成功了&lt;/p&gt;
&lt;h2 id=&#34;5-优化&#34;&gt;5 优化
&lt;/h2&gt;&lt;p&gt;当你登录成功后，你会问，我怎么知道登录成功了呢？当你试图去抓取&lt;code&gt;http://write.blog.csdn.net/postlist&lt;/code&gt;的内容的时候，你会发现一个403的错误，这是为啥呢？
很简单，&lt;code&gt;user agent&lt;/code&gt;没有修改，我们用的是默认的&lt;code&gt;user agent&lt;/code&gt;，这可不是一个正常的用户，所以被网站拒绝了。我们加上他就好了&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;header &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;User-Agent&amp;#39;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0&amp;#39;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; s&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;post(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http://passport.csdn.net/account/login&amp;#34;&lt;/span&gt;,data&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;payload,headers&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;header)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;text
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;后话&#34;&gt;后话
&lt;/h1&gt;&lt;p&gt;上面的代码还是太简单，我们都知道cookie是有有效期的，我在做调试的时候，没修改一次，就要模拟登录一次，这样不好，我们要保存cookie，这样下次就不需要重新发送登录请求了
分享出完整的代码&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# !/usr/bin/env python&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# -*- coding: utf-8 -*-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; requests
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; time
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; os
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; bs4 &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; BeautifulSoup &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; bs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; cookielib &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; LWPCookieJar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;toJson&lt;/span&gt;(str):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    提取lt流水号，将数据化为一个字典
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    soup &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; bs(str)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tt &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; inp &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; soup&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;form&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;find_all(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;input&amp;#39;&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; inp&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            tt[inp&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;)] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;inp&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; tt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# cookie setting&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;s &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; requests&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Session()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;s&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;cookies &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; LWPCookieJar(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;cookiejar&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;header &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;User-Agent&amp;#39;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0&amp;#39;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;path&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;exists(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;cookiejar&amp;#39;&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;there is no cookie,setting&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    r &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; s&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http://passport.csdn.net/account/login&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    soup &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; toJson(r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;text)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    payload &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;username&amp;#39;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;jackroyal&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;password&amp;#39;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;123456&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;lt&amp;#39;&lt;/span&gt;:soup[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;lt&amp;#34;&lt;/span&gt;],&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;execution&amp;#39;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;e1s1&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;_eventId&amp;#39;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;submit&amp;#39;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print payload
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    r &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; s&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;post(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http://passport.csdn.net/account/login&amp;#34;&lt;/span&gt;,data&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;payload,headers&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;header)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    s&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;cookies&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;save(ignore_discard&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;text
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cookie exists,restore&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    s&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;cookies&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;load(ignore_discard&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# r = s.get(&amp;#34;https://passport.csdn.net/content/loginbox/loginapi.js&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; s&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http://write.blog.csdn.net/postlist&amp;#34;&lt;/span&gt;,headers&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;header)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;text
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;http://requests-docs-cn.readthedocs.org/zh_CN/latest/user/quickstart.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;requests官方文档快速上手——中文版&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;http://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;beautifuisoup官方文档&lt;/a&gt;
3 &lt;a class=&#34;link&#34; href=&#34;http://stackoverflow.com/questions/13030095/how-to-save-requests-python-cookies-to-a-file&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;python的requests如何保存cookie到文件&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>html5在ie中遇到的那些坑</title>
        <link>https://blog.huirongis.me/post/holes-in-ie6-about-html5/</link>
        <pubDate>Fri, 15 May 2015 23:19:43 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/holes-in-ie6-about-html5/</guid>
        <description>&lt;p&gt;这段时间,笨笨找了个活儿,做一个页面,能够适配所有的主流浏览器,包括pc,平板和手机等终端(这和当年某刘提的要求一样啊).
我第一个想到的是bootstrap,可惜这货太大了,我只是几个简单的页面,没必要用这么大体量的东西.
搜索一番以后,我找到了我的解决方案,media query,支付宝也是这么解决的.&lt;/p&gt;
&lt;h1 id=&#34;前提条件&#34;&gt;前提条件
&lt;/h1&gt;&lt;p&gt;以下所给出的例子,都是html5的页面,不合适html4.0的页面,也就是说你的头部必须是
&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/code&gt;才行,如果是&lt;code&gt;&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;/code&gt;,是不行的,要仔细看清楚哈.
下面就来罗列一下,这次经过的那些坑:&lt;/p&gt;
&lt;h1 id=&#34;1--自动适配终端屏幕宽度&#34;&gt;1  自动适配终端屏幕宽度
&lt;/h1&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;meta name=&amp;#34;viewport&amp;#34; content=&amp;#34;width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no&amp;#34;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;content属性值 :
width:可视区域的宽度，值可为数字或关键词device-width
height:同width
intial-scale:页面首次被显示是可视区域的缩放级别，取值1.0则页面按实际尺寸显示，无任何缩放
maximum-scale=1.0, minimum-scale=1.0;可视区域的缩放级别，
maximum-scale用户可将页面放大的程序，1.0将禁止用户放大到实际尺寸之上。
user-scalable:是否可对页面进行缩放，no 禁止缩放&lt;/p&gt;
&lt;h1 id=&#34;2--使ie6-8支持html5的元素&#34;&gt;2  使ie6-8支持html5的元素
&lt;/h1&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!-- HTML5 shim, for IE6-8 support of HTML5 elements --&amp;gt;
&amp;lt;!--[if lt IE 9]&amp;gt;
&amp;lt;script src=&amp;#34;http://html5shim.googlecode.com/svn/trunk/html5.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;![endif]--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;以上代码,顾名思义,当ie的版本是9一下的时候,加载html5.js这个文件(建议最好下载下来在本地调用),他是用来帮助ie6-8支持html元素的.&lt;/p&gt;
&lt;h1 id=&#34;3--ie10以下的版本不支持placeholder不完美解决&#34;&gt;3  ie10以下的版本不支持placeholder(不完美解决)
&lt;/h1&gt;&lt;p&gt;placeholder是html5里面才有的东东,ie8不支持就算了,ie9都不支持,伤不起.这个没办法,只能用js去写,网上有很多类似的东西,不过不是很好用,我找到的都不完美.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(function($) {
  /**
   * 没有开花的树
   * http://blog.csdn.net/mycwq/
   * 2012/11/28 15:12
   */

  var placeholderfriend = {
    focus: function(s) {
      s = $(s).hide().prev().show().focus();
      var idValue = s.attr(&amp;#34;id&amp;#34;);
      if (idValue) {
        s.attr(&amp;#34;id&amp;#34;, idValue.replace(&amp;#34;placeholderfriend&amp;#34;, &amp;#34;&amp;#34;));
      }
      var clsValue = s.attr(&amp;#34;class&amp;#34;);
      if (clsValue) {
        s.attr(&amp;#34;class&amp;#34;, clsValue.replace(&amp;#34;placeholderfriend&amp;#34;, &amp;#34;&amp;#34;));
      }
    }
  }

  //判断是否支持placeholder
  function isPlaceholer() {
    var input = document.createElement(&amp;#39;input&amp;#39;);
    return &amp;#34;placeholder&amp;#34; in input;
  }
  //不支持的代码
  if (!isPlaceholer()) {
    $(function() {

      var form = $(this);

      //遍历所有文本框，添加placeholder模拟事件
      var elements = form.find(&amp;#34;input[type=&amp;#39;text&amp;#39;][placeholder]&amp;#34;);
      elements.each(function() {
        var s = $(this);
        var pValue = s.attr(&amp;#34;placeholder&amp;#34;);
        var sValue = s.val();
        if (pValue) {
          if (sValue == &amp;#39;&amp;#39;) {
            s.val(pValue);
          }
        }
      });

      elements.focus(function() {
        var s = $(this);
        var pValue = s.attr(&amp;#34;placeholder&amp;#34;);
        var sValue = s.val();
        if (sValue &amp;amp;&amp;amp; pValue) {
          if (sValue == pValue) {
            s.val(&amp;#39;&amp;#39;);
          }
        }
      });

      elements.blur(function() {
        var s = $(this);
        var pValue = s.attr(&amp;#34;placeholder&amp;#34;);
        var sValue = s.val();
        if (!sValue) {
          s.val(pValue);
        }
      });

      //遍历所有密码框，添加placeholder模拟事件
      var elementsPass = form.find(&amp;#34;input[type=&amp;#39;password&amp;#39;][placeholder]&amp;#34;);
      elementsPass.each(function(i) {
        var s = $(this);
        var pValue = s.attr(&amp;#34;placeholder&amp;#34;);
        var sValue = s.val();
        if (pValue) {
          if (sValue == &amp;#39;&amp;#39;) {
            //DOM不支持type的修改，需要复制密码框属性，生成新的DOM
            var html = this.outerHTML || &amp;#34;&amp;#34;;
            html = html.replace(/\s*type=([&amp;#39;&amp;#34;])?password\1/gi, &amp;#34; type=text placeholderfriend&amp;#34;)
              .replace(/\s*(?:value|on[a-z]+|name)(=([&amp;#39;&amp;#34;])?\S*\1)?/gi, &amp;#34; &amp;#34;)
              .replace(/\s*placeholderfriend/, &amp;#34; placeholderfriend value=&amp;#39;&amp;#34; + pValue
              + &amp;#34;&amp;#39; &amp;#34; + &amp;#34;onfocus=&amp;#39;placeholderfriendfocus(this);&amp;#39; &amp;#34;);
            var idValue = s.attr(&amp;#34;id&amp;#34;);
            if (idValue) {
              s.attr(&amp;#34;id&amp;#34;, idValue + &amp;#34;placeholderfriend&amp;#34;);
            }
            var clsValue = s.attr(&amp;#34;class&amp;#34;);
            if (clsValue) {
              s.attr(&amp;#34;class&amp;#34;, clsValue + &amp;#34;placeholderfriend&amp;#34;);
            }
            s.hide();
            s.after(html);
          }
        }
      });

      elementsPass.blur(function() {
        var s = $(this);
        var sValue = s.val();
        if (sValue == &amp;#39;&amp;#39;) {
          var idValue = s.attr(&amp;#34;id&amp;#34;);
          if (idValue) {
            s.attr(&amp;#34;id&amp;#34;, idValue + &amp;#34;placeholderfriend&amp;#34;);
          }
          var clsValue = s.attr(&amp;#34;class&amp;#34;);
          if (clsValue) {
            s.attr(&amp;#34;class&amp;#34;, clsValue + &amp;#34;placeholderfriend&amp;#34;);
          }
          s.hide().next().show();
        }
      });

    });
  }
  window.placeholderfriendfocus = placeholderfriend.focus;
})(jQuery);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我最终选择这段代码,他能够在ie的各版本中正常运行,支持&lt;code&gt;text&lt;/code&gt;和&lt;code&gt;password&lt;/code&gt;标签.
唯一的不足是,你直接点提交,你的text里面会有内容,内容就是placeholder中设置的提示内容.&lt;/p&gt;
&lt;h1 id=&#34;4--background-size在ie9一下不支持&#34;&gt;4  background-size在ie9一下不支持
&lt;/h1&gt;&lt;p&gt;background-size属性是用来让背景图片平铺的.不过ie9一下并不支持这个属性,我们使用滤镜来实现平铺的效果,示例代码如下.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;background-size: cover;
    filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=&amp;#39;./assets/images/01.png&amp;#39;, sizingMethod=&amp;#39;scale&amp;#39;)\9;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;需要注意的是,这里的图片路径是相对于html文件的,不是css的路径,如果设置了没效果,先检查下你的路径.&lt;/p&gt;
&lt;h1 id=&#34;5--input输入框-光标不居中&#34;&gt;5  input输入框 光标不居中
&lt;/h1&gt;&lt;p&gt;这个问题来自于魅族手机,还有老大难的ie6-8的测试中.
解决方法是设置&lt;code&gt;height&lt;/code&gt;和&lt;code&gt;line-height&lt;/code&gt;等高,没那么简单,这里有技巧的&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;line-height&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;normal&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/*这行代码解决了魅族手机中的不居中问题*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;line-height&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;42px&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/*这行css代码的含义是ie9以下设置line-height为42px*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;6--opacity的继承问题&#34;&gt;6  opacity的继承问题
&lt;/h1&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;style&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;hello&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;moto&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果我们给父div设置了一个&lt;code&gt;opacity&lt;/code&gt;为0.1,即使我们给子div设置&lt;code&gt;opacity&lt;/code&gt;为1,也是不管用的,如图
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1es5fm0jafhj20iv0ecq46.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;未设置父div的opacity之前&#34;
	
	
&gt;
设置父div的&lt;code&gt;opacity&lt;/code&gt;之后
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1es5fnsk3pvj20hy0fdwfm.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;设置父div的opacity之后&#34;
	
	
&gt;
我们可以清楚看到子div受到了影响.
解决办法:解除父子关系,把子div从父div中挪出来&lt;/p&gt;
&lt;h1 id=&#34;7--border-radius在ie9以下不支持&#34;&gt;7  border-radius在ie9以下不支持
&lt;/h1&gt;&lt;p&gt;输入框等其他地方用到圆角的话,在老版本ie中果断是没有支持的.
我们需要用hack的方式&lt;a class=&#34;link&#34; href=&#34;http://css3pie.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;pie&lt;/a&gt;,去实现border-radius和box-shadow等功能.加入pie以后的css代码如下:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    -moz-border-radius: 6px;
    -webkit-border-radius: 6px;
    border-radius: 6px;
    behavior: url(assets/css/pie.htc);/*这一行是核心*/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;缺点:设置的border-radius四角的设置值都是相同的&lt;/p&gt;
&lt;h1 id=&#34;8-css递进关系&#34;&gt;8 css递进关系
&lt;/h1&gt;&lt;p&gt;挖坑,以后填&lt;/p&gt;
&lt;p&gt;ps:晚安,亲爱的&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;http://www.cnblogs.com/yuzhongwusan/p/4184923.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;meta name=&amp;ldquo;viewport&amp;rdquo; content=&amp;ldquo;width=device-width,initial-scale=1.0&amp;rdquo; 解释&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;http://css3pie.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;pie用hack方式在ie中实现border-radius&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>win8中使用vs2010配置opencv</title>
        <link>https://blog.huirongis.me/post/opencv-and-vs2010-in-win8/</link>
        <pubDate>Fri, 15 May 2015 19:56:06 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/opencv-and-vs2010-in-win8/</guid>
        <description>&lt;p&gt;今天在师兄的帮助下,总算配置好了opencv.&lt;/p&gt;
&lt;h1 id=&#34;1-系统环境和软件版本&#34;&gt;1 系统环境和软件版本
&lt;/h1&gt;&lt;p&gt;操作系统:win8 64位
vs版本:vs2010 32位
opencv版本:opencv 2.4.10&lt;/p&gt;
&lt;h1 id=&#34;2-配置opencv&#34;&gt;2 配置opencv
&lt;/h1&gt;&lt;p&gt;安装vs比较简单,这里不再赘述.
现在说下配置opencv.
网上有很多相关的配置,都是设置环境变量,然后添加库目录,包含目录,blablabla.
这样做的坏处是,每次我新建一个项目,都要重复以上操作,这样岂不是很蛋疼.
如果你移植你的程序给别人,别人也还要去配置这些东西才能够运行,是不是很不方便?
所以,师兄教给我简单粗暴的办法,直接把相关文件手动复制到vs的目录下,这样就没这么多事了.
&lt;strong&gt;缺点:每次都需要手动设置你所需要调用的lib文件&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;解压opencv到某个目录&#34;&gt;解压opencv到某个目录
&lt;/h2&gt;&lt;p&gt;这个很简单,双击那个exe,选择一个目录,就会把opencv的文件解压到你设定的那个目录.
我将它解压到&lt;code&gt;D:/opencv&lt;/code&gt;下.&lt;/p&gt;
&lt;h2 id=&#34;复制include文件夹&#34;&gt;复制include文件夹
&lt;/h2&gt;&lt;p&gt;复制&lt;code&gt;D:\opencv\build\include&lt;/code&gt;目录下的&lt;code&gt;opencv&lt;/code&gt;和&lt;code&gt;opencv2&lt;/code&gt;
到&lt;code&gt;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include&lt;/code&gt;.
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1es5atg7oimj20kw081ta4.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;opencv解压后的include目录&#34;
	
	
&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1es5az6qsa7j20jc099jtf.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;复制以后的效果截图&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;复制lib文件夹&#34;&gt;复制lib文件夹
&lt;/h2&gt;&lt;p&gt;同理,复制lib文件夹
从&lt;code&gt;D:\opencv\build\x86\vc10\lib&lt;/code&gt;复制到&lt;code&gt;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib&lt;/code&gt;
如果你的程序是win32就选择x86,如果你写的程序是64位的,就复制x64的程序&lt;/p&gt;
&lt;h2 id=&#34;复制bin文件夹&#34;&gt;复制bin文件夹
&lt;/h2&gt;&lt;p&gt;复制bin目录下的东西,我们只需要系统找得到就行,所以我们这里采用环境变量的搞法&lt;/p&gt;
&lt;p&gt;我们修改path变量,在后面添加&lt;code&gt;;d:\opencv\build\x86\vc10\bin&lt;/code&gt;,效果如图所示&lt;!-- raw HTML omitted --&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1es5bew5vcjj20e10g4go8.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;修改path变量,添加opencv的bin目录路径&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;3-写代码调试&#34;&gt;3 写代码调试
&lt;/h1&gt;&lt;p&gt;代码如下:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c#&#34; data-lang=&#34;c#&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt; include &amp;lt;opencv2/opencv.hpp&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt; include &amp;lt;iostream&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt; include &amp;lt;&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt; ifdef _DEBUG
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# pragma&lt;/span&gt; comment(lib,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;opencv_core2410d.lib&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# pragma&lt;/span&gt; comment(lib,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;opencv_highgui2410d.lib&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# pragma&lt;/span&gt; comment(lib,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;opencv_core2410.lib&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# pragma&lt;/span&gt; comment(lib,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;opencv_highgui2410.lib&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# endif&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;using&lt;/span&gt; namespace cv;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;using&lt;/span&gt; namespace std;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; main()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Mat img = imread(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ie8-2.png&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(img.empty())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cout&amp;lt;&amp;lt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; -&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   imshow(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;xx的靓照&amp;#34;&lt;/span&gt;,img);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   waitKey();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注意一下这段宏设置&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# ifdef _DEBUG
# pragma comment(lib,&amp;#34;opencv_core2410d.lib&amp;#34;)
# pragma comment(lib,&amp;#34;opencv_highgui2410d.lib&amp;#34;)
# else
# pragma comment(lib,&amp;#34;opencv_core2410.lib&amp;#34;)
# pragma comment(lib,&amp;#34;opencv_highgui2410.lib&amp;#34;)
# endif
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;debug和release,分别调用对应的lib
如果你当前是debug模式&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# pragma comment(lib,&amp;#34;opencv_core2410d.lib&amp;#34;)
# pragma comment(lib,&amp;#34;opencv_highgui2410d.lib&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这段代码是必须要的,以后调用相应的lib文件,我们都要手动在头部加入这句话才行
否则,你会看到下面这堆东西&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;1&amp;gt;  test.cpp
1&amp;gt;ManifestResourceCompile:
1&amp;gt;  所有输出均为最新。
1&amp;gt;test.obj : error LNK2019: 无法解析的外部符号 &amp;#34;int __cdecl cv::waitKey(int)&amp;#34; (?waitKey@cv@@YAHH@Z)，该符号在函数 _main 中被引用
1&amp;gt;test.obj : error LNK2019: 无法解析的外部符号 &amp;#34;void __cdecl cv::imshow(class std::basic_string&amp;lt;char,struct std::char_traits&amp;lt;char&amp;gt;,class std::allocator&amp;lt;char&amp;gt; &amp;gt; const &amp;amp;,class cv::_InputArray const &amp;amp;)&amp;#34; (?imshow@cv@@YAXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABV_InputArray@1@@Z)，该符号在函数 _main 中被引用
1&amp;gt;test.obj : error LNK2019: 无法解析的外部符号 &amp;#34;public: __thiscall cv::_InputArray::_InputArray(class cv::Mat const &amp;amp;)&amp;#34; (??0_InputArray@cv@@QAE@ABVMat@1@@Z)，该符号在函数 _main 中被引用
1&amp;gt;test.obj : error LNK2019: 无法解析的外部符号 &amp;#34;class cv::Mat __cdecl cv::imread(class std::basic_string&amp;lt;char,struct std::char_traits&amp;lt;char&amp;gt;,class std::allocator&amp;lt;char&amp;gt; &amp;gt; const &amp;amp;,int)&amp;#34; (?imread@cv@@YA?AVMat@1@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@Z)，该符号在函数 _main 中被引用
1&amp;gt;test.obj : error LNK2019: 无法解析的外部符号 &amp;#34;void __cdecl cv::fastFree(void *)&amp;#34; (?fastFree@cv@@YAXPAX@Z)，该符号在函数 &amp;#34;public: __thiscall cv::Mat::~Mat(void)&amp;#34; (??1Mat@cv@@QAE@XZ) 中被引用
1&amp;gt;test.obj : error LNK2019: 无法解析的外部符号 &amp;#34;public: void __thiscall cv::Mat::deallocate(void)&amp;#34; (?deallocate@Mat@cv@@QAEXXZ)，该符号在函数 &amp;#34;public: void __thiscall cv::Mat::release(void)&amp;#34; (?release@Mat@cv@@QAEXXZ) 中被引用
1&amp;gt;test.obj : error LNK2019: 无法解析的外部符号 &amp;#34;int __cdecl cv::_interlockedExchangeAdd(int *,int)&amp;#34; (?_interlockedExchangeAdd@cv@@YAHPAHH@Z)，该符号在函数 &amp;#34;public: void __thiscall cv::Mat::release(void)&amp;#34; (?release@Mat@cv@@QAEXXZ) 中被引用
1&amp;gt;C:\Users\chenhao\documents\visual studio 2010\Projects\b\Debug\b.exe : fatal error LNK1120: 7 个无法解析的外部命令
1&amp;gt;
1&amp;gt;生成失败。
1&amp;gt;
1&amp;gt;已用时间 00:00:03.71
========== 生成: 成功 0 个，失败 1 个，最新 0 个，跳过 0 个 ==========
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ok,打完收工!&lt;/p&gt;
&lt;p&gt;ps:上述操作完,应该就好了.我还遇到一个奇葩问题
编译和生成解决方案没有问题，但是开始执行就出现应用程序无法正常启动 0xc000007b错误窗口
最后,原来是权限问题,使用管理员权限打开vs就解决了,win7下找兼容性设置,以管理员权限运行
我的win8没有找到兼容性设置,如图所示操作,每次都能以管理员权限打开vs
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1es5bpz7mkqj20mm0giq7k.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;win8使用管理员权限运行vs2010&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;http://www.cnblogs.com/freedomshe/archive/2012/04/25/2470540.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;VS2010+Opencv-2.4.0的配置攻略&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>opencv中LBPH的人脸识别代码分析</title>
        <link>https://blog.huirongis.me/post/opencv-lbph-source-code-analysis/</link>
        <pubDate>Wed, 06 May 2015 22:32:42 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/opencv-lbph-source-code-analysis/</guid>
        <description>&lt;p&gt;我开始用opencv的时候，用的是opencv最新的3.0版本。不过我死活找不到LBPH的代码，网上的教程也都是opencv 2.4的，so  我也去下一份2.4的源码来读读。&lt;/p&gt;
&lt;p&gt;opencv目前支持一下三种方法来实现人脸识别：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Eigenfaces特征脸createEigenFaceRecognizer()&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fisherfaces createFisherFaceRecognizer()&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Local Binary Patterns Histograms局部二值直方图 createLBPHFaceRecognizer()&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我今天读了一下LBPH的代码。
自动人脸识别就是如何从一幅图像中提取有意义的特征，把它们放入一种有用的表示方式，然后对他们进行一些分类。&lt;!-- raw HTML omitted --&gt;特征脸方法描述了一个全面的方法来识别人脸：面部图像是一个点，这个点是从高维图像空间找到它在低维空间的表示，这样分类变得很简单。低维子空间低维是使用主元分析(Principal Component Analysis,PCA)找到的，它可以找拥有最大方差的那个轴。虽然这样的转换是从最佳重建角度考虑的，但是他没有把标签问题考虑进去。想象一个情况，如果变化是基于外部来源，比如光照。轴的最大方差不一定包含任何有鉴别性的信息，因此此时的分类是不可能的。因此，一个使用线性鉴别(Linear Discriminant Analysis,LDA)的特定类投影方法被提出来解决人脸识别问题。其中一个基本的想法就是，使类内方差最小的同时，使类外方差最大。&lt;!-- raw HTML omitted --&gt;近年来，各种局部特征提取方法出现。为了避免输入的图像的高维数据，仅仅使用的局部特征描述图像的方法被提出，提取的特征(很有希望的)对于局部遮挡、光照变化、小样本等情况更强健。有关局部特征提取的方法有盖伯小波(Gabor Waelets)，离散傅立叶变换(Discrete Cosinus Transform,DCT)，局部二值模式(Local Binary Patterns,LBP)。使用什么方法来提取时域空间的局部特征依旧是一个开放性的研究问题，因为空间信息是潜在有用的信息。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>ubuntu 14.04 安装denyhosts</title>
        <link>https://blog.huirongis.me/post/ubuntu-denyhosts/</link>
        <pubDate>Tue, 28 Apr 2015 20:19:23 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/ubuntu-denyhosts/</guid>
        <description>&lt;h1 id=&#34;起因&#34;&gt;起因
&lt;/h1&gt;&lt;p&gt;因为之前服务器两次被黑，妈蛋。今天在上google+的时候，无意中看到一个维护vps的帖子，就顺手把我的服务器维护下。
之前被黑经历也很简单，因为方便管理的缘故，我给root用户设置了密码，没错，是弱口令，一扫不要一分钟就可以出来的那种。
我在那篇帖子中看到denyhosts这货。东西很简单，分析你的日志，如果有人连续登陆几次密码都错误，那么把他的ip添加到denyhost当中，禁止它继续扫描。这货还很多功能，可以设置禁止时间以后，自动解禁；可以配置自动解禁的次数;还可以配置用户密码尝试的次数，给管理员发邮件等。&lt;/p&gt;
&lt;h1 id=&#34;安装&#34;&gt;安装
&lt;/h1&gt;&lt;h2 id=&#34;1下载源码包解压源码包&#34;&gt;1、下载源码包,解压源码包
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wget http:&lt;span style=&#34;color:#f92672&#34;&gt;//&lt;/span&gt;sourceforge&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;net&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;projects&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;denyhosts&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;files&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;denyhosts&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2.6&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;DenyHosts&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2.6&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;tar&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;gz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tar zxvf DenyHosts&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2.6&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;tar&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;gz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd DenyHosts&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2.6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;2安装部署&#34;&gt;2、安装部署
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python setup&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;py install
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;usr&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;share&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;denyhosts&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cp denyhosts&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;cfg&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;dist denyhosts&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;cfg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cp daemon&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;control&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;dist daemon&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;control
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;3编辑配置文件denyhostscfg&#34;&gt;3、编辑配置文件denyhosts.cfg
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo vi denyhosts&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;cfg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;几个常见的参数如下所示：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;PURGE_DENY：当一个IP被阻止以后，过多长时间被自动解禁。可选如3m（三分钟）、5h（5小时）、2d（两天）、8w（8周）、1y（一年）；
PURGE_THRESHOLD：定义了某一IP最多被解封多少次。即某一IP由于暴力破解SSH密码被阻止/解封达到了PURGE_THRESHOLD次，则会被永久禁止；
BLOCK_SERVICE：需要阻止的服务名；
DENY_THRESHOLD_INVALID：某一无效用户名（不存在的用户）尝试多少次登录后被阻止；
DENY_THRESHOLD_VALID：某一有效用户名尝试多少次登陆后被阻止（比如账号正确但密码错误），root除外；
DENY_THRESHOLD_ROOT：root用户尝试登录多少次后被阻止；
HOSTNAME_LOOKUP：是否尝试解析源IP的域名；```

一般我们就用默认就好，我们只需要改两个地方：
### 第一个，我们注释掉第12行，启用第15行，修改以后结果如下(原因是ubuntu中的log不在/var/log/secure中，而是在/var/log/auth.log中)
![修改后的denyhosts.cfg](/images/692869a3gw1erll3zp3xpj20id0b5q63.jpg)
### 第二个，我们启用第64行，也就是设置，ip被禁止后，禁止5天，这个时间你可以自行设置
去掉前面的`# `,就行了，修改后结果如下
```bash
 63 # purge entries older than 5 days
 64 PURGE_DENY = 5d
 65 ###################################################################### #
 66 
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;4编辑配置文件daemon-control&#34;&gt;4、编辑配置文件daemon-control
&lt;/h2&gt;&lt;p&gt;因为在ubuntu系统中，有些文件不在预设的位置，所以我们需要编辑这个文件
我们只需要改第14行就好了，修改&lt;code&gt;/usr/bin/denyhosts.py&lt;/code&gt;为&lt;code&gt;/usr/local/bin/denyhosts.py&lt;/code&gt;，修改后结果如下&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;14&lt;/span&gt; DENYHOSTS_BIN   &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/local/bin/denyhosts.py&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt; DENYHOSTS_LOCK  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/var/lock/subsys/denyhosts&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt; DENYHOSTS_CFG   &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/share/denyhosts/denyhosts.cfg&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;17&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt; PYTHON_BIN      &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/bin/env python&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;19&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;5运行&#34;&gt;5、运行
&lt;/h2&gt;&lt;p&gt;运行，额，错误一堆啊，我们执行&lt;code&gt;sudo ./daemon-control start&lt;/code&gt;,然后得到如下错误&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;starting DenyHosts:    /usr/bin/env python /usr/local/bin/denyhosts.py --daemon --config&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/usr/share/denyhosts/denyhosts.cfg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;DenyHosts could not obtain lock &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;pid: &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;Errno 2&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; No such file or directory: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/var/lock/subsys/denyhosts&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们可以去&lt;code&gt;/var/lock&lt;/code&gt;下面的确看不到subsys这个文件夹，那我们就手动创建他&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p /var/lock/subsys
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;继续执行&lt;code&gt;sudo ./daemon-control start&lt;/code&gt;，应该就会成功
ps：如果还不成功，他缺什么文件我们就用&lt;code&gt;touch&lt;/code&gt;新建这个文件，如果说&lt;code&gt;file exists&lt;/code&gt;,我们就删除那个文件&lt;/p&gt;
&lt;h2 id=&#34;6添加到开机启动&#34;&gt;6、添加到开机启动
&lt;/h2&gt;&lt;p&gt;第一种是将DenyHosts作为类似apache、mysql一样的服务，这种方法可以通过 /etc/init.d/denyhosts 命令来控制其状态。方法如下：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd /etc/init.d
ln -s /usr/share/denyhosts/daemon-control denyhosts
# 上面的操作就把他变成了一个服务 我们可以使用service denyhosts start来启动服务
# 下面把他添加到开机自启动，我们这里需要安装一个软件来实现
# ubuntu中没有chkconfig命令，网上的教程是用的chkconfig，具体操作查看后面的参考文献1，ubuntu中对应的是update-rc.d，但是不好用，所以我用sysv-rc-conf 
sudo apt-get install sysv-rc-conf
sudo sysv-rc-conf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们设置运行级别2345，编辑以后如下所示
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1erlmrt5ht5j20j80m40zg.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;设置denyhosts开机自启动&#34;
	
	
&gt;
按&lt;code&gt;q&lt;/code&gt;，退出并保存&lt;/p&gt;
&lt;p&gt;第二种是将Denyhosts直接加入rc.local中自动启动（类似于Windows中的“启动文件夹”）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/usr/share/denyhosts/daemon-control start&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; /etc/rc.local
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;http://www.bootf.com/571.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;通过DenyHosts阻止SSH暴力攻击教程&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2 &lt;a class=&#34;link&#34; href=&#34;http://askubuntu.com/questions/534324/var-log-secure-not-present-in-14-04-is-there-any-alternative&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;/var/log/secure not present in 14.04 ,is there any alternative?&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>ubuntu下使用scrapy抓取cnblogs</title>
        <link>https://blog.huirongis.me/post/ubuntu-scrapy-stackoverflow/</link>
        <pubDate>Sun, 26 Apr 2015 16:52:28 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/ubuntu-scrapy-stackoverflow/</guid>
        <description>&lt;p&gt;今天在伯乐在线上看到一篇翻译的博客，讲的是使用scrapy来抓取stackoverflow上的问题，刚好好久没用这个，于是一并捡起来玩一下。&lt;/p&gt;
&lt;h1 id=&#34;软件安装&#34;&gt;软件安装
&lt;/h1&gt;&lt;p&gt;我的环境是：ubuntu 14.04 lts
需要安装相关软件&lt;/p&gt;
&lt;h2 id=&#34;scrapy&#34;&gt;scrapy
&lt;/h2&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;pip install Scrapy
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;pymongo&#34;&gt;PyMongo
&lt;/h2&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;pip install pymongo
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;mongodb&#34;&gt;Mongodb
&lt;/h2&gt;&lt;p&gt;上面安装的是python使用Mongodb的接口，很显然，我们要安装Mongodb才能使用&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo apt-get install mongodb-server
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;至此，要使用的软件都已经安装完毕&lt;/p&gt;
&lt;h1 id=&#34;使用scrapy新建工程&#34;&gt;使用scrapy新建工程
&lt;/h1&gt;&lt;p&gt;使用scrapy新建工程很简单，如下所示，我们新建一个stack的项目，他会在你的当前目录新建一个stack文件夹&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;scrapy startproject stack
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;并且会建成如下所示的目录树结构&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;chen@chen-P31:~$ tree stack
stack
├── stack
│   ├── __init__.py
│   ├── items.py
│   ├── pipelines.py
│   ├── settings.py
│   └── spiders
│       └── __init__.py
└── scrapy.cfg
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;接下来，我们修改items.py的内容，这个文件用于定义存储“容器”，用来存储将要抓取的数据。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; scrapy.item &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; Item,Field
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;StackItem&lt;/span&gt;(Item):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# define the fields for your item here like:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# name = scrapy.Field()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    title &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Field()&lt;span style=&#34;color:#75715e&#34;&gt;# 我们添加两个字段，我们等会儿会抓取一个标题和url两个字段&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    url &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Field()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;接着，还有一个很重要的东西，对，就是我们的蜘蛛，我们在spider目录下，新建一个stack_spider.py文件。顾名思义，这就是我们的蜘蛛。我们需要定义我们爬虫的起点，爬虫的规则等等&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; scrapy &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; Spider
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; stack.items &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; StackItem  &lt;span style=&#34;color:#75715e&#34;&gt;# 导入我们上面定义的容器类&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;StackSpider&lt;/span&gt;(Spider):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;stack&amp;#39;&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;# 定义我们爬虫的名字&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    allowed_domains &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cnblogs.com&amp;#34;&lt;/span&gt;]   &lt;span style=&#34;color:#75715e&#34;&gt;# 规定爬虫爬取的域名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    start_urls &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;http://www.cnblogs.com/geqianst/p/&amp;#39;&lt;/span&gt;,]   &lt;span style=&#34;color:#75715e&#34;&gt;# 爬虫工作的起点&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;parse&lt;/span&gt;(self, response):&lt;span style=&#34;color:#75715e&#34;&gt;# 爬虫用来做数据解析的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        questions &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; response&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;xpath(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;//div[@id=&amp;#34;myposts&amp;#34;]//a[@id]&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# xpath选择器，这里的含义是取所有id为myposts的div，在它下面找所有带id的超链接a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# 实际结果是这样的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# [&amp;lt;Selector xpath=&amp;#39;//div[@id=&amp;#34;myposts&amp;#34;]//a[@id]&amp;#39; data=u&amp;#39;&amp;lt;a id=&amp;#34;PostsList1_rpPosts_TitleUrl_0&amp;#34; hr&amp;#39;&amp;gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# &amp;lt;Selector xpath=&amp;#39;//div[@id=&amp;#34;myposts&amp;#34;]//a[@id]&amp;#39; data=u&amp;#39;&amp;lt;a id=&amp;#34;PostsList1_rpPosts_TitleUrl_1&amp;#34; hr&amp;#39;&amp;gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# &amp;lt;Selector xpath=&amp;#39;//div[@id=&amp;#34;myposts&amp;#34;]//a[@id]&amp;#39; data=u&amp;#39;&amp;lt;a id=&amp;#34;PostsList1_rpPosts_TitleUrl_2&amp;#34; hr&amp;#39;&amp;gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# &amp;lt;Selector xpath=&amp;#39;//div[@id=&amp;#34;myposts&amp;#34;]//a[@id]&amp;#39; data=u&amp;#39;&amp;lt;a id=&amp;#34;PostsList1_rpPosts_TitleUrl_3&amp;#34; hr&amp;#39;&amp;gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# &amp;lt;Selector xpath=&amp;#39;//div[@id=&amp;#34;myposts&amp;#34;]//a[@id]&amp;#39; data=u&amp;#39;&amp;lt;a id=&amp;#34;PostsList1_rpPosts_TitleUrl_4&amp;#34; hr&amp;#39;&amp;gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# &amp;lt;Selector xpath=&amp;#39;//div[@id=&amp;#34;myposts&amp;#34;]//a[@id]&amp;#39; data=u&amp;#39;&amp;lt;a id=&amp;#34;PostsList1_rpPosts_TitleUrl_5&amp;#34; hr&amp;#39;&amp;gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# &amp;lt;Selector xpath=&amp;#39;//div[@id=&amp;#34;myposts&amp;#34;]//a[@id]&amp;#39; data=u&amp;#39;&amp;lt;a id=&amp;#34;PostsList1_rpPosts_TitleUrl_6&amp;#34; hr&amp;#39;&amp;gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# &amp;lt;Selector xpath=&amp;#39;//div[@id=&amp;#34;myposts&amp;#34;]//a[@id]&amp;#39; data=u&amp;#39;&amp;lt;a id=&amp;#34;PostsList1_rpPosts_TitleUrl_7&amp;#34; hr&amp;#39;&amp;gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# &amp;lt;Selector xpath=&amp;#39;//div[@id=&amp;#34;myposts&amp;#34;]//a[@id]&amp;#39; data=u&amp;#39;&amp;lt;a id=&amp;#34;PostsList1_rpPosts_TitleUrl_8&amp;#34; hr&amp;#39;&amp;gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# &amp;lt;Selector xpath=&amp;#39;//div[@id=&amp;#34;myposts&amp;#34;]//a[@id]&amp;#39; data=u&amp;#39;&amp;lt;a id=&amp;#34;PostsList1_rpPosts_TitleUrl_9&amp;#34; hr&amp;#39;&amp;gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; question &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; questions:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            item &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; StackItem()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            item[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;title&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; question&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;xpath(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;text()&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;extract()[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            item[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;url&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; question&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;xpath(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;@href&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;extract()[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print item
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;yield&lt;/span&gt; item
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;测试&#34;&gt;测试
&lt;/h1&gt;&lt;p&gt;ok，上述工作基本完成，我们来测试一下&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;scrapy crawl stack
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;还可以这样测试一下，使用shell命令
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1erjvd7qeqdj213z0j9h2h.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;用shell测试xpath&#34;
	
	
&gt;
妈蛋，我的竟然出错了，输出如下&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;chen@chen-P31:~/stack$ scrapy crawl stack
2015-04-26 16:49:11+0800 [scrapy] INFO: Scrapy 0.24.6 started (bot: stack)
2015-04-26 16:49:11+0800 [scrapy] INFO: Optional features available: ssl, http11
2015-04-26 16:49:11+0800 [scrapy] INFO: Overridden settings: {&amp;#39;NEWSPIDER_MODULE&amp;#39;: &amp;#39;stack.spiders&amp;#39;, &amp;#39;SPIDER_MODULES&amp;#39;: [&amp;#39;stack.spiders&amp;#39;], &amp;#39;BOT_NAME&amp;#39;: &amp;#39;stack&amp;#39;}
Traceback (most recent call last):
  File &amp;#34;/usr/local/bin/scrapy&amp;#34;, line 11, in &amp;lt;module&amp;gt;
    sys.exit(execute())
  File &amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/cmdline.py&amp;#34;, line 143, in execute
    _run_print_help(parser, _run_command, cmd, args, opts)
  File &amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/cmdline.py&amp;#34;, line 89, in _run_print_help
    func(*a, **kw)
  File &amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/cmdline.py&amp;#34;, line 150, in _run_command
    cmd.run(args, opts)
  File &amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/commands/crawl.py&amp;#34;, line 60, in run
    self.crawler_process.start()
  File &amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/crawler.py&amp;#34;, line 92, in start
    if self.start_crawling():
  File &amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/crawler.py&amp;#34;, line 124, in start_crawling
    return self._start_crawler() is not None
  File &amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/crawler.py&amp;#34;, line 139, in _start_crawler
    crawler.configure()
  File &amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/crawler.py&amp;#34;, line 46, in configure
    self.extensions = ExtensionManager.from_crawler(self)
  File &amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/middleware.py&amp;#34;, line 50, in from_crawler
    return cls.from_settings(crawler.settings, crawler)
  File &amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/middleware.py&amp;#34;, line 29, in from_settings
    mwcls = load_object(clspath)
  File &amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/utils/misc.py&amp;#34;, line 42, in load_object
    raise ImportError(&amp;#34;Error loading object &amp;#39;%s&amp;#39;: %s&amp;#34; % (path, e))
ImportError: Error loading object &amp;#39;scrapy.telnet.TelnetConsole&amp;#39;: No module named conch
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这是什么gui？
还好我有stackoverflow，google一番，找到解决办法（其实这不是最后的解决办法，请往后看）
网上说是twisted的问题，重新安装一下就好了，ok，走起&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;chen@chen-P31:~/stack$ sudo apt-get install twisted
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package twisted
chen@chen-P31:~/stack$ sudo apt-get install twisted.conch
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Note, selecting &amp;#39;python-twisted-conch&amp;#39; for regex &amp;#39;twisted.conch&amp;#39;
Note, selecting &amp;#39;python2.7-twisted-conch&amp;#39; for regex &amp;#39;twisted.conch&amp;#39;
Note, selecting &amp;#39;python-twisted-conch&amp;#39; instead of &amp;#39;python2.7-twisted-conch&amp;#39;
The following packages were automatically installed and are no longer required:
  cli-common dockmanager freepats gstreamer1.0-plugins-bad-faad
  gstreamer1.0-plugins-bad-videoparsers libbotan-1.10-0:i386 libcdaudio1
  libdbus-glib2.0-cil libdbus2.0-cil libdbusmenu-glib4:i386
  libdbusmenu-gtk4:i386 libegl1-mesa:i386 libegl1-mesa-drivers:i386 libflite1
  libfluidsynth1 libgbm1:i386 libgconf2.0-cil libgdiplus libgif4
  libgles2-mesa:i386 libglib2.0-cil libgme0 libgmp10:i386
  libgnome-desktop-2-17 libgnome-keyring1.0-cil libgnomedesktop2.20-cil
  libgstreamer-plugins-bad0.10-0 libgstreamer-plugins-bad1.0-0 libgtk2.0-cil
  libicu52:i386 libmimic0 libmms0 libmono-addins0.2-cil libmono-cairo4.0-cil
  libmono-corlib4.0-cil libmono-corlib4.5-cil libmono-data-tds4.0-cil
  libmono-i18n-west4.0-cil libmono-i18n4.0-cil libmono-posix4.0-cil
  libmono-security4.0-cil libmono-sharpzip4.84-cil libmono-sqlite4.0-cil
  libmono-system-configuration4.0-cil libmono-system-core4.0-cil
  libmono-system-data4.0-cil libmono-system-drawing4.0-cil
  libmono-system-enterpriseservices4.0-cil
  libmono-system-runtime-serialization-formatters-soap4.0-cil
  libmono-system-security4.0-cil libmono-system-transactions4.0-cil
  libmono-system-web-applicationservices4.0-cil
  libmono-system-web-services4.0-cil libmono-system-web4.0-cil
  libmono-system-xml-linq4.0-cil libmono-system-xml4.0-cil
  libmono-system4.0-cil libmono-web4.0-cil libmpg123-0 libnotify0.4-cil
  libofa0 libopenal-data libopenal1 libopenvg1-mesa:i386 libqrencode3:i386
  libqt5core5a:i386 libqt5dbus5:i386 libqt5gui5:i386 libqt5network5:i386
  libqt5widgets5:i386 libqtshadowsocks:i386 librsvg2-2.18-cil libslv2-9
  libsoundtouch0 libspandsp2 libsrtp0 libssl1.0.0:i386 libv4l-0:i386
  libv4lconvert0:i386 libvo-aacenc0 libvo-amrwbenc0 libwayland-client0:i386
  libwayland-egl1-mesa:i386 libwayland-server0:i386 libwildmidi-config
  libwildmidi1 libwnck2.20-cil libxcb-icccm4:i386 libxcb-image0:i386
  libxcb-keysyms1:i386 libxcb-randr0:i386 libxcb-render-util0:i386
  libxcb-shape0:i386 libxcb-util0:i386 libxcb-xfixes0:i386 libxcb-xkb1:i386
  libxkbcommon-x11-0:i386 libxkbcommon0:i386 libzbar0:i386 mono-4.0-gac
  mono-gac mono-runtime mono-runtime-common mono-runtime-sgen python-mpd
  python-mutagen python-twisted-names
Use &amp;#39;apt-get autoremove&amp;#39; to remove them.
The following extra packages will be installed:
  python-pyasn1
The following NEW packages will be installed:
  python-pyasn1 python-twisted-conch
0 upgraded, 2 newly installed, 0 to remove and 6 not upgraded.
Need to get 286 kB of archives.
After this operation, 1,793 kB of additional disk space will be used.
Do you want to continue? [Y/n] 
Get:1 http://mirrors.ustc.edu.cn/ubuntu/ trusty/main python-pyasn1 all 0.1.7-1ubuntu2 [44.2 kB]
Get:2 http://mirrors.ustc.edu.cn/ubuntu/ trusty/main python-twisted-conch all 1:13.2.0-1ubuntu1 [242 kB]
Fetched 286 kB in 0s (1,595 kB/s)         
Selecting previously unselected package python-pyasn1.
(Reading database ... 359746 files and directories currently installed.)
Preparing to unpack .../python-pyasn1_0.1.7-1ubuntu2_all.deb ...
Unpacking python-pyasn1 (0.1.7-1ubuntu2) ...
Selecting previously unselected package python-twisted-conch.
Preparing to unpack .../python-twisted-conch_1%3a13.2.0-1ubuntu1_all.deb ...
Unpacking python-twisted-conch (1:13.2.0-1ubuntu1) ...
Processing triggers for doc-base (0.10.5) ...
Processing 1 added doc-base file...
Processing triggers for man-db (2.6.7.1-1ubuntu1) ...
Setting up python-pyasn1 (0.1.7-1ubuntu2) ...
Setting up python-twisted-conch (1:13.2.0-1ubuntu1) ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;安装总算完成，再试一次，妈蛋，又来一个新错误，这是什么gui？？？&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chen@chen-P31:~/stack$ scrapy crawl stack
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2015-04-26 16:50:44+0800 &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;scrapy&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; INFO: Scrapy 0.24.6 started &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;bot: stack&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2015-04-26 16:50:44+0800 &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;scrapy&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; INFO: Optional features available: ssl, http11
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2015-04-26 16:50:44+0800 &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;scrapy&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; INFO: Overridden settings: &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;NEWSPIDER_MODULE&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;stack.spiders&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;SPIDER_MODULES&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;stack.spiders&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;BOT_NAME&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;stack&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Traceback &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;most recent call last&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/local/bin/scrapy&amp;#34;&lt;/span&gt;, line 11, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sys.exit&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;execute&lt;span style=&#34;color:#f92672&#34;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/cmdline.py&amp;#34;&lt;/span&gt;, line 143, in execute
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    _run_print_help&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;parser, _run_command, cmd, args, opts&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/cmdline.py&amp;#34;&lt;/span&gt;, line 89, in _run_print_help
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    func&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;*a, **kw&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/cmdline.py&amp;#34;&lt;/span&gt;, line 150, in _run_command
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cmd.run&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;args, opts&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/commands/crawl.py&amp;#34;&lt;/span&gt;, line 60, in run
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    self.crawler_process.start&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/crawler.py&amp;#34;&lt;/span&gt;, line 92, in start
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; self.start_crawling&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/crawler.py&amp;#34;&lt;/span&gt;, line 124, in start_crawling
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; self._start_crawler&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; is not None
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/crawler.py&amp;#34;&lt;/span&gt;, line 139, in _start_crawler
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    crawler.configure&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/crawler.py&amp;#34;&lt;/span&gt;, line 46, in configure
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    self.extensions &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ExtensionManager.from_crawler&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;self&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/middleware.py&amp;#34;&lt;/span&gt;, line 50, in from_crawler
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; cls.from_settings&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;crawler.settings, crawler&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/middleware.py&amp;#34;&lt;/span&gt;, line 29, in from_settings
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    mwcls &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; load_object&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;clspath&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/usr/local/lib/python2.7/dist-packages/scrapy/utils/misc.py&amp;#34;&lt;/span&gt;, line 42, in load_object
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    raise ImportError&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Error loading object &amp;#39;%s&amp;#39;: %s&amp;#34;&lt;/span&gt; % &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;path, e&lt;span style=&#34;color:#f92672&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ImportError: Error loading object &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;scrapy.contrib.memusage.MemoryUsage&amp;#39;&lt;/span&gt;: No module named mail.smtp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最后的最后，我在我们万能的github上找到&lt;a class=&#34;link&#34; href=&#34;https://github.com/scrapy/scrapy/issues/958&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;答案&lt;/a&gt;，原来是我们没有安装python-twisted，安装一下，世界都美好了&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo apt-get install python-twisted
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;输出到文件&#34;&gt;输出到文件
&lt;/h2&gt;&lt;p&gt;为了更直观的看到结果，我们将结果输出到一个json文件&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;scrapy crawl stack -o items.json -t json
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;噢耶，第一个爬虫成功&lt;/p&gt;
&lt;h1 id=&#34;存储到mongodb&#34;&gt;存储到mongodb
&lt;/h1&gt;&lt;p&gt;接下来，我们做最后一件事，我们将结果存储到mongodb的数据库中
在这里，我遇到一个大坑，无论是伯乐在线翻译的博客
还是网上搜索到的一般教程，都是使用pymongo.Connection来连接数据库，可是妈蛋，你使用&lt;code&gt;pip install pymongo&lt;/code&gt;安装的版本都是最新版本3.0.1，那个Connection的写法已经不支持，被丢弃了，擦。
我们来看一下版本，我学到一个新命令&lt;code&gt;pip show pymongo&lt;/code&gt;，用来查看某一个包的版本的。
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1erjct36jnrj20df038dgf.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;查看pymongo版本&#34;
	
	
&gt;
在pymongo 3.0的版本中，已经不再支持pymongo.Connection，而是使用pymongo.MongoClient来替代。&lt;/p&gt;
&lt;h2 id=&#34;第一步&#34;&gt;第一步
&lt;/h2&gt;&lt;p&gt;创建一个用来保存我们抓取数据的数据库。打开&lt;code&gt;settings.py&lt;/code&gt;,指定管道，然后加入数据库的相关设置&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;BOT_NAME &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;stack&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SPIDER_MODULES &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;stack.spiders&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NEWSPIDER_MODULE &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;stack.spiders&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Crawl responsibly by identifying yourself (and your website) on the user-agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# USER_AGENT = &amp;#39;stack (+http://www.yourdomain.com)&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ITEM_PIPELINES &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;stack.pipelines.MongoDBPipeline&amp;#39;&lt;/span&gt;, ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 关于mongodb的相关设置，包括服务器的ip，端口号，数据库名，表名，&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 我也是第一次使用mongodb竟然不需要用户验证信息，而且这表名确实奇怪，叫做MONGODB_COLLECTION&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;MONGODB_SERVER &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;MONGODB_PORT &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;27017&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;MONGODB_DB &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;stackoverflow&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;MONGODB_COLLECTION &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;questions&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;DOWNLOAD_DELAY &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# 抓取的延迟&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;第二步&#34;&gt;第二步
&lt;/h2&gt;&lt;p&gt;我们已经能够爬取和解析html数据了，而且已经配置了数据库，接下来，我们通过&lt;code&gt;pipelines.py&lt;/code&gt;中建立一个管道去连接这两个部分。
我们首先来完成数据库的连接部分&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; pymongo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; scrapy.conf &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; settings
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; scrapy.exceptions &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; DropItem
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; scrapy &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; log
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;MongoDBPipeline&lt;/span&gt;(object):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;__init__&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        connection &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; pymongo&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;MongoClient(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            settings[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;MONGODB_SERVER&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            settings[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;MONGODB_PORT&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        db &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; connection[settings[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;MONGODB_DB&amp;#39;&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;collection &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; db[settings[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;MONGODB_COLLECTION&amp;#39;&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;接下来定义一个处理函数&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process_item&lt;/span&gt;(self, item, spider):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; data &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; item:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; data:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;raise&lt;/span&gt; DropItem(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Missing data!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;collection&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;update({&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;url&amp;#39;&lt;/span&gt;: item[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;url&amp;#39;&lt;/span&gt;]}, dict(item), upsert&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        log&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;msg(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Question added to MongoDB database!&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                level&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;log&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;DEBUG, spider&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;spider)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; item
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ok,搞定，我们再测试一把&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;scrapy crawl stack
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;执行效果如下&#34;&gt;执行效果如下
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1erjv5to5w3j20w70g8wio.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;mongodb数据库管理&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;https://github.com/scrapy/scrapy/issues/958&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ImportError: Error loading object &amp;lsquo;scrapy.contrib.memusage.MemoryUsage&amp;rsquo;: No module named mail.smtp&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;http://stackoverflow.com/questions/8671071/error-to-execute-python-scrappy-module&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://stackoverflow.com/questions/8671071/error-to-execute-python-scrappy-module&lt;/a&gt;
3 &lt;a class=&#34;link&#34; href=&#34;http://python.jobbole.com/81320/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Python下用Scrapy和MongoDB构建爬虫系统（1）&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>使用opencv实现人脸检测</title>
        <link>https://blog.huirongis.me/post/face-detection/</link>
        <pubDate>Sun, 26 Apr 2015 12:54:24 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/face-detection/</guid>
        <description>&lt;p&gt;这两个星期，都在搞这个，就把代码都分享一下，太烂，就不分享到github了。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# !/usr/bin/env python&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# -*- coding:utf-8-*-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;__author__ &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;chen&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; cv2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; Image
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; ImageDraw
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; sys&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;os
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;detectFaces&lt;/span&gt;(image_name):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    img &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;imread(image_name)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    face_cascade &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CascadeClassifier(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;../data2/haarcascades/haarcascade_frontalface_alt.xml&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#75715e&#34;&gt;# 加载级联分类器，这里使用的是intel训练出来的人脸识别分类器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; img&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;ndim &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;:&lt;span style=&#34;color:#75715e&#34;&gt;# 判断图片是否是灰度图像，如果img.ndim==3那就表示不是灰度图像&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        gray &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;cvtColor(img, cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;COLOR_BGR2GRAY)&lt;span style=&#34;color:#75715e&#34;&gt;# 将图片转化为灰度图像&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        gray &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; img
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    faces &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; face_cascade&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;detectMultiScale(gray, scaleFactor&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1.2&lt;/span&gt;, minNeighbors&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;, minSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt;), flags &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CASCADE_SCALE_IMAGE)&lt;span style=&#34;color:#75715e&#34;&gt;# 核心操作，返回图片中所有的人脸的坐标和宽高度&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    result &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (x, y, width, height) &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; faces:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        print (x, y, width, height)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        result&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append((x, y, x&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;width, y&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;height))&lt;span style=&#34;color:#75715e&#34;&gt;# 将原始数据，转化为人脸的四个点的坐标&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; result
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;drawFaces&lt;/span&gt;(image_name):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    faces &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; detectFaces(image_name)&lt;span style=&#34;color:#75715e&#34;&gt;# 此处的返回值是一个元组，(x, y, width, height)，每一个元组都包括人脸的（x,y）坐标，还有人脸的宽度和高度，有这些数据，我们就可以把人脸标记出来，比如画一个矩形框出来&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print faces
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; faces:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        imga &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;imread(image_name)&lt;span style=&#34;color:#75715e&#34;&gt;# 读取图片&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        draw_rects(imga, faces, (&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;,&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;))&lt;span style=&#34;color:#75715e&#34;&gt;# 画矩形标记&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;imshow(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;img&amp;#39;&lt;/span&gt;, imga)&lt;span style=&#34;color:#75715e&#34;&gt;# 显示修改后的矩形&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;waitKey(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;draw_rects&lt;/span&gt;(img, rects, color):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; x1, y1, x2, y2 &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; rects:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;rectangle(img, (x1, y1), (x2, y2), color, &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;)&lt;span style=&#34;color:#75715e&#34;&gt;# 调用cv2的矩形函数，画矩形&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;saveFaces&lt;/span&gt;(image_name):&lt;span style=&#34;color:#75715e&#34;&gt;# 将人脸截取并保存成图片&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    faces &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; detectFaces(image_name)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; faces:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        save_dir &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; image_name&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;)[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;_faces_&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;path&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;isdir(save_dir):&lt;span style=&#34;color:#75715e&#34;&gt;# 检测目录是否存在，如果不存在那就创建目录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;mkdir(save_dir)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (x1, y1, x2, y2) &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; faces:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            imga &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;imread(image_name)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            file_name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;path&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;join(save_dir,str(count)&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;.jpg&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            roi &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; imga[y1:y2,x1:x2]&lt;span style=&#34;color:#75715e&#34;&gt;# 这一步是重点，他就像取一个数组一样，把人脸的部分保存出来&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;imwrite(file_name,cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;cvtColor(cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;resize(roi,(&lt;span style=&#34;color:#ae81ff&#34;&gt;92&lt;/span&gt;,&lt;span style=&#34;color:#ae81ff&#34;&gt;112&lt;/span&gt;)), cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;COLOR_BGR2GRAY))&lt;span style=&#34;color:#75715e&#34;&gt;# 把图片的size重新设定维（92,112），并将图片转换为灰度图像&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#75715e&#34;&gt;# cv2.imshow(&amp;#39;aaa&amp;#39;,imga)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drawFaces(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;../at/chen.jpg&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;saveFaces(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;../at/chen.jpg&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里面的截取人脸并保存的saveFaces函数，我觉得还不错。网上找到的代码，调用了Image库，我的代码全部都是用cv2搞定的，没有用Image库。画矩形也是，我也都是用cv2自带的东西完成的。
我用以上代码生成的数据，去进行人脸识别，惨不忍睹。&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;http://blog.csdn.net/u012162613/article/details/43523507&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Python-OpenCV人脸检测(代码)&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;http://wangwei007.blog.51cto.com/68019/1104940&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;python os.path模块常用方法详解&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>使用opencv实现人脸识别</title>
        <link>https://blog.huirongis.me/post/face-recognizer/</link>
        <pubDate>Sun, 26 Apr 2015 10:50:00 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/face-recognizer/</guid>
        <description>&lt;p&gt;最近搞了两个星期的opencv，人脸识别方向，感觉没有什么前途，看不到论文在哪里啊。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# !/usr/bin/env python&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# -*- coding:utf-8-*-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; os
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; sys
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; cv2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; numpy &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; np
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;z &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {} &lt;span style=&#34;color:#75715e&#34;&gt;# 存储关于每张图片对应的lable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;for_pre &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; []  &lt;span style=&#34;color:#75715e&#34;&gt;# 存储用来进行测试的图片，规则是每个人10张图，5张用来训练，5张用来测试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;normalize&lt;/span&gt;(X, low, high, dtype&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;对数据进行正常化处理，让其处于最高和最低值之间.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    X &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;asarray(X)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    minX, maxX &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;min(X), np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;max(X)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# normalize to [0...1].&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    X &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; X &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; float(minX)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    X &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; X &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt; float((maxX &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; minX))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# scale to [low...high].&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    X &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; X &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; (high&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;low)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    X &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; X &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; low
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; dtype &lt;span style=&#34;color:#f92672&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;asarray(X)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;asarray(X, dtype&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;dtype)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;read_images&lt;/span&gt;(path, sz&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;从文件夹中读取图像，并且将其大小限制在一定范围之内
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    参数:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        path: 图片的路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        sz: 设定图像的大小以元组的形式，例如(92,112)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    返回值:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        返回一个list的数据[X,y]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            X: 一个numpy的数组，里面存储的是所有的图片的矩阵.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            y:一个list存储的，都是与X中图片对应的lable
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    c &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    X,y &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [], []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; dirname, dirnames, filenames &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;walk(path):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; subdirname &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; dirnames:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            subject_path &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;path&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;join(dirname, subdirname)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; filename &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;listdir(subject_path):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;try&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    im &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;imread(os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;path&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;join(subject_path, filename), cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;IMREAD_GRAYSCALE)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#75715e&#34;&gt;# resize to given size (if given)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (sz &lt;span style=&#34;color:#f92672&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        im &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;resize(im, sz)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; y&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;count(c) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        for_pre&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append({&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;no&amp;#39;&lt;/span&gt;:c,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;src&amp;#39;&lt;/span&gt;:np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;asarray(im, dtype&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;uint8)})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        X&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;asarray(im, dtype&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;uint8))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        y&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(c)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;global&lt;/span&gt; z
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    z[os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;path&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;join(subject_path, filename)] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; c
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;except&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;IOError&lt;/span&gt;, (errno, strerror):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    print &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;I/O error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{0}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;): &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{1}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;format(errno, strerror)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;except&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    print &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Unexpected error:&amp;#34;&lt;/span&gt;, sys&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;exc_info()[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;raise&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            c &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; c&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; [X,y]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;prediction&lt;/span&gt;(model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;图像预测
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    参数:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        model: 就是图片训练的那个model
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    数据集中每个人存储了10张图片，我把其中的5张存储到for_pre，作为训练数据。用已知的lable和预测的lable作比较，得出图片识别正确的概率
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tn &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# 识别正确的图片数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; item &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; for_pre:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        [p_label, p_confidence] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; model&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;predict(cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;resize(item[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;src&amp;#39;&lt;/span&gt;],(&lt;span style=&#34;color:#ae81ff&#34;&gt;92&lt;/span&gt;,&lt;span style=&#34;color:#ae81ff&#34;&gt;112&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; p_label &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; item[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;no&amp;#39;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            tn &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; tn&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;the answer is &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%d&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;,&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; item[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;no&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Predicted label = &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%d&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; (confidence=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%.2f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;)&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; (p_label, p_confidence)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;总共有&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%d&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;次预测，其中正确次数为&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%d&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt;(len(for_pre),tn)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; __name__ &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# This is where we write the images, if an output_dir is given&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# in command line:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    out_dir &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# You&amp;#39;ll need at least a path to your image data, please see&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# the tutorial coming with this source code on how to prepare&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# your image data:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; len(sys&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;argv) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        print &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;USAGE: face_rec.py &amp;lt;/path/to/images&amp;gt; [&amp;lt;/path/to/store/images/at&amp;gt;]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        sys&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;exit()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Now read in the image data. This must be a valid path!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    [X,y] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; read_images(sys&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;argv[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;], (&lt;span style=&#34;color:#ae81ff&#34;&gt;92&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;112&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Convert labels to 32bit integers. This is a workaround for 64bit machines,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# because the labels will truncated else. This will be fixed in code as&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# soon as possible, so Python users don&amp;#39;t need to know about this.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Thanks to Leo Dirac for reporting:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    y &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;asarray(y, dtype&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;int32)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# If a out_dir is given, set it:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; len(sys&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;argv) &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        out_dir &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; sys&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;argv[&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Create the Eigenfaces model. We are going to use the default&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# parameters for this simple example, please read the documentation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# for thresholding:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    model &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;createEigenFaceRecognizer()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Read&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Learn the model. Remember our function returns Python lists,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# so we use np.asarray to turn them into NumPy lists to make&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# the OpenCV wrapper happy:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    model&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;train(np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;asarray(X), np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;asarray(y))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    prediction(model) &lt;span style=&#34;color:#75715e&#34;&gt;# 图片预测&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# You can see the available parameters with getParams():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print model&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;getParams()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Now let&amp;#39;s get some data:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    mean &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; model&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;getMat(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mean&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print out_dir &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/out.xml&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    f &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; open(out_dir &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/out.xml&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;w&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    model&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;save(out_dir &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/out.xml&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    eigenvectors &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; model&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;getMat(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;eigenvectors&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# We&amp;#39;ll save the mean, by first normalizing it:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    mean_norm &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; normalize(mean, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;, dtype&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;np&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;uint8)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    mean_resized &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; mean_norm&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;reshape(X[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;shape)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; out_dir &lt;span style=&#34;color:#f92672&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;imshow(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mean&amp;#34;&lt;/span&gt;, mean_resized)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;imwrite(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%s&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/mean.png&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; (out_dir), mean_resized)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Turn the first (at most) 16 eigenvectors into grayscale&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# images. You could also use cv::normalize here, but sticking&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# to NumPy is much easier for now.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Note: eigenvectors are stored by column:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# for i in xrange(min(len(X), 16)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#     eigenvector_i = eigenvectors[:,i].reshape(X[0].shape)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#     eigenvector_i_norm = normalize(eigenvector_i, 0, 255, dtype=np.uint8)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#     # Show or save the images:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#     if out_dir is None:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#         cv2.imshow(&amp;#34;%s/eigenface_%d&amp;#34; % (out_dir,i), eigenvector_i_norm)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#     else:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#         cv2.imwrite(&amp;#34;%s/eigenface_%d.png&amp;#34; % (out_dir,i), eigenvector_i_norm)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Show the images:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print z
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; out_dir &lt;span style=&#34;color:#f92672&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cv2&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;waitKey(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;代码执行效果如下
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eriuc3wsckj20nr08qn2q.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;人脸识别执行效果&#34;
	
	
&gt;
我在这里输出的是那些预测错误的。&lt;code&gt;总共有200次预测，其中正确次数为186。&lt;/code&gt;这预测率有点低啊，我用的数据都是来自于&lt;a class=&#34;link&#34; href=&#34;http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt; AT&amp;amp;T Facedatabase&lt;/a&gt;。一共40个人，每个人10张图，图片宽高是92*112像素，全部是灰度图像。
至于如何提高图片识别的效率，我也不知道。&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;http://docs.opencv.org/modules/contrib/doc/facerec/facerec_tutorial.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://docs.opencv.org/modules/contrib/doc/facerec/facerec_tutorial.html&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;https://code.google.com/p/pythonxy/source/browse/src/python/OpenCV/DOC/samples/python2/facerec_demo.py?repo=xy-27&amp;amp;r=a2e41c7a3cb6db536b948747872cab71c696b44e&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;python调用opencv实现人脸识别&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>blog2markdown程序打包,csdn爬虫</title>
        <link>https://blog.huirongis.me/post/blog2markdown-csdn-windows/</link>
        <pubDate>Sun, 29 Mar 2015 22:08:22 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/blog2markdown-csdn-windows/</guid>
        <description>&lt;blockquote&gt;
&lt;p&gt;项目地址&lt;a class=&#34;link&#34; href=&#34;https://github.com/Jackroyal/blog2markdown.git&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/Jackroyal/blog2markdown.git&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;用来实现普通blog到markdown的搬家，自动将blog的html转换成HEXO可用的Markdown格式
暂时只做了CSDN&lt;/p&gt;
&lt;h3 id=&#34;update&#34;&gt;UPDATE:
&lt;/h3&gt;&lt;p&gt;2015-03-29 添加了打包成exe的程序,修复cmd下乱码,win和ubuntu完美运行
2015-03-29 连夜修复了在win下乱码的问题,删除了冗余代码
2015-03-28 将某些参数改为从配置文件中读取,加入更多异常判断
2014-12-15 优化标签解析功能,添加了标题,tag和category
2014-12-13 实现解析功能,基本完成解析功能
2014-12-10 实现CSDN的抓取，正在实现parse解析过程&lt;/p&gt;
&lt;h3 id=&#34;bug&#34;&gt;BUG
&lt;/h3&gt;&lt;p&gt;如果代码中有# 和*会被转义成&lt;code&gt;\#&lt;/code&gt;和&lt;code&gt;\*&lt;/code&gt;
对table的支持不好&lt;/p&gt;
&lt;h3 id=&#34;依赖库&#34;&gt;依赖库
&lt;/h3&gt;&lt;p&gt;爬虫使用了&lt;code&gt;beautifulsoup  4.3.2&lt;/code&gt;
&lt;a class=&#34;link&#34; href=&#34;http://www.crummy.com/software/BeautifulSoup/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;点我点我&lt;/a&gt;
你必须安装这个才可以正常使用
PS:我打包了exe&lt;a class=&#34;link&#34; href=&#34;http://pan.baidu.com/s/1dDERlOP&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;点此下载&lt;/a&gt;,可以什么不装,改完配置文件,直接运行&lt;/p&gt;
&lt;h1 id=&#34;使用&#34;&gt;使用:
&lt;/h1&gt;&lt;h1 id=&#34;-首先编辑配置文件spiderconf&#34;&gt;# 首先,编辑配置文件&lt;code&gt;spider.conf&lt;/code&gt;
&lt;/h1&gt;&lt;p&gt;格式如下:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[blog]
# 此处url不需要单引号或者双引号,不然类型识别错误,网址最后不要/
url=http://blog.csdn.net/jackroyal
[setting]
wait_time=5
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这里的&lt;code&gt;url&lt;/code&gt;地址注意不要加引号,下面的&lt;code&gt;wait_time&lt;/code&gt;是指两次抓取的间隔时间,这是为了安全起见,如果高频访问,可能会被封,我设置的&lt;code&gt;5&lt;/code&gt;秒,你可以根据自己需要去设置&lt;/p&gt;
&lt;h2 id=&#34;打包&#34;&gt;打包
&lt;/h2&gt;&lt;p&gt;我打包了一个&lt;a class=&#34;link&#34; href=&#34;http://pan.baidu.com/s/1dDERlOP&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;exe程序&lt;/a&gt;,放在github项目的dist目录下,在windows系统中,&lt;code&gt;直接下载&lt;/code&gt;,&lt;code&gt;运行&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;PS:由于pyInstaller的问题,导致无法在中文路径下正常运行&lt;/p&gt;
&lt;p&gt;比如你放在C:/users/张三/spider.exe
这样是无法正常运行的
所以应该放在全英文的目录下
C:/software/spider.exe
运行结果如图
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eqmymt6bhrj20ip0cata6.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;spider运行截图&#34;
	
	
&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eqmyur9uihj20mb0gqmzf.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;运行结果截图&#34;
	
	
&gt;&lt;/p&gt;
&lt;h1 id=&#34;源码执行&#34;&gt;源码执行
&lt;/h1&gt;&lt;p&gt;如果你对我的exe不放心,可以自己执行python源码&lt;/p&gt;
&lt;h2 id=&#34;--执行&#34;&gt;#  执行
&lt;/h2&gt;&lt;p&gt;在linux下,首先要给予执行权限&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;chmod a+x spider.py ParseBlog.py
python spider.py
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后就可以了,输出文件在output文件夹&lt;/p&gt;
&lt;p&gt;在win下,经过修复也可以正常运行了,在idle(在win中你安装了python2.7的话就会有这个编辑器)中是可以完全正常的显示中文~~~~,在系统自带的cmd里中文显示会有问题,因为cmd中的编码默认是GBK,我程序基本都是utf-8,如果要在cmd显示正常,显示的代码都要加个str.encode(&amp;lsquo;utf-8&amp;rsquo;)才行.
不过抓取是没有问题的,此处就不纠结了哈,能用就好~~~~&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 在win下,没有权限的问题,直接执行就好了
python spider.py
&lt;/code&gt;&lt;/pre&gt;</description>
        </item>
        <item>
        <title>hexo发布失败</title>
        <link>https://blog.huirongis.me/post/hexo-deploy-error/</link>
        <pubDate>Sun, 29 Mar 2015 18:09:28 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/hexo-deploy-error/</guid>
        <description>&lt;p&gt;可能受到上次ddos的问题,这两天国内访问github,总是感觉不顺畅.&lt;/p&gt;
&lt;p&gt;今天下午写了一篇博客,可是却发布不成功,一直卡在这一步:
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eqmrrf20j1j20g006676y.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;hexo发布的时候卡住&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;然后我继续等,得到如下错误:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;hexo Failed to receive SOCKS4 connect request ack.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我执行了&lt;code&gt;hexo clean&lt;/code&gt;命令,手动删掉了&lt;code&gt;.deploy&lt;/code&gt;文件夹,可是还是不行
最后报错
无法连接&lt;code&gt;https://github.com/Jackroyal/Jackroyal.github.io.git&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(ps:此处已经无法重现了,抽风啊)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;最后我换了下这条链接
我修改了博客目录下的&lt;code&gt;_config.yml&lt;/code&gt;,改了deploy参数
原参数设置&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;deploy:
  type: github
  repo: https://github.com/Jackroyal/Jackroyal.github.io.git
  branch: master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;修改以后:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;deploy:
  type: github
  repo: git@github.com:Jackroyal/Jackroyal.github.io.git
  branch: master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后就deploy成功了.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;PPPS:千万注意,上面的参数设置repo:后面有一个空格,没有空格会报错&lt;/em&gt;&lt;/p&gt;
&lt;h1 id=&#34;update&#34;&gt;update:
&lt;/h1&gt;&lt;p&gt;repo的两种方式分别为ssh和https
昨天没搞清楚,专门去查了一下,ssh和https两种提交的区别
官方推荐用https,因为这回要求你输入用户名和密码,这样更安全
用ssh的话,只要你的ssh-key(可以设置一道类似密码的东西,和你的key一起加密,这样使用的时候会要求输入这段密码)对,那么就都可以提交,没有了更多的验证过程(可以设置一个para加密,提交会要求输入这段para)&lt;/p&gt;
&lt;p&gt;2015-05-06
最近又发现，使用ssh提交的话，github不会计算到你的conribute里面去，也就是你今天提交了，但是github的contribute不会变化，所以还是改成https吧，不然怎么装B呢？&lt;/p&gt;
&lt;h3 id=&#34;友情链接&#34;&gt;友情链接
&lt;/h3&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;http://rolight.cn/blog/?p=34&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ubuntu  shadowsocks 全局 代理&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>python学习笔记--python和beautifulsoup遇到的编码问题</title>
        <link>https://blog.huirongis.me/post/python-blog-spider/</link>
        <pubDate>Sun, 29 Mar 2015 14:43:45 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/python-blog-spider/</guid>
        <description>&lt;p&gt;在刚开始使用github pages的时候,我用python写了一个爬虫,计划是从csdn和cnblogs等博客网站上,把自己之前写的博客爬取下来,然后再转换成hexo用的markdown格式,样就可以直接添加到我的github pages.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;项目主页: &lt;a class=&#34;link&#34; href=&#34;https://github.com/Jackroyal/blog2markdown&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/Jackroyal/blog2markdown&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;最近刚好在学习python,刚好就把它给优化了一下,顺便做了个跨平台(哈哈,win和ubuntu都可以跑哈),昨天遇到很蛋疼的问题,一它给了我很多思路帮助我定位问题,.直搞到凌晨两点才弄好.
非常非常感谢&lt;a class=&#34;link&#34; href=&#34;http://www.crifan.com/summary_python_2_x_common_string_encode_decode_error_reason_and_solution/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;【总结】Python 2.x中常见字符编码和解码方面的错误及其解决办法&lt;/a&gt;
作者做了一个很好的总结,帮助我们定位问题.&lt;/p&gt;
&lt;h1 id=&#34;1-编码类型&#34;&gt;1 编码类型
&lt;/h1&gt;&lt;p&gt;首先确定好你的编码类型,比如一般推荐用utf-8.当确定编码类型后,就要保持统一,不要又弄些GBK的编码在里面.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1.1  编辑器编码
&lt;ul&gt;
&lt;li&gt;我们有时候会犯一个错误,我在py文件的头部声明当前文件是按照utf-8来编码.但是文件实际保存的编却不是utf-8,这样也会导致乱码.建议使用可以查看当前文件编码的编辑器,比如sublime text或者notepad++ 或者pycharm.&lt;!-- raw HTML omitted --&gt;在sublime下如图所示&lt;!-- raw HTML omitted --&gt;&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eqmn535qb7j208u028t8k.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;sublime显示当前文件编码&#34;
	
	
&gt;&lt;/li&gt;
&lt;li&gt;文件编码声明,我们要在py文件的头部添加一行&lt;code&gt;# -*- coding: utf-8 -*-&lt;/code&gt;,表明我接下来要使用utf-8编码&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.2  python解释器
&lt;ul&gt;
&lt;li&gt;如果是Python的IDLE，如果你没修改defaultencoding，那么就使用默认的字符编码可以通过sys.getdefaultencoding()而获得，比如此处获得是：ascii&lt;!-- raw HTML omitted --&gt;&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eqmnd8fgrjj20b205kabi.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;win中python解释器编码&#34;
	
	
&gt;&lt;!-- raw HTML omitted --&gt;&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eqmnfd29u7j20k5047wfv.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;ubuntu终端解释器的编码&#34;
	
	
&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.3  执行python代码
&lt;ul&gt;
&lt;li&gt;其中，很常见的几种动作是：
&lt;ul&gt;
&lt;li&gt;打印print对应的所获得的字符
&lt;ul&gt;
&lt;li&gt;对于字符串打印,Python的逻辑:
&lt;ul&gt;
&lt;li&gt;如果是Unicode字符串,则可以,自动地,编码为对应的终端所用编码,然后正确的显示出来&lt;/li&gt;
&lt;li&gt;比如unicode的字符串,输出到windows的默认编码为GBK的cmd中,则Python可以自动将Unicode编码为GBK,然后输出到cmd中&lt;/li&gt;
&lt;li&gt;个别特殊情况,也会出错:
&lt;ul&gt;
&lt;li&gt;当此unicode字符串中包含某特殊字符,而目标终端的编码集合中,没有此字符,则很明显也是无法实现将Unicode编码为对应的特定编码的字符串,无法正确显示的&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;如果是某种编码类型的str,则需要该str的编码类型,和目标终端编码匹配
&lt;ul&gt;
&lt;li&gt;比如GBK的字符串,输出到windows的默认编码为GBK的cmd,则是可以正常输出的&lt;/li&gt;
&lt;li&gt;此处后来经过代码测试，就发现一个有趣或者说诡异的问题，虽然我们python文件声明的UTF-8编码，但是实际上实际上是用GBK编码，而此时，文件中的字符串，很明显是用GBK存储的，所以，将此GBK字符，输出到GBK的cmd中，是可以正常输出的。即，此处字符串的类型，很明显只和文件所用的实际编码有关，而和文件所声明的代码无关。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;如果是UTF-8的字符串,输出到windows的默认编码为GBK的cmd,就会出错
&lt;ul&gt;
&lt;li&gt;对相应的字符，进行编码（为某种特定类型的字符str），或解码（为对应的unicode类型的字符）&lt;/li&gt;
&lt;li&gt;比如将当前的某种编码的字符串，解码为Unicode字符串
&lt;ul&gt;
&lt;li&gt;很明显，也是要保证，你字符串本身的编码和所指定的编码，两者之间要一致的&lt;/li&gt;
&lt;li&gt;比如：decodedUnicode = someUtf8Str.decode(&amp;ldquo;UTF-8&amp;rdquo;)&lt;/li&gt;
&lt;li&gt;而如果用这样的：decodedUnicode = someGbkStr.decode(&amp;ldquo;UTF-8&amp;rdquo;)，那就会出现错误&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;2-常用方法&#34;&gt;2 常用方法
&lt;/h1&gt;&lt;h3 id=&#34;21-encode和decode&#34;&gt;2.1 encode和decode
&lt;/h3&gt;&lt;p&gt;encode()  unicode编码-&amp;gt;其他编码&lt;/p&gt;
&lt;p&gt;decode()  其他编码-&amp;gt;unicode编码&lt;/p&gt;
&lt;p&gt;使用这两个方法的前提是,你要知道当前是什么编码.然后用对应的编码去进行解码
比如对于s字符串可以用&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;s.encode(&amp;#39;utf-8&amp;#39;) # 将s由unicode转码成utf-8
s.decode(&amp;#39;GBK&amp;#39;) # s是GBK编码,将s转换成unicode
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;22-isinstance&#34;&gt;2.2 isinstance()
&lt;/h3&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;isinstance(s , unicode) # 检测s是否是unicode编码

isinstance(s , str) # 检测s是否是str格式
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;3-beautifulsoup编码问题&#34;&gt;3 beautifulsoup编码问题
&lt;/h1&gt;&lt;h3 id=&#34;beautiful-soup-会按顺序尝试不同的编码将你的文档转换为unicode&#34;&gt;Beautiful Soup 会按顺序尝试不同的编码将你的文档转换为Unicode：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;可以通过from_encoding参数传递编码类型给soup的构造器&lt;/li&gt;
&lt;li&gt;通过文档本身找到编码类型：例如XML的声明或者HTML文档http-equiv的META标签。&lt;/li&gt;
&lt;li&gt;如果Beautiful Soup在文档中发现编码类型，它试着使用找到的类型转换文档。 +&lt;/li&gt;
&lt;li&gt;但是，如果你明显的指定一个编码类型，&lt;/li&gt;
&lt;li&gt;并且成功使用了编码：这时它会忽略任何它在文档中发现的编码类型。&lt;/li&gt;
&lt;li&gt;通过嗅探文件开头的一下数据，判断编码。如果编码类型可以被检测到，&lt;/li&gt;
&lt;li&gt;它将是这些中的一个：UTF-*编码，EBCDIC或者ASCII。&lt;/li&gt;
&lt;li&gt;通过chardet库,嗅探编码，如果你安装了这个库。&lt;/li&gt;
&lt;li&gt;UTF-8&lt;/li&gt;
&lt;li&gt;Windows-1252&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一般来说,bs的自动识别,是不会有问题的,但是在我这里除了问题,具体原因不太清楚
我的网页上已经声明了是&lt;code&gt;utf-8&lt;/code&gt;编码
原来代码如下&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 这是原来的编码,在win下面乱码
self.soup = bs((response.read()))
print self.soup.originalEncoding   # 此处结果竟然返回Windows-1252
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;修改后代码如下&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# win下乱码的关键在这里,beautifulsoup解析的编码不对,我们这里直接指定编码
self.soup = bs((response.read()), from_encoding=&amp;#39;utf-8&amp;#39;)
print self.soup.originalEncoding   # 修正后代码正确返回&amp;#39;utf-8&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;看来beautifulsoup的自动识别编码不能全部依赖.
好不容易才定位到这里的问题,折腾了一天啊
这里用了一个方法来检测编码.就是soup.iriginalEncoding属性&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;print self.soup.originalEncoding   # 修正后代码正确返回&amp;#39;utf-8&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这篇博客好水,毕竟不是很懂,所以说不出来&lt;/p&gt;
&lt;p&gt;update:2015-03-30&lt;/p&gt;
&lt;h1 id=&#34;4-新技能get&#34;&gt;4 新技能get
&lt;/h1&gt;&lt;p&gt;之前都没好好理解原作者的博客,觉得没办法一个程序在win和ubuntu中不更改正常运行,现在发现,如果把编码改为unicode格式输出,那么系统会自动转换,这样就不存在utf-8编码在windows下cmd乱码了.&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;http://www.crifan.com/summary_python_2_x_common_string_encode_decode_error_reason_and_solution/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;【总结】Python 2.x中常见字符编码和解码方面的错误及其解决办法&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;http://www.crifan.com/resolved_python_garbled_chinese_characters_gb2312_gbk_gb18030-related_issues/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;【已解决】python中文字符乱码（GB2312，GBK，GB18030相关的问题）&lt;/a&gt;
参考资料太多,贴不过来啊,主要都是cifan的博客,里面资料很多,一步一步都有过程,非常好用,谢谢cifan作者&lt;/p&gt;
</description>
        </item>
        <item>
        <title>python学习笔记--一个简单聊天室的实现</title>
        <link>https://blog.huirongis.me/post/python-im/</link>
        <pubDate>Thu, 26 Mar 2015 21:33:35 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/python-im/</guid>
        <description>&lt;p&gt;最近项目真多,一个接一个的失之交臂,全部都错过了.最近状态有些不好,容易胡思乱想.
这是来自书上的一个python聊天程序,我照着敲了一遍,然后给扩展了一下,加了多个房间和创建选择房间的功能,写了好久好久,感觉都拖了一个星期了.
下一步是做一个gui,恩,那将是我的第一个gui程序.&lt;/p&gt;
&lt;h1 id=&#34;先贴一下代码-server5py&#34;&gt;先贴一下代码 server5.py
&lt;/h1&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# !/usr/bin/env python
# -*- coding:utf-8-*-
__author__ = &amp;#39;chen&amp;#39;

from asyncore import  dispatcher
from  asynchat import async_chat
import socket,asyncore

PORT = 5005  # 设定程序的端口号
NAME = &amp;#39;testchat&amp;#39;  # 给服务器一个名称

class EndSession(Exception):pass

class CommandHandler:
    &amp;#34;&amp;#34;&amp;#34;
    类似标准库中cmd.Cmd的简单命令处理程序
    &amp;#34;&amp;#34;&amp;#34;
    # 如果输入的命令,那么就返回unknown命令
    def unknown(self, session, cmd):
        session.push(&amp;#39;Unknown command: %s \r\n&amp;#39; % cmd)
    
    def handle(self, session, line):
        if not line.strip():
            return
        parts = line.split(&amp;#39; &amp;#39;, 1)
        cmd = parts[0]
        try:
            line = parts[1].strip()
        except IndexError:line = &amp;#39;&amp;#39;
        meth = getattr(self, &amp;#39;do_&amp;#39; + cmd, None)
        try:
            meth(session, line)
        except TypeError:
            self.unknown(session, cmd)
# 这个类是聊天房间的类,继承上面的类是为了继承执行命令的功能
class ChatRoom(CommandHandler):
    def __init__(self, name, server):
        self.server = server
        self.name = name
        self.sessions = []

    def add(self, session):
        self.broadcast(session.name + &amp;#39; has entered the room %s\r\n&amp;#39; % self.name)
        session.push(&amp;#39;you can type &amp;#34;h&amp;#34; for help\r\n&amp;#39;)
        ## 因为后面要将用户挪动房间,所以必须保存每个用户的session,这样才能挪动和删除
        self.server.users[session.name] = session
        self.sessions.append(session)

    def remove(self, session):
        try:
            self.sessions.remove(session)
        except: pass # 如果此处的sessions为空或者已经不存在,会出错,此处不上报

    def broadcast(self, line):
        # 广播,只广播到当前房间
        for session in self.sessions:
            session.push(line)

    def do_say(self, session, line):
        # 说话
        self.broadcast(session.name + &amp;#34;:&amp;#34; + line + &amp;#39;\r\n&amp;#39;)

    def do_login(self, session, line):
        # login,其实是实现改名字的功能,懒得去改函数名了
        name = line.strip()
        if not name:
            session.push(&amp;#39;please enter a name\r\n&amp;#39;)
        elif name in self.server.users.keys():
            session.push(&amp;#39;The name %s is taken\r\n&amp;#39; % name)
            session.push(&amp;#39;please try again\r\n&amp;#39;)
        else:
            session.server.users[name] = session.server.users.pop(session.name)
            session.name = name
            session.enter(self)
            self.do_list(session, &amp;#39;&amp;#39;)
            session.push(&amp;#39;type &amp;#34;select name&amp;#34; to choose one room\r\n&amp;#39;)
    # 查看当前房间有哪些人
    def do_look(self, session, line):
        session.push(&amp;#39;the following are in this room:\r\n&amp;#39;)
        for other in self.sessions:
            session.push(other.name + &amp;#34;\r\n&amp;#34;)
    # 查看当前在线的用户,所有房间的用户
    def do_who(self, session, line):
        session.push(&amp;#39;the following are logged in:\r\n&amp;#39;)
        for name in self.server.users:
            session.push(name + &amp;#39;\r\n&amp;#39;)
    # 查看当前所有的房间
    def do_list(self, session, line):
        session.push(&amp;#39;the room list is below\r\n&amp;#39;)
        session.push(&amp;#39;   &amp;#39;.join(self.server.rooms) + &amp;#39;\r\n&amp;#39;)
    # 选择房间
    def do_select(self, session, line):
        name = line.strip()
        if not name:
            session.push(&amp;#39;please enter a room name\r\n&amp;#39;)
        elif name in self.server.rooms.keys():
            session.enter(self.server.rooms[name])
            self.broadcast(&amp;#39; %s ,welcome to join %s\r\n&amp;#39;% (session.name, name))
    # 输出帮助
    def do_h(self, session, line):
        session.push(&amp;#39;you can use this commands:\r\n1,who to see who is on this server(online and offline)\r\n2,&amp;#39;
        &amp;#39;list to see how many room are avaliable\r\n3,look to see who are in this room\r\n4,login to login online and &amp;#39;
        &amp;#39;change a name\r\n5,create to create a new room&amp;#39;)
    # 创建新房间
    def do_create(self, session, line):
        name = line.strip()
        if not name:
            session.push(&amp;#39;please enter a name\r\n&amp;#39;)
        elif name in self.server.rooms.keys():
            session.push(&amp;#39;The room name %s is taken\r\n&amp;#39; % name)
            session.push(&amp;#39;please try again\r\n&amp;#39;)
        else:
            ChatRoom(name, self.server)
            session.server.rooms[name] = ChatRoom(name, self.server)
            session.push(&amp;#34;the room %s create successful\r\n&amp;#34; % name)
            session.enter(session.server.rooms[name])
# 每个用户回话,这个是重点类
class ChatSession(async_chat):
    def __init__(self, server, sock):
        async_chat.__init__(self, sock)
        self.server = server
        self.set_terminator(&amp;#39;\r\n&amp;#39;)
        self.data = []
        self.name = &amp;#39;visitor&amp;#39; + str(len(server.users))# 初始化用户名,用visitor1之类来表示
        self.room = self.server.main_room
        self.enter(self.server.main_room)

    def enter(self, room):
        try:
            cur = self.room
        except AttributeError: pass
        else: cur.remove(self)
        self.room = room
        room.add(self)
    # 当用户有输入的时候
    def collect_incoming_data(self, data):
        self.data.append(data)
    # 当用户输入终止符的时候
    def found_terminator(self):
        line = &amp;#39;&amp;#39;.join(self.data)
        self.data = []
        try:
            self.room.handle(self, line)
        except EndSession:
            self.handle_close()
    # 关闭用户回话
    def handle_close(self):
        async_chat.handle_close(self)
        # self.enter()

# 服务器类,这个也是重点类
class ChatServer(dispatcher):
    def __init__(self, port, name):
        dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        # 端口复用
        self.set_reuse_addr()
        self.bind((&amp;#39;&amp;#39;, port))
        self.listen(5)
        self.sessions = {}
        self.name = name
        self.users = {}
        self.rooms = {}
        # 新建一个房间hall,因为每个初始登陆的用户没有房间,但是操作是依赖与ChatRoom类的,所以给一个初始默认的房间
        self.main_room = ChatRoom(&amp;#39;hall&amp;#39;, self)
        self.rooms[self.main_room.name] = self.main_room

    def handle_accept(self):
        conn,addr = self.accept()
        ChatSession(self, conn)
        print &amp;#39;connection attempt from &amp;#39;, addr[0]

if __name__ == &amp;#34;__main__&amp;#34;:
    print &amp;#39;server start&amp;#39;
    s = ChatServer(PORT, NAME)
    try:
        asyncore.loop()
    except KeyboardInterrupt: print
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;效果如图所示
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eqjhaekoz0j20ii0h5q62.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;运行效果&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>python学习笔记--socket编程端口复用</title>
        <link>https://blog.huirongis.me/post/python-socket-port-reuse/</link>
        <pubDate>Wed, 18 Mar 2015 08:47:02 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/python-socket-port-reuse/</guid>
        <description>&lt;p&gt;最近在学习socket编程,遇到一个问题:
我先bind一个端口后,如果通过ctr+c关闭进程.接下来执行程序的时候,就会提示&lt;code&gt;socket.error: Address already in use&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;照例google一番,找到&lt;a class=&#34;link&#34; href=&#34;http://blog.csdn.net/xl_xunzhao/article/details/3130037&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这个&lt;/a&gt;.博主说的情况和我的一样.
我还在stackoverflow上找到&lt;a class=&#34;link&#34; href=&#34;http://stackoverflow.com/questions/4465959/python-errno-98-address-already-in-use&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这个&lt;/a&gt;.
修改后代码如下:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 下面这行是关健
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    server_socket.bind((&amp;#39;&amp;#39;, PORT))
    server_socket.listen(5)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后就搞定了.&lt;/p&gt;
&lt;p&gt;下面的代码是socket编程敲得两个小例子,基于socket的聊天小程序都是别人的东西,只是练习一下,源地址在本文最后.&lt;/p&gt;
&lt;h2 id=&#34;多线程版本服务器端程序server2py&#34;&gt;多线程版本服务器端程序server2.py
&lt;/h2&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# !/usr/bin/env python
# -*- coding:utf-8-*-
__author__ = &amp;#39;chen&amp;#39;


import socket,sys
from thread import *

HOST = &amp;#39;&amp;#39;
PORT = 8888

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print &amp;#39;socket created&amp;#39;

try:
    s.bind((HOST, PORT))
except socket.error, msg:
    print &amp;#39;bind failed.Error code: |||%S Message: %s&amp;#39; %(str(msg[0]), msg[1])
    sys.exit()


print &amp;#39;socket bind complete&amp;#39;

s.listen(10)
print &amp;#39;socket now listening&amp;#39;

def clientthread(conn):
    conn.send(&amp;#39;welcome to the server.Type something and hit enter\n&amp;#39;)

    while True:
        data = conn.recv(1024)
        reply = &amp;#39;ok...&amp;#39; + data
        if not data:
            break
        conn.sendall(reply)
    conn.close()

while 1:
    conn, addr = s.accept()
    print &amp;#39;connected with %s : %s&amp;#39; %(addr[0],str(addr[1]))

    start_new_thread(clientthread, (conn,))

s.close()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;直接telnet连接socket,就可以调试&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;telnet localhost 8888
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;改良版带广播的聊天室程序server3py&#34;&gt;改良版,带广播的聊天室程序server3.py
&lt;/h2&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# !/usr/bin/env python
# -*- coding:utf-8-*-
__author__ = &amp;#39;chen&amp;#39;

import socket, select

def broadcast_data(sock, message):
    for socket in CONNECTION_LIST:
        if socket != server_socket != sock:
            try:
                socket.send(message)
            except msg:
                socket.close()
                CONNECTION_LIST.remove(socket)

if __name__ == &amp;#34;__main__&amp;#34;:
    CONNECTION_LIST = []
    RECV_BUFFER = 4096
    PORT = 5000
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind((&amp;#39;&amp;#39;, PORT))
    server_socket.listen(5)

    CONNECTION_LIST.append(server_socket)
    print &amp;#34;chat server started on port %s&amp;#34; % str(PORT)

    while 1:
        read_sockets, write_sockets,error_sockets = select.select(CONNECTION_LIST, [], [])

        for sock in read_sockets:
            if sock == server_socket:
                sockfd,addr = server_socket.accept()
                CONNECTION_LIST.append(sockfd)
                print &amp;#34;client (%s, %s) connected&amp;#34; % addr

                broadcast_data(sockfd, &amp;#34;[%s:%s] entered room\n&amp;#34; % addr)

            else:
                try:
                    data = sock.recv(RECV_BUFFER)
                    if data:
                        print  &amp;#34;[%s:%s]&amp;#34; % (str(sock.getpeername()), data)
                        broadcast_data(sock, &amp;#34;[%s:%s]&amp;#34; % (str(sock.getpeername()), data))
                except msg:
                    print msg
                    broadcast_data(sock, &amp;#34;client (%s, %s) is offline &amp;#34;% addr)
                    print &amp;#34;client (%s,%s) is offline &amp;#34; % addr
                    sock.close()
                    CONNECTION_LIST.remove(sock)
                    continue
    server_socket.close()
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;客户端程序client3py&#34;&gt;客户端程序client3.py
&lt;/h2&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# !/usr/bin/env python
# -*- coding:utf-8-*-
__author__ = &amp;#39;chen&amp;#39;

import socket,select,string,sys

def prompt():
    sys.stdout.write(&amp;#39;[you]&amp;#39;)
    sys.stdout.flush()

if __name__ == &amp;#34;__main__&amp;#34;:
    if(len(sys.argv)&amp;lt;3):
        print &amp;#39;usage: python client3.py hostname port&amp;#39;
        sys.exit()

    host = sys.argv[1]
    port = int(sys.argv[2])

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(2)

    try:
        s.connect((host, port))
    except:
        print &amp;#39;unable to connect&amp;#39;
        sys.exit()

    print &amp;#39;connected to remote host. start sending messages&amp;#39;
    prompt()

    while 1:
        rlist = [sys.stdin, s]

        read_list, write_list, error_list = select.select(rlist, [], [])

        for sock in read_list:
            if sock == s:
                data = sock.recv(4096)
                if not data:
                    print &amp;#39;\nDisconnected from chat server&amp;#39;
                    sys.exit()
                else:
                    sys.stdout.write(data)
                    prompt()

            else:
                msg = sys.stdin.readline()
                s.send(msg)
                prompt()
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;http://www.cnblogs.com/hazir/p/python_socket_programming.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Python Socket 网络编程&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;http://www.cnblogs.com/hazir/p/python_chat_room.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Python Socket 编程——聊天室示例程序&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>shadowsocks的安装和配置--在ubuntu和ubuntu中</title>
        <link>https://blog.huirongis.me/post/use-ss/</link>
        <pubDate>Mon, 09 Mar 2015 22:26:21 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/use-ss/</guid>
        <description>&lt;p&gt;最近我的vpn一直在抽风，几乎没法正常使用，而且我的chrome也是各种花屏，我快疯了，没办法，只能改用shadowsocks了。
搭建过程分为两部分:服务端和客户端(这里是主要是ubuntu的客户端)。&lt;/p&gt;
&lt;h1 id=&#34;1-系统环境&#34;&gt;1 系统环境
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;服务器&lt;/strong&gt;:DigitalOcean上的Ubuntu 14.04 LTS
&lt;strong&gt;客户端&lt;/strong&gt;:Ubuntu 14.04 LTS&lt;/p&gt;
&lt;h1 id=&#34;2-服务器端安装和配置&#34;&gt;2 服务器端安装和配置
&lt;/h1&gt;&lt;p&gt;这里主要是参考github的&lt;a class=&#34;link&#34; href=&#34;https://github.com/shadowsocks/shadowsocks/wiki/Shadowsocks-%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;官方说明&lt;/a&gt;
通过ssh登陆的服务器上去,这里不在赘述如何登陆.
以下主要针对linux服务器,windows服务器查看&lt;a class=&#34;link&#34; href=&#34;https://github.com/shadowsocks/shadowsocks/wiki/Install-Shadowsocks-Server-on-Windows&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这里&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;安装&#34;&gt;安装
&lt;/h2&gt;&lt;p&gt;Linux不同的发行版本执行的命令如下&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Debian / Ubuntu:

apt-get install python-pip
pip install shadowsocks

CentOS:

yum install python-setuptools &amp;amp;&amp;amp; easy_install pip
pip install shadowsocks
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;配置&#34;&gt;配置
&lt;/h2&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo vi /etc/shadowsocks.json
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;配置文件的内容大致如下:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;{
    &amp;#34;server&amp;#34;:&amp;#34;你的服务器的ip&amp;#34;,
    &amp;#34;server_port&amp;#34;:8388,
    &amp;#34;local_address&amp;#34;: &amp;#34;127.0.0.1&amp;#34;,
    &amp;#34;local_port&amp;#34;:1080,
    &amp;#34;password&amp;#34;:&amp;#34;你设置的密码&amp;#34;,
    &amp;#34;timeout&amp;#34;:300,
    &amp;#34;method&amp;#34;:&amp;#34;aes-256-cfb&amp;#34;,
    &amp;#34;fast_open&amp;#34;: false
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;参数名称       解释&lt;/strong&gt;
server         安装shadowsocks服务器ip
server_port    服务器端口号
local_address  本地服务器默认是127.0.0.1
local_port     本地监听的端口号
password       密码
timeout        超时时间,单位是秒
method         加密方法默认是: &amp;ldquo;aes-256-cfb&amp;quot;可以用其他加密方法
fast_open      是否使用TCP_FASTOPEN,默认为不使用
workers        number of workers, available on Unix/Linux&lt;/p&gt;
&lt;h2 id=&#34;运行&#34;&gt;运行
&lt;/h2&gt;&lt;p&gt;前台运行的命令
&lt;code&gt;ssserver -c /etc/shadowsocks.json&lt;/code&gt;
后台运行
&lt;code&gt;ssserver -c /etc/shadowsocks.json -d start&lt;/code&gt;
&lt;code&gt;ssserver -c /etc/shadowsocks.json -d stop&lt;/code&gt;
ps:我上述两条命令都会出错,这两条命令来自官方的github,我用的是下面的
&lt;code&gt;nohup ssserver -c /etc/shadowsocks.json &amp;gt; aa.log&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;开机自启&#34;&gt;开机自启
&lt;/h2&gt;&lt;p&gt;我们把它写入/etc/rc.local中就可以完成开机自启动了.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo vi /etc/rc.local  # 打开rc.local文件
# 然后在exit前面加入下面这一行
# nohup /usr/local/bin/ssserver -c /etc/shadowsocks.json &amp;gt; aa.log
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ps:这里我之前犯了一个错误,没有写&lt;code&gt;ssserver&lt;/code&gt;的绝对路径,导致开机无法自启动,但是手动执行的话,又是可以执行的&lt;/p&gt;
&lt;h1 id=&#34;3-客户端的安装和配置&#34;&gt;3 客户端的安装和配置
&lt;/h1&gt;&lt;p&gt;客户端按理说和服务器端类似,安装shadowsocks,但是我的就是这个出了问题.&lt;/p&gt;
&lt;h2 id=&#34;1-安装相关软件&#34;&gt;1) 安装相关软件
&lt;/h2&gt;&lt;p&gt;shadowsocks有各种客户端版本,各个系统都有.在ubuntu下带图形化界面的有shadowsocks-qt5,还可以直接用命令行.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图形化:&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo add-apt-repository ppa:hzwhuang/ss-qt5
sudo apt-get update
sudo apt-get install shadowsocks-qt5
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;*PS:*我的电脑安装这个以后,会自动卸载我的chrome
*PPS:*我刚才又试了一次,我在安装了命令行模式的shadowsocks以后,现在不会卸载我的chrome,总算正常了&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;The following extra packages will be installed:
  libbotan-1.10-0 libqrencode3 libqtshadowsocks libzbar0
The following packages will be REMOVED:
  libbotan-1.10-0:i386 libqtshadowsocks:i386 libzbar0:i386
The following NEW packages will be installed:
  libbotan-1.10-0 libqrencode3 libqtshadowsocks libzbar0 shadowsocks-qt5
0 upgraded, 5 newly installed, 3 to remove and 19 not upgraded.
Need to get 1,280 kB of archives.
After this operation, 662 kB of additional disk space will be used.
Do you want to continue? [Y/n] 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;命令行模式:&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo apt-get install python-pip python-dev build-essential 
sudo pip install  pip
sudo apt-get install python-m2crypto
sudo pip install shadowsocks
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我因为之前在环境中就安装过pip,所以我只需要执行倒数第三个和第四个命令.
但是我的倒数第四个命令&lt;code&gt;pip install shadowsocks&lt;/code&gt;一直报错:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Exception: Traceback (most recent call last):
File &amp;#34;/usr/lib/python2.7/dist-packages/pip/basecommand.py&amp;#34;, line 122, in main
  status = self.run(options, args)
File &amp;#34;/usr/lib/python2.7/dist-packages/pip/commands/install.py&amp;#34;, line 278, in run
  requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle) 
File &amp;#34;/usr/lib/python2.7/dist-packages/pip/req.py&amp;#34;, line 1177, in prepare_files 
  url = finder.find_requirement(req_to_install, upgrade=self.upgrade) 
File &amp;#34;/usr/lib/python2.7/dist-packages/pip/index.py&amp;#34;, line 256, in find_requirement
  page_versions.extend(self._package_versions(page.links, req.name.lower())) 
File &amp;#34;/usr/lib/python2.7/dist-packages/pip/index.py&amp;#34;, line 432, in _package_versions 
  for link in self._sort_links(links): 
File &amp;#34;/usr/lib/python2.7/dist-packages/pip/index.py&amp;#34;, line 422, in _sort_links 
  for link in links: 
File &amp;#34;/usr/lib/python2.7/dist-packages/pip/index.py&amp;#34;, line 769, in links 
  for anchor in self.parsed.findall(&amp;#34;.//a&amp;#34;):
AttributeError: &amp;#39;Document&amp;#39; object has no attribute &amp;#39;findall&amp;#39;

Storing debug log for failure in /root/.pip/pip.log
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;网上搜索一番,在&lt;a class=&#34;link&#34; href=&#34;https://github.com/pypa/pip/issues/1742&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这里&lt;/a&gt;找到答案.
解决方法很简单,执行&lt;code&gt;easy_install pip&lt;/code&gt;,就ok(貌似是把pip重新安装了一次).&lt;/p&gt;
&lt;h2 id=&#34;2-客户端运行&#34;&gt;2) 客户端运行
&lt;/h2&gt;&lt;p&gt;shadowsocks图形化的比较简单,这里不表.
命令行模式,启动如下:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sslocal -s 服务器ip -p 8388 -k 密码
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;启动成功后会有如下输出:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;2015-03-10 11:12:59 INFO     loading libcrypto from libcrypto.so.1.0.0
2015-03-10 11:12:59 INFO     starting local at 127.0.0.1:1080
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;3-浏览器代理设置&#34;&gt;3) 浏览器代理设置
&lt;/h2&gt;&lt;p&gt;一般来说我们不希望shadowsocks做全局的翻墙,那样,访问国内的速度也会变慢,我们在chome浏览器中安装switchysharp,来管理代理.具体设置如下所示:
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eq0k16t5ejj20ne0ihmzh.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;swichysharp设置&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;enjoy it!&lt;/p&gt;
&lt;h1 id=&#34;后记&#34;&gt;后记
&lt;/h1&gt;&lt;p&gt;安卓客户端安装,&lt;a class=&#34;link&#34; href=&#34;https://apps.evozi.com/apk-downloader/?id=com.github.shadowsocks&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;点我点我&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 这是一篇好博客 &lt;a class=&#34;link&#34; href=&#34;http://mushapi.com/shadowsocks-install-config-using.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://mushapi.com/shadowsocks-install-config-using.html&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;https://github.com/shadowsocks/shadowsocks/wiki/Shadowsocks-%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;shadowsocks使用说明&lt;/a&gt;
3 &lt;a class=&#34;link&#34; href=&#34;https://github.com/pypa/pip/issues/1742&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;修复我pip问题的一个issue&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;致谢&#34;&gt;致谢
&lt;/h1&gt;&lt;p&gt;这个网站可以下载google play的apk,对于我等天朝良民来说,可真是个好东西
&lt;a class=&#34;link&#34; href=&#34;https://apps.evozi.com/apk-downloader/?id=com.github.shadowsocks&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://apps.evozi.com/apk-downloader/?id=com.github.shadowsocks&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我们家&lt;a class=&#34;link&#34; href=&#34;http://huirong.github.io&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;笨笨的博客&lt;/a&gt;弄好了,欢迎访问&lt;/p&gt;
</description>
        </item>
        <item>
        <title>kali安装后设置</title>
        <link>https://blog.huirongis.me/post/after-kali/</link>
        <pubDate>Wed, 04 Mar 2015 14:14:57 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/after-kali/</guid>
        <description>&lt;p&gt;kali安装好了，还有几件事要做
我们用root的身份登进去系统&lt;/p&gt;
&lt;h1 id=&#34;1-更新软件源&#34;&gt;1 更新软件源
&lt;/h1&gt;&lt;p&gt;官方自带的软件源速度相对比较慢，资源也少一些，我们添加一些国内的源进去
vi /etc/apt/sources.list
（可自由选择，不一定要全部）：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 官方源
deb http://http.kali.org/kali kali main non-free contrib
deb-src http://http.kali.org/kali kali main non-free contrib
deb http://security.kali.org/kali-security kali/updates main contrib non-free

# 激进源，新手不推荐使用这个软件源
deb http://repo.kali.org/kali kali-bleeding-edge main
deb-src http://repo.kali.org/kali kali-bleeding-edge main

# 中科大kali源
deb http://mirrors.ustc.edu.cn/kali kali main non-free contrib
deb-src http://mirrors.ustc.edu.cn/kali kali main non-free contrib
deb http://mirrors.ustc.edu.cn/kali-security kali/updates main contrib non-free

# 阿里云kali源
deb http://mirrors.aliyun.com/kali kali main non-free contrib
deb-src http://mirrors.aliyun.com/kali kali main non-free contrib
deb http://mirrors.aliyun.com/kali-security kali/updates main contrib non-free
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;保存之后运行：
&lt;code&gt;apt-get update &lt;/code&gt;     # 刷新系统
&lt;code&gt;apt-get dist-upgrade &lt;/code&gt;        # 安装更新&lt;/p&gt;
&lt;h1 id=&#34;2-安装中文输入法和字体&#34;&gt;2 安装中文输入法和字体
&lt;/h1&gt;&lt;p&gt;安装字体
&lt;code&gt;apt-get install ttf-wqy-microhei ttf-wqy-zenhei&lt;/code&gt;
执行以下命令
&lt;code&gt;apt-get install fcitx fcitx-googlepinyin&lt;/code&gt;&lt;/p&gt;
&lt;h1 id=&#34;3-安装vpn&#34;&gt;3 安装vpn
&lt;/h1&gt;&lt;p&gt;kali默认情况下vpn是无法使用的，需要安装相关组件&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;apt-get install network-manager-openvpn
apt-get install network-manager-openvpn-gnome
apt-get install network-manager-pptp
apt-get install network-manager-pptp-gnome
apt-get install network-manager-strongswan
apt-get install network-manager-vpnc
apt-get install network-manager-vpnc-gnome
/etc/init.d/network-manager restart
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;4-网卡管理显示device-not-managed&#34;&gt;4 网卡管理显示“device not managed”
&lt;/h1&gt;&lt;p&gt;&lt;code&gt;vi  /etc/NetworkManager/NetworkManager.conf&lt;/code&gt;
修改&lt;code&gt;managed=false&lt;/code&gt;为&lt;code&gt;managed=true&lt;/code&gt;
然后重启网络管理
&lt;code&gt;service network-manager restart&lt;/code&gt;&lt;/p&gt;
&lt;h1 id=&#34;5-安装chrome浏览器&#34;&gt;5 安装chrome浏览器
&lt;/h1&gt;&lt;p&gt;&lt;code&gt;apt-get install google-chrome-unstable&lt;/code&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>kali和ubuntu双系统安装</title>
        <link>https://blog.huirongis.me/post/kali-and-ubuntu/</link>
        <pubDate>Tue, 03 Mar 2015 21:17:41 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/kali-and-ubuntu/</guid>
        <description>&lt;p&gt;时间忽快忽慢，一转眼，年过完了，又回来学校了，又一个多月没有push了，重新回到github。今天我们家笨笨给我找了点kali的资料，索性就把kali捡起来，第一步安装kali的系统。
此处背景不再介绍，直奔主题。kali的安装过程和ubuntu的安装过程类似，应该说原理上是一模一样的，只是界面有些不同。我的电脑当前已经安装了win8和ubuntu，现在需要再加一个kali的系统，三系统共存。
大体分为如下几个步骤：&lt;/p&gt;
&lt;h3 id=&#34;1-下载kali镜像&#34;&gt;1 下载kali镜像
&lt;/h3&gt;&lt;h3 id=&#34;2-刻录u盘&#34;&gt;2 刻录u盘
&lt;/h3&gt;&lt;h3 id=&#34;3-安装kali&#34;&gt;3 安装kali
&lt;/h3&gt;&lt;hr&gt;
&lt;h1 id=&#34;1-下载kali镜像-1&#34;&gt;1 下载kali镜像
&lt;/h1&gt;&lt;p&gt;这步很简单，我们去kali的官网下载&lt;a class=&#34;link&#34; href=&#34;https://www.kali.org/downloads/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.kali.org/downloads/&lt;/a&gt;,下载对应的版本。我这里下载的是第一个64位版本（&lt;a class=&#34;link&#34; href=&#34;http://cdimage.kali.org/kali-1.1.0/kali-linux-1.1.0-amd64.iso&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://cdimage.kali.org/kali-1.1.0/kali-linux-1.1.0-amd64.iso&lt;/a&gt;）,因为是在ubuntu下，我们可以顺手校验一下文件的hash值，防止文件损坏。
在终端中输入&lt;code&gt; sha1sum /home/chen/kali-linux-1.1.0-amd64.iso&lt;/code&gt;
查看输出是否是&lt;code&gt;40a1fd1d4864e7fac70438a1bf2095c8c1a4e764&lt;/code&gt;，若正确，则第一步完成。&lt;/p&gt;
&lt;h1 id=&#34;2-刻录u盘-1&#34;&gt;2 刻录u盘
&lt;/h1&gt;&lt;p&gt;如果采用硬盘安装的话，我们需要在win下面操作，使用easybcd来编辑grub引导，还需要解压文件，相对比较麻烦，我这里采用u盘安装，相对比较简单。
和安装ubuntu不同，我之前在win下用UltraISO来刻录,
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1epsvwgs1rqj20fa0c676e.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;刻录ubuntu&#34;
	
	
&gt;如图所示，便捷启动是可以不修改的，直接默认，点击写入就行。我今天在刻录kali的时候，发现这样写的u盘无法启动，开机的时候会提示&lt;code&gt;failed to boot from USB disk with error: gfxboot.c32: not a COM32R Image boot:&lt;/code&gt;的错误。
解决方法有两个
1 linux的用mkusb，windows的用Win32DiskImager 来制作U盘启动
具体用法：
&lt;a class=&#34;link&#34; href=&#34;https://wiki.ubuntu.com/Win32DiskImager/iso2usb&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://wiki.ubuntu.com/Win32DiskImager/iso2usb&lt;/a&gt;
&lt;a class=&#34;link&#34; href=&#34;https://help.ubuntu.com/community/mkusb&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://help.ubuntu.com/community/mkusb&lt;/a&gt;
2 在win下用UltraISO来刻录，记得更改便捷启动的设置，如图所示
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1epsw409qr3j20go09rjtp.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;更改便捷启动&#34;
	
	
&gt;，点击便捷启动-&amp;gt;选择写入新的启动器引导扇区——&amp;gt;syslinus——&amp;gt;写入&lt;/p&gt;
&lt;p&gt;&lt;em&gt;我采用的是法一，我在ubuntu中用mkusb来刻录&lt;/em&gt;&lt;/p&gt;
&lt;h1 id=&#34;3-安装kali-1&#34;&gt;3 安装kali
&lt;/h1&gt;&lt;p&gt;下面开始安装kali（以下图片是我用virtualbox虚拟机中安装拍摄的）&lt;/p&gt;
&lt;h2 id=&#34;1-引导成功以后开机画面如图所示&#34;&gt;1 引导成功以后，开机画面如图所示
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eptme5jxk5j20ne0hcjwf.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;开机画面&#34;
	
	
&gt;
我们选择&lt;code&gt;Graphical install&lt;/code&gt;,图形化安装，也可以选择&lt;code&gt;install&lt;/code&gt;那是文字界面安装&lt;/p&gt;
&lt;h2 id=&#34;2-选择语言地区&#34;&gt;2 选择语言，地区
&lt;/h2&gt;&lt;p&gt;语言： 选择 &lt;code&gt;chinese（simplified）简体中文&lt;/code&gt;
地区： 选择 &lt;code&gt;中国&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;3-配置网络名称和domain&#34;&gt;3 配置网络名称和domain
&lt;/h2&gt;&lt;p&gt;这个代表你的电脑在网络上的名称，比如win默认的就是pc-2000123131，也就是别人在网上邻居中看到你的电脑的名称。我们就用默认的&lt;code&gt;localhost&lt;/code&gt;
domain我们留空不管他，下一步&lt;/p&gt;
&lt;h2 id=&#34;4-设置root密码&#34;&gt;4 设置root密码
&lt;/h2&gt;&lt;p&gt;我们设置两次一样的密码就行，不要忘记了
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eptmmnvzlnj20ne0hcdih.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;设置root密码&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;5-磁盘分区&#34;&gt;5 磁盘分区
&lt;/h2&gt;&lt;p&gt;我们选择第三项&lt;code&gt;手动&lt;/code&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eptmp2uw4ij20ne0hc42t.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;磁盘分区选项&#34;
	
	
&gt;
&lt;strong&gt;分区&lt;/strong&gt;，这里我们一共分&lt;code&gt;三个区&lt;/code&gt;，一个300M的&lt;code&gt;/boot&lt;/code&gt;分区，一个2048M的&lt;code&gt;swap&lt;/code&gt;分区，其他的分为一个&lt;code&gt;/&lt;/code&gt;（你也可以把/home单独分区出来），因为分区方法类似，所以我只讲一个&lt;code&gt;/boot&lt;/code&gt;和&lt;code&gt;swap&lt;/code&gt;分区的步骤
&lt;strong&gt;boot分区&lt;/strong&gt;
&lt;strong&gt;注意:&lt;strong&gt;选择&lt;/strong&gt;可启动标志&lt;/strong&gt;，我们只有/boot设置为&lt;code&gt;开&lt;/code&gt;，其他分区的这个选项都是&lt;code&gt;关&lt;/code&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eptmu4nonsj20ne0hctbb.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;boot分区设置&#34;
	
	
&gt;
设置完成后，选择&lt;code&gt;分区设定结束&lt;/code&gt;，点击继续&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;交换空间&lt;/strong&gt;
&lt;strong&gt;注意:&lt;strong&gt;交换空间是一种&lt;/strong&gt;文件类型&lt;/strong&gt;，其他的分区是&lt;strong&gt;属于载点&lt;/strong&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eptn2gehkdj20ne0hc77a.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;交换空间swap分区设置&#34;
	
	
&gt;
设置完成后，选择&lt;code&gt;分区设定结束&lt;/code&gt;，点击继续&lt;/p&gt;
&lt;p&gt;等分区完成，就选择&lt;code&gt;分区设定结束并将修改写入磁盘&lt;/code&gt;，点击继续，就开始安装kali&lt;/p&gt;
&lt;h2 id=&#34;6-启动引导&#34;&gt;6 启动引导
&lt;/h2&gt;&lt;p&gt;当系统快安装完成的时候，会出现grub安装的选择,如图所示
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1eptnhakprmj20ns0j7dij.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;交换空间swap分区设置&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;因为我的系统是&lt;code&gt;win8&lt;/code&gt;和&lt;code&gt;ubuntu&lt;/code&gt;和&lt;code&gt;kali&lt;/code&gt;多系统共存，当前是由&lt;code&gt;win&lt;/code&gt;来引导（当前系统由谁引导就看开机看到的第一个&lt;code&gt;系统选择&lt;/code&gt;是谁的，如果是红色的ubuntu选项，那就说明由ubuntu引导）。
我这里选择否的话，那么我就需要去&lt;code&gt;win&lt;/code&gt;里面手动添加&lt;code&gt;kali&lt;/code&gt;的引导（使用easybcd来操作）。
如果你是&lt;code&gt;ubuntu&lt;/code&gt;来引导系统的话，一样需要手动去添加&lt;code&gt;kali&lt;/code&gt;的引导（这里我还不会）。
所以我选择&lt;code&gt;是&lt;/code&gt;，这样装完三个系统都可以正常开机了。&lt;/p&gt;
&lt;p&gt;到此所有的安装结束。&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 安装kali 系统 &lt;a class=&#34;link&#34; href=&#34;http://blog.sina.com.cn/s/blog_779dcd090102va9c.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://blog.sina.com.cn/s/blog_779dcd090102va9c.html&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;http://www.bkjia.com/Linuxjc/844530.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;kali系统安装图文教程，kali系统安装图文&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;致谢&#34;&gt;致谢
&lt;/h1&gt;&lt;p&gt;这里，要感谢我最亲爱的笨笨&lt;a class=&#34;link&#34; href=&#34;http://huirong.github.io&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://huirong.github.io&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Linux下使用github</title>
        <link>https://blog.huirongis.me/post/linux-how-to-use-github/</link>
        <pubDate>Mon, 19 Jan 2015 00:53:48 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/linux-how-to-use-github/</guid>
        <description>&lt;blockquote&gt;
&lt;p&gt;我的惰性真是病入膏肓了，已经整整3周没有在github上提交东西了，今天看了《模拟游戏》，索性又捡起来了。下面来总结一下linux下github的使用，也算是给自己一个备份，因为我自己也是老忘记。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;使用环境：Ubuntu 14.04&lt;/p&gt;
&lt;h2 id=&#34;1-安装git相关软件&#34;&gt;1 安装git相关软件
&lt;/h2&gt;&lt;p&gt;我的Ubuntu里面没有自带git相关软件，所以我们首先需要安装它，很简单。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo apt-get install git 
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;2-初始化git的设置&#34;&gt;2 初始化git的设置
&lt;/h2&gt;&lt;p&gt;接下来，进行初始化设置，也就是设置你的github账号和密码&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;git config --global user.name &amp;#34;zhangsan&amp;#34;# 其中的“zhangsan”输入的就是你注册时候的用户名，这步是设置你提交时候默认的用户名
# 之后设置提交时候默认的邮箱，在命令行输入：
git config --global user.email &amp;#34;haha@qq.com&amp;#34;
# 其中的“haha@qq.com”就是你注册时候用的邮箱，当然也可以用别的邮箱，用别的邮箱的时候你必须在github的主页上设置里面把用的邮箱添加进去
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;3-开始使用github&#34;&gt;3 开始使用github
&lt;/h2&gt;&lt;p&gt;1 首先你的github上应该有一个库，如果没有的话，就去github网站上新建一个库，或者fork一个别人的项目，以下的操作都是建立在这个基础上，&lt;code&gt;假设存在一个库https://github.com/Jackroyal/test.git&lt;/code&gt;.
如果你的github上已经有库了，可以忽略第1步直接进入第2步
2 我们在本地新建一个文件夹(命名随你便，我取名叫做test_git)&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mkdir test_git
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;3 将远程的库复制下来，我们使用git clone命令来完成&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# 如果你的环境不在test_git目录
# cd test_git
# 如果在test_git中
git clone https://github.com/Jackroyal/test.git# 他会在你的本地新建一个test文件夹
cd test
# 接下来新建一个测试文件
touch test.md
# 修改测试文件的内容
vi test.md
# 提交刚才所做的更改
git add .
git commit -m &amp;#34;首次提交&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;3 push提交到github&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;git remote add origin https://github.com/Jackroyal/test.git
git push
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;之后会提示你输入用户名密码，你输入你github账号和密码就行了
打完收工，睡觉
后面会陆续介绍hexo在Linux下的使用&lt;/p&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;http://blog.chinaunix.net/uid-29040159-id-3799719.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ubuntu 下 github 简单的使用教程&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;http://blog.csdn.net/pony_maggie/article/details/23207847&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Github入门级使用攻略&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>近期任务</title>
        <link>https://blog.huirongis.me/post/recent-task/</link>
        <pubDate>Tue, 02 Dec 2014 22:56:31 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/recent-task/</guid>
        <description>&lt;p&gt;2014-12-02 22:56:31  接下来的一个星期，我的任务是学习python爬虫的编写，至少要实现csdn博客转markdown的任务&lt;/p&gt;
</description>
        </item>
        <item>
        <title>配置hexo</title>
        <link>https://blog.huirongis.me/post/custom-hexo/</link>
        <pubDate>Fri, 28 Nov 2014 21:07:27 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/custom-hexo/</guid>
        <description>&lt;p&gt;经过&lt;a class=&#34;link&#34; href=&#34;http://jackroyal.github.io/2014/11/27/how-to-build-a-blog-with-hexo/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;上篇博客&lt;/a&gt;,我们搭建起了自己的博客,接下来我们对它做些个性化的定制.
在hexo中,配置文件一共两个(我的hexo安装在F:/blog/),分别是&lt;code&gt;F:/blog/_config.yml&lt;/code&gt;和&lt;code&gt;F:/blog/themes/light/_config.yml&lt;/code&gt;.第一个是全局的配置文件,第二个是主题的配置文件,在继续说之前,我们先来说一下主题安装.&lt;/p&gt;
&lt;h1 id=&#34;主题安装&#34;&gt;主题安装
&lt;/h1&gt;&lt;p&gt;这个很简单,在hexo的Github的主页上有个主题栏目,&lt;a class=&#34;link&#34; href=&#34;https://github.com/hexojs/hexo/wiki/Themes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/hexojs/hexo/wiki/Themes&lt;/a&gt;,里面列出了很多主题.
安装方法很简单&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ git clone &amp;lt;repository&amp;gt; themes/&amp;lt;theme-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;举个简单例子,我安装的主题名为&lt;code&gt;light&lt;/code&gt;,请在&lt;code&gt;F:/blog/&lt;/code&gt;目录下执行以下代码&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ git clone https://github.com/hexojs/hexo-theme-light themes/light
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果你不是在&lt;code&gt;F:/blog/&lt;/code&gt;中执行,请修改后面的路径themes/light为你的路径.基本原理就是把主题下下来,放在themes目录下就OK了,主题安装完毕.&lt;/p&gt;
&lt;h1 id=&#34;修改全局配置文件-fblog_configyml&#34;&gt;修改全局配置文件 &lt;code&gt;F:/blog/_config.yml&lt;/code&gt;
&lt;/h1&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# Hexo Configuration
# # Docs: http://hexo.io/docs/configuration.html
# # Source: https://github.com/hexojs/hexo/

# Site
title: 搁浅St的blog  # 站点的名称
subtitle: 我最喜欢笨笨   # 站点的副标题
description:             # 站点的描述,有利于搜索引擎的抓取
author: 搁浅St       # 作者
email: geqianst@qq.com          # 你的邮箱
language: zh-CN           # 语言,一般应该都是这个吧

# URL
# # If your site is put in a subdirectory, set url as &amp;#39;http://yoursite.com/child&amp;#39; and root as &amp;#39;/child/&amp;#39;
url: http://jackroyal.github.io       # 网站的url,在页面上,可以调用配置中的url参数,就是这个,比如google自定义搜索,需要制定搜索范围,就是通过这个设置的
root: /
permalink: :year/:month/:day/:title/
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
permalink_defaults:

# Directory
source_dir: source
public_dir: public

# Writing
new_post_name: :title.md # File name of new posts
default_layout: post  
titlecase: false # Transform title into titlecase
external_link: true # Open external links in new tab
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
highlight:
  enable: true
  line_number: true
  tab_replace:

# Category &amp;amp; Tag
default_category: uncategorized  
category_map:
tag_map:

# Archives 默认值为2，这里都修改为1，相应页面就只会列出标题，而非全文
# # 2: Enable pagination
# # 1: Disable pagination
# # 0: Fully Disable
archive: 1
category: 1
tag: 1

# Server
# # Hexo uses Connect as a server
# # You can customize the logger format as defined in
# # http://www.senchalabs.org/connect/logger.html
port: 4000
server_ip: localhost
logger: false
logger_format: dev

# Date / Time format
# # Hexo uses Moment.js to parse and display date
# # You can customize the date format as defined in
# # http://momentjs.com/docs/# /displaying/format/
date_format: MMM D YYYY
time_format: H:mm:ss

# Pagination
# # Set per_page to 0 to disable pagination
per_page: 5
pagination_dir: page

# Disqus
disqus_shortname:
# 这一行是我添加的duoshuo_shortname,因为天朝disqus不好用,用多说
duoshuo_shortname: jackroyal
# Extensions
# # Plugins: https://github.com/hexojs/hexo/wiki/Plugins
# # Themes: https://github.com/hexojs/hexo/wiki/Themes
theme: light
exclude_generator:

# Deployment  发布相关设置
# # Docs: http://hexo.io/docs/deployment.html
deploy:
  type: github
  repo: https://github.com/Jackroyal/Jackroyal.github.io.git
  branch: master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;至此,全局配置文件修改完毕,你可以&lt;code&gt;hexo g&lt;/code&gt;和&lt;code&gt;hexo s&lt;/code&gt;进行查看.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;menu:# 导航栏的设置默认只有这两个,还可以添加更多的导航
  Home: /
  Archives: /archives
# 它就是你页面右边的侧边项目,比如搜索之类,你可以根据自己的需求进行修改,你能用几个widgets可以在F:\blog\themes\light\layout\_widget中进行查看
widgets:# 我这里使用了所有的widgets
- search
- category
- tag
- recent_posts
- tagcloud

excerpt_link: Read More  # 可以换成中文的  阅读全文

twitter:
  username:
  show_replies: false
  tweet_count: 5
//默认的一个分享组件,因为主要针对国外,不适合国内我们不使用它
addthis:
  enable: false  # 把true改为false
  pubid:
  facebook: true
  twitter: true
  google: true
  pinterest: true

fancybox: true

google_analytics:
rss:
duoshuo_shortname: jackroyal  # 多说的用户名

comment_provider:
# Facebook comment
facebook:
  appid: 123456789012345
  comment_count: 5
  comment_width: 840
  comment_colorscheme: light
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;至此,配置文件修改完毕,上面提到了我们不适用disqus的评论组件,使用多说,下面教大家来配置多说&lt;/p&gt;
&lt;h1 id=&#34;创建多说&#34;&gt;创建多说
&lt;/h1&gt;&lt;p&gt;首先我们去多说注册一个账号,&lt;a class=&#34;link&#34; href=&#34;http://duoshuo.com/&#34;  title=&#34;多说官网&#34;
     target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;点击这里&lt;/a&gt;
我们点击&lt;a class=&#34;link&#34; href=&#34;http://duoshuo.com/create-site/&#34;  title=&#34;我要安装&#34;
     target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;我要安装&lt;/a&gt;,界面如下
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1emtdlnpsqaj20wo0lp783.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;duoshuo 创建界面&#34;
	
	
&gt;
shortname就是jackroyal,创建完成后,跳转到如下界面
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1emtdp96x54j20us0jxn18.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;获取多说代码&#34;
	
	
&gt;
我们选择&lt;code&gt;通用代码&lt;/code&gt;,点击复制,就行了&lt;/p&gt;
&lt;h1 id=&#34;配置多说&#34;&gt;配置多说
&lt;/h1&gt;&lt;p&gt;这里说一个前提,我使用的是light主题,如果你用的是其他主题,接下来的设置可能给我有点区别,但是原理差不多,参考看看&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;我们打开&lt;code&gt;F:\blog\themes\light\layout\_partial\comment.ejs&lt;/code&gt;这个文件,然后修改后代码如下(如果你不是light主题,可能跟这个不一样,你去找下包含comment的section在哪里,改法还是这样.例如系统默认的landscape主题,下面这段代码就是在article.ejs,它没有comment.ejs)&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;% if (page.comments){ %&amp;gt;
&amp;lt;!-- 这里添加了一个导航,页面的下面会有一个上一篇,下一篇 --&amp;gt;
 &amp;lt;nav id=&amp;#34;pagination&amp;#34; &amp;gt;
    &amp;lt;% if (page.prev) { %&amp;gt;
    &amp;lt;a href=&amp;#34;&amp;lt;%- config.root %&amp;gt;&amp;lt;%- page.prev.path %&amp;gt;&amp;#34; class=&amp;#34;alignleft prev&amp;#34; &amp;gt; &amp;lt;%=page.prev.title %&amp;gt; &amp;lt;/a&amp;gt;
    &amp;lt;% } %&amp;gt;
    &amp;lt;% if (page.next) { %&amp;gt;
    &amp;lt;a href=&amp;#34;&amp;lt;%- config.root %&amp;gt;&amp;lt;%- page.next.path %&amp;gt;&amp;#34; class=&amp;#34;alignright next&amp;#34; &amp;gt; &amp;lt;%=page.next.title %&amp;gt; &amp;lt;/a&amp;gt;
    &amp;lt;% } %&amp;gt;
    &amp;lt;div class=&amp;#34;clearfix&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/nav&amp;gt;
&amp;lt;!-- 导航结束 --&amp;gt;
&amp;lt;section id=&amp;#34;comments&amp;#34;&amp;gt;
&amp;lt;!-- 这里是多说的代码,直接把你的代码粘贴到这里就行 --&amp;gt;
    &amp;lt;!-- 多说评论框 start --&amp;gt;
    &amp;lt;div class=&amp;#34;ds-thread&amp;#34; data-thread-key=&amp;#34;&amp;lt;%= page.layout %&amp;gt;-&amp;lt;%= page.slug %&amp;gt;&amp;#34; data-title=&amp;#34;&amp;lt;%= page.title %&amp;gt;&amp;#34; data-url=&amp;#34;&amp;lt;%= page.permalink %&amp;gt;&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;!-- 多说评论框 end --&amp;gt;
    &amp;lt;!-- 多说公共JS代码 start (一个网页只需插入一次) --&amp;gt;
    &amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
    var duoshuoQuery = {short_name:&amp;#39;&amp;lt;%= config.duoshuo_shortname %&amp;gt;&amp;#39;};
      (function() {
        var ds = document.createElement(&amp;#39;script&amp;#39;);
        ds.type = &amp;#39;text/javascript&amp;#39;;ds.async = true;
        ds.src = (document.location.protocol == &amp;#39;https:&amp;#39; ? &amp;#39;https:&amp;#39; : &amp;#39;http:&amp;#39;) + &amp;#39;//static.duoshuo.com/embed.js&amp;#39;;
        ds.charset = &amp;#39;UTF-8&amp;#39;;
        (document.getElementsByTagName(&amp;#39;head&amp;#39;)[0]
         || document.getElementsByTagName(&amp;#39;body&amp;#39;)[0]).appendChild(ds);
      })();
      &amp;lt;/script&amp;gt;
    &amp;lt;!-- 多说公共JS代码 end --&amp;gt;
  &amp;lt;!-- 多说结束 --&amp;gt;
  &amp;lt;/section&amp;gt;
&amp;lt;% } %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;眼尖的同学可能已经看到我的上面第16行代码与你们的不同,这行代码包括了页面的标题和url,它会根据hexo的配置,由hexo动态生成,所以你把你的代码替换成我的这行代码.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;div class=&amp;#34;ds-thread&amp;#34; data-thread-key=&amp;#34;&amp;lt;%= page.layout %&amp;gt;-&amp;lt;%= page.slug %&amp;gt;&amp;#34; data-title=&amp;#34;&amp;lt;%= page.title %&amp;gt;&amp;#34; data-url=&amp;#34;&amp;lt;%= page.permalink %&amp;gt;&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;至此,多说添加完毕&lt;/p&gt;
&lt;h1 id=&#34;修复bug&#34;&gt;修复bug
&lt;/h1&gt;&lt;p&gt;我发现light的主题貌似有个小bug,在&lt;code&gt;F:\blog\themes\light\layout\_partial\article.ejs&lt;/code&gt;中间第27行有这样一行代码&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;        &amp;lt;% if (item.comment &amp;amp;&amp;amp; config.disqus_shortname){ %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;首先我们,替换config.disqus_shortname为config.duoshuo_shortname.
然后修改&lt;code&gt;item.comment&lt;/code&gt;为&lt;code&gt;item.comments&lt;/code&gt;,因为系统中没有comment这个变量,只有comments这个变量,如果不修改comments,那么&lt;code&gt;item.comment&lt;/code&gt;一直为假,所以一直不成立,就不会显示comments字段了.修改后代码如下&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; &amp;lt;% if (item.comments &amp;amp;&amp;amp; config.duoshuo_shortname){ %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;产生的效果如图&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1emteitia5uj20tl0fn412.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;开启和关闭comment的区别&#34;
	
	
&gt;.
至此,配置hexo,打完收工
enjoy it&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h1&gt;&lt;p&gt;1 &lt;a class=&#34;link&#34; href=&#34;http://zipperary.com/2013/05/29/hexo-guide-3/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://zipperary.com/2013/05/29/hexo-guide-3/&lt;/a&gt;
2 &lt;a class=&#34;link&#34; href=&#34;http://dev.duoshuo.com/threads/541d3b2b40b5abcd2e4df0e9&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;duoshuo官方Hexo使用教程&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>使用hexo建立自己的Github pages</title>
        <link>https://blog.huirongis.me/post/how-to-build-a-blog-with-hexo/</link>
        <pubDate>Thu, 27 Nov 2014 14:48:29 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/how-to-build-a-blog-with-hexo/</guid>
        <description>&lt;p&gt;昨天经过一天的&lt;a class=&#34;link&#34; href=&#34;http://jackroyal.github.io/2014/11/26/new-start/&#34;  title=&#34;生命在于折腾&#34;
     target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;折腾&lt;/a&gt;,总算把博客搭建起来了,今天就来写个博客总结一下.
网上的资料很多,我主要参考的是这篇博客,一路很顺利.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;http://zipperary.com/2013/05/28/hexo-guide-2/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://zipperary.com/2013/05/28/hexo-guide-2/&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;一个很重要的原因就是他是针对windows的,刚好我也在用windows.&lt;/p&gt;
&lt;h1 id=&#34;安装过程&#34;&gt;安装过程
&lt;/h1&gt;&lt;h1 id=&#34;-1-安装github-for-windows&#34;&gt;# 1. 安装Github for windows
&lt;/h1&gt;&lt;p&gt;因为我之前就在用Github,所以早就安装了这个.已经装过的同学请忽略这一段.
下载 &lt;a class=&#34;link&#34; href=&#34;https://windows.github.com/&#34;  title=&#34;Github for windows&#34;
     target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Github for windows&lt;/a&gt; 并执行即可完成安装(&lt;em&gt;在线安装,会有点慢&lt;/em&gt;)。这个软件的的好处是有一个带GUI的界面,还有一个终端界面.如图所示
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3jw1emplp1lz31j204w033mx0.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Github for windows&#34;
	
	
&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/692869a3gw1empluh6hvej210b0j741r.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;GUI and Bash&#34;
	
	
&gt;
如果你不喜欢用这个,也可以用上面的博客推荐的&lt;a class=&#34;link&#34; href=&#34;http://code.google.com/p/msysgit/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;msysgit&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;-2-安装nodejs&#34;&gt;# 2. 安装Node.js
&lt;/h1&gt;&lt;p&gt;在 Windows 环境下安装 &lt;a class=&#34;link&#34; href=&#34;http://nodejs.org/&#34;  title=&#34;Node.js 官网&#34;
     target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Node.js&lt;/a&gt; 非常简单，仅须下载安装文件并执行即可完成安装。（win下建议下载msi格式的，因为这样可以不用配置环境变量之类的）&lt;/p&gt;
&lt;h1 id=&#34;-3-测试nodejs是否安装&#34;&gt;# 3. 测试node.js是否安装
&lt;/h1&gt;&lt;p&gt;在任何控制台输入(可以按windows键+R,输入cmd,然后输入npm,一般来说不会有问题)&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;npm
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;返回值如下&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Usage: npm &amp;lt;command&amp;gt;

where &amp;lt;command&amp;gt; is one of:
    add-user, adduser, apihelp, author, bin, bugs, c, cache,
    completion, config, ddp, dedupe, deprecate, docs, edit,
    explore, faq, find, find-dupes, get, help, help-search,
    home, i, info, init, install, isntall, issues, la, link,
    list, ll, ln, login, ls, outdated, owner, pack, prefix,
    prune, publish, r, rb, rebuild, remove, repo, restart, rm,
    root, run-script, s, se, search, set, show, shrinkwrap,
    star, stars, start, stop, submodule, t, tag, test, tst, un,
    uninstall, unlink, unpublish, unstar, up, update, v,
    version, view, whoami

npm &amp;lt;cmd&amp;gt; -h     quick help on &amp;lt;cmd&amp;gt;
npm -l           display full usage info
npm faq          commonly asked questions
npm help &amp;lt;term&amp;gt;  search for help on &amp;lt;term&amp;gt;
npm help npm     involved overview

Specify configs in the ini-formatted file:
    C:\Users\chenhao\.npmrc
or on the command line via: npm &amp;lt;command&amp;gt; --key value
Config info can be viewed via: npm help config

npm@1.4.28 D:\Program Files (x86)\nodejs\node_modules\npm
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;看到这个结果,就表示你的node.js已经安装上去了
*感谢我们家笨笨的反馈：*此处如果npm无效，首先确定win下你采用的是msi格式的安装文件，然后重启下电脑，应该就正常了。&lt;/p&gt;
&lt;h1 id=&#34;-4-安装hexo&#34;&gt;# 4. 安装hexo
&lt;/h1&gt;&lt;p&gt;接下来的操作我都是用&lt;strong&gt;Github for windows&lt;/strong&gt;自带的Bash来完成的,因为后面会涉及到SSH,用&lt;strong&gt;Github for windows&lt;/strong&gt;,就可以避免这个问题.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在Bash中输入以下命令&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;npm install -g hexo
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;创建hexo文件夹
创建你hexo放置的文件夹,先用Bash进入到目标文件夹,比如我的是F:/blog/,接下来初始化hexo,自动生成相关的文件,在F:/blog/环境下,输入&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd /f/blog  # 这个命令表示当前进入目录为f：/blog/
hexo init
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;安装依赖包&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;本地预览,做完以上操作,可以本地预览一下&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;hexo g
hexo s
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;ok到这里博客搭建基本完成现在要做的就是把它发布到你的github上去&#34;&gt;以上两条命令的意思是:
生成相关文件(就是生成目标html,静态博客嘛,就是很多html组成)
打开本地服务器预览(node.js就是干这事的,点击访问&lt;a class=&#34;link&#34; href=&#34;http://localhost:4000&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://localhost:4000&lt;/a&gt;,就可以看到了)
&lt;strong&gt;ok&lt;/strong&gt;,到这里,博客搭建基本完成,现在要做的就是把它发布到你的Github上去
&lt;/h2&gt;&lt;p&gt;接下来,教你怎么发布到Github上去&lt;/p&gt;
&lt;h1 id=&#34;注册github&#34;&gt;注册Github
&lt;/h1&gt;&lt;p&gt;这一步没什么说的,如果你连简单的注册都不会,我也不会教你╮(╯▽╰)╭&lt;/p&gt;
&lt;h1 id=&#34;创建公共库&#34;&gt;创建公共库
&lt;/h1&gt;&lt;p&gt;在自己Github主页右下角，创建一个新的repository(&lt;a class=&#34;link&#34; href=&#34;https://github.com/new&#34;  title=&#34;点我新建&#34;
     target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;点这里&lt;/a&gt;)。比如我的Github账号是Jackroyal，那么我应该创建的repository名字应该是Jackroyal.github.io(注意你的repository名字就是Jackroyal.github.io,我之前用的是Jackroyal怎么尝试都不行)。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;PS:有个大小写的问题其实我注册的是Jackroyal,大写的J,但是我访问的时候特别是带https的链接,他会自动转为小写访问.怎么说呢?简单点,你就按照你的用户名来,该大写大写,该小写小写&lt;/p&gt;&lt;/blockquote&gt;
&lt;h1 id=&#34;部署&#34;&gt;部署
&lt;/h1&gt;&lt;p&gt;现在万事俱备,只差部署了,我们来配置下&lt;code&gt;_config.yml&lt;/code&gt;.
这个文件在路径是F:/blog/_config.yml.
用编辑器把它打开,修改最后一段
ps:以下为hexo 2.8x的配置方法,不适用于3.0&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;deploy:
  type: github
  repo: https://github.com/Jackroyal/Jackroyal.github.io.git
  branch: master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;update 2015-06-16:&lt;/em&gt;
现在hexo由2.8升级到3.0了,按照上面的方式安装,你的hexo版本是hexo 3.0,3.0的这段代码的设置内容如下:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;deploy:
  type: git
  repo: https://github.com/Jackroyal/Jackroyal.github.io.git
  branch: master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;照着我的这个格式修改就好了,把我里面的用户名替换成你的.
至此基本完成所有搭建步骤.&lt;/p&gt;
&lt;h1 id=&#34;上传&#34;&gt;上传
&lt;/h1&gt;&lt;p&gt;我们开始上传项目的代码,再重复一次,我一直以来用的工具都是_Github for windows_自带的Bash,所以我没有配置SSH,如果你用的windows自带的终端或者其他比如msysgit,可能需要配置SSH,不然无法使用Github(点击&lt;a class=&#34;link&#34; href=&#34;https://help.github.com/articles/generating-ssh-keys/&#34;  title=&#34;https://help.github.com/articles/generating-ssh-keys/&#34;
     target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;这里&lt;/code&gt;&lt;/a&gt;查看官方教程).
我们输入以下命令&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;hexo g
hexo d
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;或者偷个懒&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;hexo d -g
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ok,现在就可以去看看你的个人主页了,逼格满满有木有.&lt;/p&gt;
&lt;h1 id=&#34;问题&#34;&gt;问题
&lt;/h1&gt;&lt;p&gt;我的中间出过一些问题:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;我的&lt;code&gt;hexo d&lt;/code&gt;的时候出错,可以尝试手动删除&lt;code&gt;.deploy&lt;/code&gt;文件夹,然后执行&lt;code&gt;hexo clean&lt;/code&gt;还有可能出现的情况是,&lt;code&gt;deploy&lt;/code&gt;没错但是一直没有提示&lt;code&gt;deploy done&lt;/code&gt;,那就是骚年,你访问Github网速太慢&lt;/li&gt;
&lt;li&gt;我&lt;code&gt;deploy d&lt;/code&gt;成功以后,在Github里面已经看到生成的页面了,访问&lt;a class=&#34;link&#34; href=&#34;http://jackroyal.github.io&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://jackroyal.github.io&lt;/a&gt;或者&lt;a class=&#34;link&#34; href=&#34;https://jackroyal.github.io&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://jackroyal.github.io&lt;/a&gt;一直报404的错误,这种时候等一等就好了,一般等几分钟.如果一直不好那就给官方发个邮件,他们很快会回复你的,有什么问题说清楚就行.&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&#34;致谢&#34;&gt;致谢
&lt;/h1&gt;&lt;p&gt;这里，要感谢我最亲爱的笨笨，是她给我测试和反馈的&lt;a class=&#34;link&#34; href=&#34;http://huirong.github.io&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://huirong.github.io&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>新的开始</title>
        <link>https://blog.huirongis.me/post/new-start/</link>
        <pubDate>Wed, 26 Nov 2014 21:29:15 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/new-start/</guid>
        <description>&lt;p&gt;今天&lt;strong&gt;折腾&lt;/strong&gt;了一天,终于弄好了,&lt;a class=&#34;link&#34; href=&#34;http://jackroyal.github.io&#34;  title=&#34;搁浅St的博客&#34;
     target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;我的博客&lt;/a&gt;,正式落户Github.
&lt;img src=&#34;https://blog.huirongis.me/images/GitHub-Mark.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;GitHub Mark&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>[js]replace替换</title>
        <link>https://blog.huirongis.me/post/js-replace/</link>
        <pubDate>Tue, 25 Nov 2014 22:32:00 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/js-replace/</guid>
        <description>&lt;p&gt;今天做前端试题,用到了replace函数,来记录一下.
(以下部分知识点来自&lt;a class=&#34;link&#34; href=&#34;http://www.w3cschool.cn/jsref_replace.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://www.w3cschool.cn/jsref_replace.html&lt;/a&gt;)&lt;/p&gt;
&lt;h2 id=&#34;定义和用法&#34;&gt;定义和用法
&lt;/h2&gt;&lt;p&gt;replace() 方法用于在字符串中用一些字符替换另一些字符，或替换一个与正则表达式匹配的子串。&lt;/p&gt;
&lt;h3 id=&#34;语法&#34;&gt;语法
&lt;/h3&gt;&lt;!-- raw HTML omitted --&gt;
&lt;h3 id=&#34;返回值&#34;&gt;返回值
&lt;/h3&gt;&lt;p&gt;一个新的字符串，是用 &lt;em&gt;replacement&lt;/em&gt; 替换了 regexp 的第一次匹配或所有匹配之后得到的。&lt;/p&gt;
&lt;h3 id=&#34;说明&#34;&gt;说明
&lt;/h3&gt;&lt;p&gt;字符串 stringObject 的 replace() 方法执行的是查找并替换的操作。它将在 stringObject 中查找与 regexp 相匹配的子字符串，然后用 &lt;em&gt;replacement&lt;/em&gt; 来替换这些子串。如果 regexp 具有全局标志 g，那么 replace() 方法将替换所有匹配的子串。否则，它只替换第一个匹配子串。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;replacement&lt;/em&gt; 可以是字符串，也可以是函数。如果它是字符串，那么每个匹配都将由字符串替换。但是 replacement 中的 $ 字符具有特定的含义。如下表所示，它说明从模式匹配得到的字符串将用于替换。&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;__注意：__ECMAScript v3 规定，replace() 方法的参数 replacement 可以是函数而不是字符串。在这种情况下，每个匹配都调用该函数，它返回的字符串将作为替换文本使用。该函数的第一个参数是匹配模式的字符串。接下来的参数是与模式中的子表达式匹配的字符串，可以有 0 个或多个这样的参数。接下来的参数是一个整数，声明了匹配在 stringObject 中出现的位置。最后一个参数是
stringObject 本身。&lt;/p&gt;
&lt;p&gt;下面给几个简单的例子来说明一下&lt;/p&gt;
&lt;p&gt;ps:介绍一下正则的小知识,\w表示匹配一个英文字符,+表示匹配数量必须大于一个,\b就是分节符,单词中间分隔用的,连在一起就是取出前面字符串中所有的单词&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;my name is&amp;#39;&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;replace&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;/(\w+)\b/g&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;haha  &amp;#39;&lt;/span&gt;);&lt;span style=&#34;color:#75715e&#34;&gt;//输出结果为   &amp;#34;haha   haha   haha  &amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;my name is&amp;#39;&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;replace&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;/(\w+)\b/g&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;$1aa&amp;#39;&lt;/span&gt;);&lt;span style=&#34;color:#75715e&#34;&gt;//输出结果为&amp;#34;myaa nameaa isaa&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;my name is&amp;#39;&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;replace&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;/((\w)(\w+?))\b/g&lt;/span&gt;,&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;m&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;b&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;c&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;d&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;e&lt;/span&gt;){&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;b&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;toUpperCase&lt;/span&gt;()&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;c&lt;/span&gt;;});&lt;span style=&#34;color:#75715e&#34;&gt;//输出结果为&amp;#34;My Name Is&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;重点讲解一下第三个,replace返回值为函数的例子(function必须要return)&lt;/p&gt;
&lt;p&gt;当replace返回值为函数的时候&lt;/p&gt;
&lt;p&gt;如果只有一个分组的话,他的参数是funciton(match,pos,originalText),分别表示模式的匹配项,模式匹配项在字符串中的位置和原始字符串&lt;/p&gt;
&lt;p&gt;如果有多个分组的话,他的参数是funciton(match,arr1,arr2,arr3,&amp;hellip;.arrn,pos,originalText),分别表示模式的匹配项,模式匹配项,还有n个匹配的分组,最后的两个参数是在字符串中的位置和原始字符串&lt;/p&gt;
&lt;p&gt;比如下面的例子,执行的结果就是&lt;/p&gt;
&lt;p&gt;&amp;lsquo;my name is imweba &amp;lsquo;.replace(/((\w)(\w+?))\b/g,function(m,a,b,c,d,e){&lt;/p&gt;
&lt;p&gt;console.log(m);&lt;/p&gt;
&lt;p&gt;console.log(a);&lt;/p&gt;
&lt;p&gt;console.log(b);&lt;/p&gt;
&lt;p&gt;console.log(c);&lt;/p&gt;
&lt;p&gt;console.log(d);&lt;/p&gt;
&lt;p&gt;console.log(e);&lt;/p&gt;
&lt;p&gt;});
执行结果&lt;/p&gt;
&lt;p&gt;my//模式匹配的值,因为上面匹配了整个单词,虽然分了多个组&lt;/p&gt;
&lt;p&gt;my//第一个分组的值&lt;/p&gt;
&lt;p&gt;m//第二个分组的值&lt;/p&gt;
&lt;p&gt;y//第三个分组的值&lt;/p&gt;
&lt;p&gt;0//模式匹配在字符串中的起始位置&lt;/p&gt;
&lt;p&gt;my name is imweba  //原始字符串&lt;/p&gt;
&lt;p&gt;name&lt;/p&gt;
&lt;p&gt;name&lt;/p&gt;
&lt;p&gt;n&lt;/p&gt;
&lt;p&gt;ame&lt;/p&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;p&gt;my name is imweba &lt;/p&gt;
&lt;p&gt;is&lt;/p&gt;
&lt;p&gt;is&lt;/p&gt;
&lt;p&gt;i&lt;/p&gt;
&lt;p&gt;s&lt;/p&gt;
&lt;p&gt;8&lt;/p&gt;
&lt;p&gt;my name is imweba &lt;/p&gt;
&lt;p&gt;imweba&lt;/p&gt;
&lt;p&gt;imweba&lt;/p&gt;
&lt;p&gt;i&lt;/p&gt;
&lt;p&gt;mweba&lt;/p&gt;
&lt;p&gt;11&lt;/p&gt;
&lt;p&gt;my name is imweba &lt;/p&gt;
&lt;p&gt;&amp;ldquo;undefined undefined undefined undefined &amp;ldquo;//这一行是因为function必须要有return,我没写return,所以就都是undefined&lt;/p&gt;
&lt;p&gt;ok  打完收工&lt;/p&gt;
</description>
        </item>
        <item>
        <title>[js]前端试题</title>
        <link>https://blog.huirongis.me/post/js-problem/</link>
        <pubDate>Tue, 25 Nov 2014 22:26:00 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/js-problem/</guid>
        <description>&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 1、获取页面id为 hello 的节点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;he&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;document.&lt;span style=&#34;color:#a6e22e&#34;&gt;getElementById&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;hello&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 2、获取页面所有 div 标签
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;di&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;document.&lt;span style=&#34;color:#a6e22e&#34;&gt;getElementsByTagName&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;div&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 3、给 id 为hello的节点绑定click 事件，点击的时候弹出 &amp;#34;hello&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;document.&lt;span style=&#34;color:#a6e22e&#34;&gt;getElementById&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;hello&amp;#39;&lt;/span&gt;).&lt;span style=&#34;color:#a6e22e&#34;&gt;onclick&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(){&lt;span style=&#34;color:#a6e22e&#34;&gt;alert&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;helo&amp;#39;&lt;/span&gt;)};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 4、将页面上 id为hello的节点隐藏
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;document.&lt;span style=&#34;color:#a6e22e&#34;&gt;getElementById&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;hello&amp;#39;&lt;/span&gt;).&lt;span style=&#34;color:#a6e22e&#34;&gt;style&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;visibility&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;none&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 5、将 &amp;#34;hello world&amp;#34; 用正则替换成 &amp;#34;hello javascript”
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;str&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;hello world&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;str&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;replace&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;/hello[\s]+world/g&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;hello javascript&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 6、给节点（假设为element）绑定click事件，当被点击时候，alert 弹出事件的类型（通过jquery）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;$&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;element&lt;/span&gt;).&lt;span style=&#34;color:#a6e22e&#34;&gt;click&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;event&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;alert&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;event&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;type&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 7、给一个节点添加一个类 &amp;#34;hello&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;document.&lt;span style=&#34;color:#a6e22e&#34;&gt;getElementById&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;kw&amp;#39;&lt;/span&gt;).&lt;span style=&#34;color:#a6e22e&#34;&gt;className&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;document.&lt;span style=&#34;color:#a6e22e&#34;&gt;getElementById&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;kw&amp;#39;&lt;/span&gt;).&lt;span style=&#34;color:#a6e22e&#34;&gt;className&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34; hello&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 8、给节点（假设为element）绑定click事件，当被点击时候，alert 弹出事件的类型（要求兼容IE、标准浏览器）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;element&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;onclick&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;event&lt;/span&gt;){&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;e&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;event&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt;window.&lt;span style=&#34;color:#a6e22e&#34;&gt;event&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 9、假设页面有这么两个节点将 id为world的节点的 内容设置成 跟 id 为 hello 的节点一样。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;document.&lt;span style=&#34;color:#a6e22e&#34;&gt;getElementById&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;world&amp;#39;&lt;/span&gt;).&lt;span style=&#34;color:#a6e22e&#34;&gt;innerHTML&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;document.&lt;span style=&#34;color:#a6e22e&#34;&gt;getElementById&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;hello&amp;#39;&lt;/span&gt;).&lt;span style=&#34;color:#a6e22e&#34;&gt;innerHTML&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 10、通过 js 将element的margin-left 设置为 20px
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;element&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;style&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;marginLeft&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;20px&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 1.[{a:3},{a:4},{a:1},{a:2}] sort排序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sortnum&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;b&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;b&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//   [{a:3,b:5},{a:4,b:6},{a:1},{a:2,b:8}]按a的正向排序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sortab&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;b&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;b&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;?&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;b&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;b&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;b&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//   sort 排序原理  使用的算法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 2.my name is imweba ... =&amp;gt; my6 name7 is8 imweba9 ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//   用正则实现
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;my name is imweba &amp;#39;&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;replace&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;/([\w]+)\b/g&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;$1&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;attr&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;my name is imweba &amp;#39;&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;match&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;/([\w]+)\b/g&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;attr&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt;; &lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;attr&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;attr&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;attr&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;join&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt;);&lt;span style=&#34;color:#75715e&#34;&gt;//感觉不对,只能做到这个程度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 3.实现function test(str)(){},将str的每个单词的首字母大写（str为英文字符串）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;test&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;str&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;str&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;replace&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;/((\w)(\w+?))\b/g&lt;/span&gt;,&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;m&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;b&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;c&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;d&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;e&lt;/span&gt;){&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;b&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;toUpperCase&lt;/span&gt;()&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;c&lt;/span&gt;;});
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 4.写一个二分查找的算法   （假设这个数组不是有序的呢）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 5.123+”+34  直接说结果   12334
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12334&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 加法会将数字转化为字符串，减法和乘法等会将字符串转化为数字
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// &amp;#34;4&amp;#34;\*&amp;#34;5&amp;#34;=20
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 6.实现function find(attr,val){},找到当前页面里具备属性为attr且值为val的节点，输出其父元素名称
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;find&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;attr&lt;/span&gt;,&lt;span style=&#34;color:#a6e22e&#34;&gt;val&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;dom&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;document.&lt;span style=&#34;color:#a6e22e&#34;&gt;getElementsByTagName&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\*&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; &lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;dom&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt;; &lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;dom&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;getAttribute&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;attr&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;val&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;dom&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;i&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;parentNode&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;tagName&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
        </item>
        <item>
        <title>cmcc520扩展使用说明</title>
        <link>https://blog.huirongis.me/post/how-to-use-cmcc520/</link>
        <pubDate>Mon, 24 Nov 2014 21:56:00 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/how-to-use-cmcc520/</guid>
        <description>&lt;p&gt;我的cmcc520 2.0版本终于完成了,写个使用说明&lt;/p&gt;
&lt;p&gt;学校部分范围有CMCC-EDU可用,通过手动修改ssid,可以免费使用.&lt;/p&gt;
&lt;p&gt;写了个扩展来简化这个过程.&lt;/p&gt;
&lt;p&gt;1 安装扩展
将保存下来的 *.crx 文件或*.js 文件直接拖拽到浏览器的“扩展程序”（[chrome://chrome/extensions](&amp;ldquo;Chrome 扩展程序页面&amp;rdquo;)/）页面。
&lt;img src=&#34;https://blog.huirongis.me/images/20141124215558921.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;( 注：只有拖动到此页面才能安装，其它页面无效)&lt;/p&gt;
&lt;p&gt;　　2. 按照提示安装
&lt;img src=&#34;https://blog.huirongis.me/images/20141124215611765.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt; 
详细安装过程见&lt;a class=&#34;link&#34; href=&#34;http://www.williamlong.info/archives/3160.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://www.williamlong.info/archives/3160.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;3,配置软件功能&lt;/p&gt;
&lt;p&gt;左键点击图标,可以选择开关扩展功能(默认为开启)
 &lt;img src=&#34;https://blog.huirongis.me/images/20141124215702865.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;4.使用软件&lt;/p&gt;
&lt;p&gt;如果软件的功能打开,那么如果当你使用cmcc-edu的时候会自动跳转完成登录,不再需要手动操作,登录成功页面如下,你可以关闭这个页面了
&lt;img src=&#34;https://blog.huirongis.me/images/20141124215651437.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;5.下线&lt;/p&gt;
&lt;p&gt;在任何页面按ALT+X   可以下线&lt;/p&gt;
&lt;p&gt;Ps,如果按Alt+x无任何提示,可能是快捷键设置有问题
 &lt;img src=&#34;https://blog.huirongis.me/images/20141124215717575.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/20141124215740968.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;那就需要你按照上图手动设置快捷键&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;6 反馈
如果发现任何bug,可以和我联系&lt;/p&gt;
&lt;p&gt;新浪微博&lt;a class=&#34;link&#34; href=&#34;http://weibo.com/517123263&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://weibo.com/517123263&lt;/a&gt;
Github项目地址 &lt;a class=&#34;link&#34; href=&#34;https://github.com/Jackroyal/cmcc520&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/Jackroyal/cmcc520&lt;/a&gt;
我的csdn博客&lt;a class=&#34;link&#34; href=&#34;file:///C:/Users/chenhao/Desktop/%20http:/blog.csdn.net/jackroyal&#34; &gt; http://blog.csdn.net/jackroyal&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;2014/11/24&lt;/p&gt;
</description>
        </item>
        <item>
        <title>chrome扩展开发手记-chrome扩展开始第一步manfest.json</title>
        <link>https://blog.huirongis.me/post/chrome-extention-3/</link>
        <pubDate>Mon, 24 Nov 2014 15:16:00 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/chrome-extention-3/</guid>
        <description>&lt;p&gt;参考文档   &lt;a class=&#34;link&#34; href=&#34;https://lmk123.duapp.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://lmk123.duapp.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;下面开始写chrome扩展了,第一步就是看文档,官方文档有入门指导,先要过一遍&lt;/p&gt;
&lt;p&gt;我们首先来编写第一个文件manfest.json,这是一个清单文件,告诉系统,我有哪些文件,需要申请哪些权限都在里面,下卖弄给出我的manfest.json&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmcc520&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#75715e&#34;&gt;//扩展的名称
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#75715e&#34;&gt;//扩展的版本号,随便写
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;powered by 搁浅St&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#75715e&#34;&gt;//扩展的描述,就是在chrome://extension页面中,扩展名称下面的几个字
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;background&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; {&lt;span style=&#34;color:#75715e&#34;&gt;//background.js,整个扩展的运行,有个页面在后台运行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;scripts&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;js/function.js&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;bg.js&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;persistent&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;page_action&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;{&lt;span style=&#34;color:#75715e&#34;&gt;//比较常见有page_action和browser_action有,page会出现在地址栏末端,browser会在浏览器上显示一个图标
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;default_icon&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;icon-48.png&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;default_popup&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;popup.html&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#75715e&#34;&gt;//popup.html点击弹出的页面
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;default_title&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmcc520&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;permissions&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color:#75715e&#34;&gt;//申请内容脚本的权限,在插入内容到页面时,需要用哪些权限,此处必须声明
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;tabs&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http://\*/\*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;icons&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; {&lt;span style=&#34;color:#75715e&#34;&gt;//图标设置
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;48&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;icon-48.png&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;128&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;icon-128.png&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;commands&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; {&lt;span style=&#34;color:#75715e&#34;&gt;//快捷键设置
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;logout_cmcc&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;退出CMCC登录&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;suggested_key&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Alt+X&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;manifest_version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//manifest_version,现在版本1已经不支持,统一都写成2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;简单的属性,这里不再赘述,我重点说一下background,page_action,permissions和commands.&lt;/p&gt;
&lt;p&gt;background  它是一个包含扩展程序主要逻辑的不可见页面。扩展程序也可以包含其他页面，展现扩展程序的用户界面。如果扩展程序需要与用户加载的网页交互（相对于包含在扩展程序中的页面），扩展程序必须使用内容脚本。后台网页分两种：持续运行的后台网页与事件页面(设置persistent属性)。正如它们的名称所述，持续运行的后台网页保持打开状态，事件页面根据需要打开与关闭。除非您绝对需要您的后台网页一直运行，请首选事件页面。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;background&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; {&lt;span style=&#34;color:#75715e&#34;&gt;//background.js,整个扩展的运行,有个页面在后台运行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;scripts&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;js/function.js&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;bg.js&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;persistent&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;比如我的这个 后台执行就是这样的&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/images/20141124194616706.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;采用pageaction还是browseraction取决于你是否想让图标一直可见.`&lt;img src=&#34;https://blog.huirongis.me/images/20141124193151343.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;如图,绿色的是广告终结者,他的图标是pageAction,后面的印象笔记还有switchproxy是browserAction.一般来说,适用于少数页面的扩展建议使用pageaction,适用于大多数页面的建议使用browseraction&lt;/p&gt;
&lt;p&gt;permissions属性,用来设置和conten_script相关的选项,举个例子,如果你想插入一段代码到页面中去执行,操作页面上的dom,那就写个content_script就行了,使用 content_scripts 字段，扩展程序可以向一个页面中插入多个内容脚本，每个内容脚本可以有多个
JavaScript 和 CSS 文件,详细情况请看这里&lt;a class=&#34;link&#34; href=&#34;https://lmk123.duapp.com/extensions/content_scripts&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://lmk123.duapp.com/extensions/content_scripts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我现在在做的一个扩展就是做这样的事,百度的搜索结果会先跳到一个百度的网址,然后才是目标网址,我可以使用cotent_scripts来插入脚本,修改百度搜索结果的链接,让他直接跳转到目标页面,而不是百度的搜索结果页面.&lt;/p&gt;
&lt;p&gt;commands选项是设置快捷键,然后给快捷键设置事件 监听,这样我们按快捷键就会执行相应操作.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;logout_cmcc&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; {&lt;span style=&#34;color:#75715e&#34;&gt;//某个快捷操作的名称
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;退出CMCC登录&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#75715e&#34;&gt;//快捷操作的描述
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;suggested_key&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; {&lt;span style=&#34;color:#75715e&#34;&gt;//默认推荐的快捷键,不能与系统默认的快捷键冲突,否则就会失灵,需要用户手动去设置
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;                &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Alt+X&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
        </item>
        <item>
        <title>chrome扩展开发手记&lt;2&gt;-登录原理分析</title>
        <link>https://blog.huirongis.me/post/chrome-extention-2/</link>
        <pubDate>Mon, 24 Nov 2014 11:18:00 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/chrome-extention-2/</guid>
        <description>&lt;p&gt;上一篇,我们 介绍了一下登录的流程,但是用程序进行登录的话,我们肯定不能那样一步一步,太过复杂,所以我们接下来分下一下登录的具体过程,看看能不能作一些简化&lt;/p&gt;
&lt;p&gt;我们接下来,给几个页面编个号,下面好分析一点
A   最原始的跳转 &lt;a class=&#34;link&#34; href=&#34;http://120.202.164.10:8080/portal/?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=CMCC-EDU&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://120.202.164.10:8080/portal/?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=CMCC-EDU&lt;/a&gt;
B  第一次改ssid  &lt;a class=&#34;link&#34; href=&#34;http://120.202.164.10:8080/portal/?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=CMCC-EDU&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://120.202.164.10:8080/portal/?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=iWuhan-Free&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;C 第一次点击 请点击登录  以后的地址
&lt;a class=&#34;link&#34; href=&#34;http://120.202.164.10:8080/portal/loginFree.jsp?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=iWuhan-Free&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://120.202.164.10:8080/portal/loginFree.jsp?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=iWuhan-Free&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;D 第二次改ssid  
&lt;a class=&#34;link&#34; href=&#34;http://120.202.164.10:8080/portal/loginFree.jsp?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=iWuhan-Free&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://120.202.164.10:8080/portal/loginFree.jsp?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=CMCC520&lt;/a&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;从www.baidu.com跳转到A地址,这个步骤没什么特别的,服务器那边做了一个302跳转,然后我们这边就自动跳转到A地址了&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第一次改ssid,也就是从A到B,这个过程也没什么,只是一个单纯的地址跳转,B地址中有一个表单&lt;!-- raw HTML omitted --&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/20141124134725891.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;!-- raw HTML omitted --&gt;
这个表单里面 主要包含四个字段,
&lt;!-- raw HTML omitted --&gt;wlanacname:1022.0027.270.00
&lt;!-- raw HTML omitted --&gt;wlanuserip:10.80.97.209
ssid:iWuhan-Free
&lt;!-- raw HTML omitted --&gt;userAgent_1:Mozilla/5.0 (Windows NT 6.2)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我们第一次点击 请提交登录,所做的操作就是把上面的表单提交到  &lt;a class=&#34;link&#34; href=&#34;http://120.202.164.10:8080/portal/servlets/SingleLoginServlet&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://120.202.164.10:8080/portal/servlets/SingleLoginServlet&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;
服务器返回的地址是C,这一步的表单提交主要是为了获取C的地址,就是因为多了的那个loginFree.jsp,这样下一步才能改ssid为CMCC520,否则,如果你越过这一步直接改ssid为CMCC520,就会跳转到其他的页面,比如下面这个&lt;img src=&#34;https://blog.huirongis.me/images/20141124133708801.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;!-- raw HTML omitted --&gt;
这个地址如果点击提交,是没有办法正常登陆的,我们必须要到武汉的那个页面才行.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在我们到达C那个页面以后,我们再次修改ssid,就到了D页面,然后在D页面点击  请点击登录,流程和上面的一样,页面效果也是一样,不过表单的值变了一个,具体表单post内容如下
&lt;!-- raw HTML omitted --&gt;wlanacname:1022.0027.270.00
&lt;!-- raw HTML omitted --&gt;wlanuserip:10.80.97.209
ssid:CMCC520
userAgent_1:Mozilla/5.0 (Windows NT 6.2)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36&lt;!-- raw HTML omitted --&gt;
提交以后,我们就可以登录成功了,成功以后服务器会做一个302跳转,页面跳转到一个登录计时的页面.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;************************************************************************************************************************************************************
_&lt;!-- raw HTML omitted --&gt;
_
从整体来看,最核心的一个操作就是向&lt;a class=&#34;link&#34; href=&#34;http://120.202.164.10:8080/portal/servlets/SingleLoginServlet&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://120.202.164.10:8080/portal/servlets/SingleLoginServlet&lt;/a&gt;提交一个表单,表单内容是
wlanacname:1022.0027.270.00
wlanuserip:10.80.97.209
ssid:CMCC520
userAgent_1:Mozilla/5.0 (Windows NT 6.2)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36
然后,然后就没有然后了,那个最后计时页面的跳转没有多大的实际作用,我们只需要post这一个请求就好了
下一步我们开始制作chrome扩展,核心也是要实现这个post的请求
&lt;em&gt;************************************************************************************************************************************************************&lt;/em&gt;
&lt;em&gt;退出登录也是如此,发一个get请求过去,然后从获得的内容中进行判断,判断成功与否&lt;/em&gt;
__&lt;/p&gt;
&lt;p&gt;下线请求
&lt;a class=&#34;link&#34; href=&#34;http://120.202.164.10:8080/portal/servlets/LogoutServlet?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=CMCC520&amp;amp;ATTRIBUTE_USERNAME=iWuhanFree4300&amp;amp;ATTRIBUTE_UUID=26FBE9A694B6221958CF6DE2704F0ECA&amp;amp;ATTRIBUTE_IPADDRESS=10.80.97.209&amp;amp;cancelAutomatismLogin=false&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://120.202.164.10:8080/portal/servlets/LogoutServlet?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=CMCC520&amp;amp;ATTRIBUTE_USERNAME=iWuhanFree4300&amp;amp;ATTRIBUTE_UUID=26FBE9A694B6221958CF6DE2704F0ECA&amp;amp;ATTRIBUTE_IPADDRESS=10.80.97.209&amp;amp;cancelAutomatismLogin=false&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;表单实际内容&lt;/p&gt;
&lt;p&gt;wlanacname:1022.0027.270.00&lt;/p&gt;
&lt;p&gt;wlanuserip:10.80.97.209&lt;/p&gt;
&lt;p&gt;ssid:CMCC520&lt;/p&gt;
&lt;p&gt;ATTRIBUTE_USERNAME:iWuhanFree4300&lt;/p&gt;
&lt;p&gt;ATTRIBUTE_UUID:26FBE9A694B6221958CF6DE2704F0ECA&lt;/p&gt;
&lt;p&gt;ATTRIBUTE_IPADDRESS:10.80.97.209&lt;/p&gt;
&lt;p&gt;cancelAutomatismLogin:false&lt;/p&gt;
</description>
        </item>
        <item>
        <title>chrome扩展开发手记&lt;1&gt;-需求分析</title>
        <link>https://blog.huirongis.me/post/chrome-extention-1/</link>
        <pubDate>Fri, 21 Nov 2014 18:17:00 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/chrome-extention-1/</guid>
        <description>&lt;p&gt;本人的学校在武汉,有CMCC-EDU的网络覆盖,中国移动和武汉市政府搞了一个活动,可以免费公益上网,说白了,就是可以免费使用EDU的网络,如图.
&lt;img src=&#34;https://blog.huirongis.me/images/20141121181910580.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;以上是前提.&lt;/p&gt;
&lt;p&gt;这个网络的使用流程是这样子的.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;你打开任何一个网址,比如http://www.baidu.com  &lt;!-- raw HTML omitted --&gt;
都会跳转到 &lt;a class=&#34;link&#34; href=&#34;http://120.202.164.10:8080/portal/?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=CMCC-EDU&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;/a&gt;&lt;a class=&#34;link&#34; href=&#34;http://120.202.164.10:8080/portal/?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=CMCC-EDU&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://120.202.164.10:8080/portal/?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=CMCC-EDU&lt;/a&gt;  界面如图所示&lt;!-- raw HTML omitted --&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/20141124103645611.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/li&gt;
&lt;li&gt;接下来我们手动更改最上面的网址栏,把ssid改为iWuhan-Free,(注意大小写)&lt;!-- raw HTML omitted --&gt;
修改后的网址如下&lt;a class=&#34;link&#34; href=&#34;http://120.202.164.10:8080/portal/?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=CMCC-EDU&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://120.202.164.10:8080/portal/?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=iWuhan-Free&lt;/a&gt;界面如下&lt;!-- raw HTML omitted --&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/20141124104120281.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/li&gt;
&lt;li&gt;接下来我们点击,请点击登录按钮,系统反馈如下&lt;!-- raw HTML omitted --&gt;
&lt;img src=&#34;https://blog.huirongis.me/images/20141124104623968.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;!-- raw HTML omitted --&gt;
我们忽略这个警告,可以注意到,上面的地址栏已经变掉了,多了个loginFree.jsp完整的地址&lt;a class=&#34;link&#34; href=&#34;http://120.202.164.10:8080/portal/loginFree.jsp?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=iWuhan-Free&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://120.202.164.10:8080/portal/loginFree.jsp?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=iWuhan-Free&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;接下来,我们再改一次ssid,改为CMCC520,完整地址如下&lt;a class=&#34;link&#34; href=&#34;http://120.202.164.10:8080/portal/loginFree.jsp?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=iWuhan-Free&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://120.202.164.10:8080/portal/loginFree.jsp?wlanacname=1022.0027.270.00&amp;amp;wlanuserip=10.80.97.209&amp;amp;ssid=CMCC520&lt;/a&gt; 界面还是和上图一样,就不贴图了,我们再点击一次,请点击登录,然后就会跳到一个计时页面,这样就表示你登录成功,可以上网了&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;登录的流程走完了,下一篇,接下来我们分析一下登录的原理,简化一下登录的流程&lt;/p&gt;
</description>
        </item>
        <item>
        <title>wamp与sql_server_因为端口80冲突,无法开启wamp</title>
        <link>https://blog.huirongis.me/post/wamp-sql_server-80-error/</link>
        <pubDate>Fri, 14 Nov 2014 18:09:00 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/wamp-sql_server-80-error/</guid>
        <description>&lt;p&gt;因为80端口占用,导致无法启动,其实不必关闭sql server太多的东西,只需要关闭SQL Server Reporting Services 就行了,这样也不会影响sql server的使用&lt;/p&gt;
&lt;p&gt;如图
&lt;img src=&#34;https://blog.huirongis.me/images/20141114175909339.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;打开sqlserver 配置管理器,关闭以上服务&lt;/p&gt;
&lt;p&gt;或者打开控制面板-&amp;gt;管理-&amp;gt;服务工具-&amp;gt;SQL Server Reporting Services&lt;/p&gt;
&lt;p&gt;然后就可以打开wamp了&lt;/p&gt;
</description>
        </item>
        <item>
        <title>sql中left_join和right_join混用</title>
        <link>https://blog.huirongis.me/post/the-use-of-left_join-and-right_join-in-sql/</link>
        <pubDate>Fri, 08 Aug 2014 10:02:00 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/the-use-of-left_join-and-right_join-in-sql/</guid>
        <description>&lt;p&gt;left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 &lt;/p&gt;
&lt;p&gt;right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录&lt;/p&gt;
&lt;p&gt;inner join(等值连接) 只返回两个表中联结字段相等的行&lt;/p&gt;
&lt;p&gt;如上所言,我们只做一下left join的实验,right join和left join 类似&lt;/p&gt;
&lt;p&gt;测试一共三张表,a  b   c
&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;表结构和数据分别如下&lt;/p&gt;
&lt;p&gt;a表                                                                  b表                                                              c表
&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;         &lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;          &lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;然后我们来试一下左连接&lt;/p&gt;
&lt;p&gt;1,  我们来查询a b两张表,连接他们aid=bid的选项
sql&amp;raquo;SELECT *  FROM a   LEFT JOIN b on aid=bid&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;看图很好理解,因为是a左连接b,所以b中为空的元素 ,在查询结果中以NULL的形式补全&lt;/p&gt;
&lt;p&gt;同理可得&lt;/p&gt;
&lt;p&gt;sql&amp;raquo;SELECT * FROM a LEFT JOIN c on aid=cid
&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;sql&amp;raquo;SELECT * FROM c LEFT JOIN b on bid=cid
sql&amp;raquo;SELECT * FROM c LEFT JOIN b on cid=bid&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;也就是on后面的顺序无所谓,无论是bid=cid还是cid=bid,重点是前面的left join还是right join&lt;/p&gt;
&lt;p&gt;2,我们来试一下如果三张表左连接呢,会有什么情况?&lt;/p&gt;
&lt;p&gt;sql&amp;raquo;SELECT * FROM a&lt;/p&gt;
&lt;p&gt;           LEFT JOIN b on bid=aid &lt;/p&gt;
&lt;p&gt;           LEFT JOIN c on aid=cid
&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;sql&amp;raquo;SELECT * FROM a LEFT JOIN b on bid=aid LEFT JOIN c on bid=cid
&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;3,如果我用了一个right join呢?&lt;/p&gt;
&lt;p&gt;sql&amp;raquo;SELECT * FROM a LEFT JOIN b on bid=aid RIGHT JOIN c on bid=cid
&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;这里该怎么理解呢?
感谢&lt;a class=&#34;link&#34; href=&#34;http://blog.csdn.net/sqlserverdiscovery/article/details/6893288&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://blog.csdn.net/sqlserverdiscovery/article/details/6893288&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我们理解的时候可以把它拆成两部分去理解&lt;/p&gt;
&lt;p&gt;比如第一部分
sql&amp;raquo;SELECT * FROM a LEFT JOIN b on bid=aid&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;然后再思考第二部分,假如上图是一张表  我们叫它a_b&lt;/p&gt;
&lt;p&gt;你可以新建一个视图,就可以真成为一张虚表了&lt;/p&gt;
&lt;p&gt;sql&amp;raquo;create  VIEW a_b  as (SELECT * FROM a LEFT JOIN b on bid=aid)
&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;然后我们继续做下面一部分&lt;/p&gt;
&lt;p&gt;sql&amp;raquo;select * from a_b right join c on bid=cid
&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;可见,与上面的结果是一样的,当然这是我们理解的过程,实际数据库服务器执行的时候可能不是这样的,它会做一些优化,提高效率&lt;/p&gt;
</description>
        </item>
        <item>
        <title>阿里云windows_server_2003_搭建邮件服务器</title>
        <link>https://blog.huirongis.me/post/aliyun-windows-server-2008-mail-server/</link>
        <pubDate>Sat, 28 Jun 2014 22:30:00 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/post/aliyun-windows-server-2008-mail-server/</guid>
        <description>&lt;p&gt;    笔者最近遇到一个在阿里云上搭建邮件服务器的问题，总算搞定，记录一下。&lt;/p&gt;
&lt;p&gt;     整个搭建过程，包括pop3服务的安装和开启，smtp服务的安装和开启，dns服务的安装和设置。
    参考文章&lt;a class=&#34;link&#34; href=&#34;http://hi.baidu.com/senya/item/63bd6588b6817056e63d1996&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://hi.baidu.com/senya/item/63bd6588b6817056e63d1996&lt;/a&gt;
   &lt;a class=&#34;link&#34; href=&#34;http://firefish.blog.51cto.com/298258/57983&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://firefish.blog.51cto.com/298258/57983&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;不在赘述，直接粘贴原文&lt;/p&gt;
&lt;p&gt;__　　一、安装Windows Server 2003邮件服务器组件__&lt;/p&gt;
&lt;p&gt;(因为盗图的缘故,图片都挂了,这里大家都去看上面的参考文章连接吧,设置dns的时候再回来)&lt;/p&gt;
&lt;p&gt;图一　“管理您的服务器”控制台&lt;/p&gt;
&lt;p&gt;　　依次单击“开始”——“管理工具”——“管理您的服务器”，打开“管理您的服务器”控制台。在这个管理控制台中我们可以看到服务器已经成为的角色。单击“添加或删除角色”命令，开始管理服务器的角色。&lt;/p&gt;
&lt;p&gt;图二　配置服务器向导&lt;/p&gt;
&lt;p&gt;　　当我们单击“添加或删除角色”命令，就会运行配置服务器向导。&lt;/p&gt;
&lt;p&gt;图三　服务器管理程序检测网络连接&lt;/p&gt;
&lt;p&gt;图四　管理服务器角色&lt;/p&gt;
&lt;p&gt;　　在图四中，可以查看已经安装的服务和支持而没有安装的服务。此时的服务器还不是邮件服务器，选择“邮件服务器(POP3,SMTP)”，单击“下一步”：&lt;/p&gt;
&lt;p&gt;图五　配置“身份验证方法”及“电子邮件域名”&lt;/p&gt;
&lt;p&gt;图六　单击“下一步”&lt;/p&gt;
&lt;p&gt;图七　安装邮件服务:POP3和SMTP&lt;/p&gt;
&lt;p&gt;图八　安装成功&lt;/p&gt;
&lt;p&gt;__　　二、管理邮件服务器__&lt;/p&gt;
&lt;p&gt;　　Windows Server 2003的电子邮件服务器的功能很简单，管理界面也很简洁。单击“管理工具”下的“POP3服务”：&lt;/p&gt;
&lt;p&gt;图九 POP3服务&lt;/p&gt;
&lt;p&gt;图十　为用户添加邮箱&lt;/p&gt;
&lt;p&gt;　　在“POP3服务”中单击“添加邮箱”命令，在弹出的对话框内输入邮箱名（用户名）及密码。&lt;/p&gt;
&lt;p&gt;图十一&lt;/p&gt;
&lt;p&gt;__　　三、配置smtp__&lt;/p&gt;
&lt;p&gt;　　方法和上面类似，在图二的画面中我们选择应用程序服务器&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;如图，我的已经开启了。&lt;/p&gt;
&lt;p&gt;下一步，依次打开“开始-程序-管理工具-internet信息服务”，在窗口左面，鼠标右键点击“smtp虚拟服务器”属性。切换到常规选项卡”IP地址“选择服务器的ip地址，点击确定就行了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;四、配置DNS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;服务器已经配置好了，我们接下来设置下dns，这样才能解析到，不然还是无法使用的&lt;/p&gt;
&lt;p&gt;依次打开，“开始-程序-管理工具-配置您的服务器向导”&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;选择自定义配置&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;选择dns服务器，下一步&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;点击正向查找域里面的区域名称，在右边的空白处点击右键，新建主机，分别新建POP3，smtp等主机&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;还是空白处，右键，新建邮件交换器，分别新建smtp和pop3的邮件交换器&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.huirongis.me/&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;注意：完全合格的域名后面没有点号，邮件服务器的完全合格的域名后面有点号，例如是smtp.ip-tcp.com.&lt;/p&gt;
&lt;p&gt;到此，邮件服务器搭建完成，可以去测试了&lt;/p&gt;
&lt;p&gt;此处参考原文&lt;a class=&#34;link&#34; href=&#34;http://www.docin.com/p-156566941.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://www.docin.com/p-156566941.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;经过我的测试，可以收邮件，但是不能发邮件（可以自己给自己发，但是不能给qq，网易等邮箱发），一直报错550 5.7.1 Unable to relay for &lt;a class=&#34;link&#34; href=&#34;mailto:xxx@xxx.com&#34; &gt;&lt;/a&gt;&lt;a class=&#34;link&#34; href=&#34;mailto:xxx@xxx.com&#34; &gt;xxx@xxx.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;最后找到答案&lt;/p&gt;
&lt;p&gt;在IIS管理器里打开“默认SMTP虚拟服务器”的属性设置对话框，在“访问”选项卡中，点击“中继”按钮，弹出“中继限制”对话框，默认为选中了“仅以下列表”，修改为选中“仅以下列表除外”即可。&lt;/p&gt;
&lt;p&gt;另外下面的“允许所有通过身份验证的计算机进行中继，而忽略上表”一项要保持选中状态（默认是选中的）。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Search</title>
        <link>https://blog.huirongis.me/page/search/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/page/search/</guid>
        <description></description>
        </item>
        <item>
        <title>隐私政策</title>
        <link>https://blog.huirongis.me/page/privacy/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://blog.huirongis.me/page/privacy/</guid>
        <description>&lt;p&gt;本站是一个个人技术博客，主要记录 Home Assistant、智能家居和开发相关的内容。这份说明只讲两件事：本站收集什么、第三方会拿到什么。&lt;/p&gt;
&lt;h2 id=&#34;本站自己收集的信息&#34;&gt;本站自己收集的信息
&lt;/h2&gt;&lt;p&gt;本站是静态站点，没有注册、登录、评论账号体系，也没有自建的数据库。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;访问日志&lt;/strong&gt;：站点由 GitHub Pages 托管，前面有 Cloudflare 做解析和缓存。IP 地址、浏览器标识这类请求信息会由这两家服务按各自的策略记录，本站不单独保存。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;评论&lt;/strong&gt;：文章评论使用 giscus，数据存放在 GitHub Discussions。你在那里留下的内容受 GitHub 的隐私政策约束。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;搜索&lt;/strong&gt;：站内搜索在浏览器本地完成，搜索词不发送到任何服务器。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;第三方广告&#34;&gt;第三方广告
&lt;/h2&gt;&lt;p&gt;本站使用 Google AdSense 展示广告。Google 及其合作伙伴可能会：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用 Cookie 或类似技术，根据你此前访问本站及其他站点的记录投放个性化广告；&lt;/li&gt;
&lt;li&gt;收集与广告展示、点击相关的设备信息和使用数据，用于统计和计费。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你可以通过 &lt;a class=&#34;link&#34; href=&#34;https://adssettings.google.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google 广告设置&lt;/a&gt; 关闭个性化广告，或访问 &lt;a class=&#34;link&#34; href=&#34;https://www.aboutads.info/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;aboutads.info&lt;/a&gt; 了解如何停用第三方广告商的 Cookie。关闭个性化广告后你仍会看到广告，只是不再基于你的兴趣。&lt;/p&gt;
&lt;p&gt;如果你所在地区适用《通用数据保护条例》（GDPR）或类似法规，你可以要求了解、更正或删除与你相关的数据。由于本站不保存个人信息，这类请求通常需要向 Google 提出。&lt;/p&gt;
&lt;h2 id=&#34;外部链接&#34;&gt;外部链接
&lt;/h2&gt;&lt;p&gt;文章里可能链接到其他网站。点开后你就在对方的隐私政策管辖范围内了，本站无法控制。&lt;/p&gt;
&lt;h2 id=&#34;变更&#34;&gt;变更
&lt;/h2&gt;&lt;p&gt;这份说明如果调整，会直接更新本页面，不另行通知。&lt;/p&gt;
&lt;p&gt;最后更新：2026-11-09&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
