OS X 多个 Python 优雅共存

首先解决了一个 Pyenv 多版本共存的问题,之前要么用 Python2.7 要么用最新版的 Python,现在怀疑是 Python3.5 导致的问题,所以要用 Pyenv 装一个多Python的环境。

在 OS X 上面安装 Pyenv 非常简单:

用 Pyenv 下载一个新的Python:

无奈公司的网络实在太差,卡在 Downloading 那一步很久都下载不完,只要自己挂代理下载下来然后从本地安装:

可以看到 Pyenv 里面已经新加了一个可执行的Python了(Pyenv挺有意思的,有兴趣的可以去看看它的原理):

这个使用 virualenv 创建 Python 的虚拟环境也可以用指定的 Python 版本:


好了,折腾这么一顿,实际上是想试一下今天遇到的一个诡异Bug, Python3.5 的 json 传进去 bytes 就挂了。

好吧,看来 Python3.6 之前确实不支持对 bytes 直接 load() 。

文档都写着的嘛……

PS: 今天发现 Python 官方网站有了交互式的 shell (也许很久就有了),是接入的 www.pythonanywhere.com 支持各种版本的 Python,很好用:

 

奇葩网站吐槽第四弹

这个周开始,爬虫的工作应该会告一段落了,《奇葩网站吐槽》系列全四弹也算截止了,enjoy!

前期回顾:

  1. 吐槽一些神奇的政府网站
  2. 奇葩网站吐槽第二弹
  3. 奇葩网站吐槽第三弹

本期内容:

20171207 这是12小时制还是24小时制?

20171213 遇到一个网站,带有很多参数,经过发送请求发现有些是固定的,是我要抓的页面定位的参数,有一些是改变的(很迷,甚至要通过不断向服务器发送一个时间戳保存session的生命),终于写好爬虫之后,过了几天发现这个爬虫没有工作!仔细观察发现,有些参数是按天变的……


这…… json请求有必要吗?而且这i18n……


20171225:第一次见可以带两个//的url……


20171228 老哥你这SEO不走心啊

网站介绍很朋克

keyword也很朋克


2018年1月5日更:大哥你这个“19月”可坑死我了……


2018年4月3日更新:今天发现一个网页返回的内容变了,不应该啊,打开一看,原来的 url 返回的内容变成了:

JS重定向到 index.html 首页?打开首页一看,首页原来是 HTTP 的,现在重定向到了 HTTPS (还是302状态码,槽点太多了)。

好嘛,用 JS 作 HTTPS 重定向的还是第一次见。


2018年4月10日更新:这网站日期最远的内容排在第一页,今天的内容排在最后一页。所谓“倒序排列”?

第一页只有年底的内容。

最后一页竟然是今天的内容。

 

使用brew升级Python之后修复virtualenv和pipsi

brew 升级和执行 brew cleanup 之后 Python virtualenv 的路径总是出问题,今天算是把问题找到了,但是却没找到好的解决办法…… 最终的解决方案是将所有的 virtualenv 删除重装。急着修复问题的可以不看中间的尝试直接拉到最下面。

以其中一个虚拟环境为例:

可以看到之前有一个 .Python 文件是软链接到 brew 安装的 Python3 的,以这次升级为例,3.6.4_4 这个版本已经不存在了,目前有的是 /usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/bin/python3.6 ,本打算将新的路径作为 .Python 的软连接:

但发现现在 pylint 是可以执行了,但是找不到依赖的包,于是又写了一个脚本,打算找到其所有的软连接,全都链接到最新的 3.6.5 版本中:

发现执行完之后还是找不到相关的包:

没办法,先重新建一下 virtualenv 吧,以前是这样处理的,应该也是最稳的方法了。

重新安装 pipsi 列表

我的 Python 命令行工具是用 pipsi 安装的,这个工具和 pip 的不同是: 它不会把模块装到系统 Python 而是每一个包新建一个 virtualenv ,然后在这个 virtualenv 中安装,然后链接 bin 的 Path。将所有 pipsi 安装的工具重装的命令如下:

pipsi list | grep -Eo ‘”(.*)”‘ | cut -c2- |rev | cut -c2- | rev | xargs -I {} — zsh -c ‘pipsi uninstall {} –yes ; pipsi install –python python3 {}|| pipsi install {}’

解释如下(按照颜色匹配):

  1. 打印出所有package,比如 “pylint”
  2. 砍掉第一个双引号,翻转,砍掉第一个双引号,再翻转(实际上就是去掉双引号)
  3. 将前面得到的干净包名传给下面的子命令,其中 {} 将被替换成包名
  4. 先卸载,再尝试用 python3 安装,如果失败改用 python2 安装

pipsi 的包就重建好了。virtualenv 里面的工作用的 env 自动重建了没什么意义,因为各个 env 的依赖都是根据项目的 requirements.txt 安装好的。还是用到什么再次重建什么吧。

 

搭建自己的静态 Wiki 站点(Vimwiki+Pages)

以前整理自己的东西都是用印象笔记,槽点太多了,比如只支持1级目录,列表页不友好等,整理起来很不方便。最近发现了 Vimwiki 这个好东西,于是想出另一种策略:

  1. 用 Vim 撰写个人 wiki (Vim 是我最喜欢的编辑器,第二喜欢的是 WordPress 后台编辑器)
  2. 用 git 追踪变更记录,每次写入的时候自动追加 commit 信息 (这样自己完全可以不用关心备份了)
  3. 用 Github pages 来托管 html (静态网站托管无比简单,写 wiki 就是为了方便查阅,如果再耗费很多精力去运维就得不偿失了)

1.新的 Github 账户

我的 Github 账号的 Pages 已经托管了一些小玩意,所以另申请了一个账号,专门用来记录 wiki。用新账号新建一个 Pages 并将主账号加入到合作者,这样 key、邮箱都不用再另外配置了。

自己邀请自己还有点奇怪

然后新账号就可以丢掉了,以后全部用自己的主账号操作。

接下来配置 Vim 和 Vimwiki。

2.安装和配置

毕竟是一个很老的项目,提供了各种 Vim 包管理工具的安装方式。可以通过 Readme 的信息选择你喜欢的方式安装。

然后 clone 下来我的 Pages 仓库,创建 wiki 文件夹存放源文件,创建 html 文件夹来保存生成的 html 文件。

.vimrc 中加入如下配置,设置 Vimwiki 的路径:

然后在 Vim 中按下 <leader>ww 就可以看到一个新创建好的 index.wiki Buffer 了。

随便写点什么保存,然后在 Vim 中执行 :Vimwiki2HTML 就可以将 wiki 文件编译成 html。然后将其 push 到 Github 上,就可以在线上看到这个页面了。

可以写一个 Makefile 自动化发布的过程。

这样只要运行 make publish 命令,就会自动构建最新的 Wiki 并发布到 Pages 上。

3.自定义域名

静态托管简直太爽,我相信 Pages 在我有生之年不会倒闭,但是为了以防万一,还是使用自己的域名,这样将来万一要切换,也会很方便,直接改下 DNS 解析位置就好了。首先添加一个 CNAME 文件让 Pages 跳转到我自己的域名: echo "wiki.kawabangga.com" > CNAME 然后 PUSH 上去就可以了。然后再到自己的域名服务商那里添加一个 CNAME 指向 laixintao-wikibot.github.io 。等解析生效就可以通过 wiki.kawabangga.com 访问了。

到这里就差不多搭建起来了,接下来就是熟悉一下 WIKI 的语法、学下 Vimwiki 的快捷键使用。另外默认的 template 太丑了,就是一个基本的 html,有时间的话还要在网上找找有没有漂亮点的 theme。

 

参考资料:

  1. 使用 Vimwiki + git 做知识管理
  2. http://kwiki.github.io/tips/vim/vimwiki-guide.html
 

Vim文件编码处理和重新打开乱码文件

Vim 中有两个与编码有关的变量,如果理解了基本就不会再为编码问题头疼了。

  • encoding :Vim 内部编码,例如 buffer、寄存器、文本等。这个值一般用户不要设置,另外打开 Vim 之后再设置这个值也是没有意义的。大家可以将这个值看作是 Vim 程序自己的变量,如果在工作中遇到文件的编码问题,和 encoding 这个变量是万万没有关系的。
  • fileencoding :顾名思义了,就是文件的编码。

此外还有一个值,叫 fileencodings 是个复数。一般我们将这个值在 vimrc 中设置,Vim 打开一个文件的时候回根据 fileencodings 里面设置的顺序来猜测文件的编码。比如这样设置:

那么有时候 Vim 猜错了,打开的文件显示乱码怎么办呢?(ps:通常 Vim 打开文件的时候乱码是因为你的 fileencodings 里面没有写某个编码,所以 Vim 没有猜对。例如从上面的设置中删掉 gb18030 ,那么打开这种编码的文件的时候你会发现 fileencoding 的值是 latin1 ,而文件的显示是乱码)

这时候你可能想到设置 fileencoding 的值,但是此时我们的文件已经打开了,你设置后会发现 Vim buffer 的状态变成了 Edited 。而文件依然显示乱码,没有变化。具体的原因后文会详细解释。

正确的做法是以特定编码重新打开文件,例如在 Vim 中使用重新打开命令 :e ++enc=gb2312 ,其中 ++enc 是一个选项,可以指定使用的编码。打开后你会发现 Vim 按照你指定的形式打开了文件,但是文件变成了 readonly 状态,如果要修改,设置 :set noreadonly 就好。

其实原理有点像 Python 里面有人提出的三明治模型

Python 在从流(例如网络, 文件 I/O 的时候),拿到的是 bytes ,通过 decode() 变成 str 而 Vim 在读入一个文件的时候,根据 fileencoding (用户设置的或者通过 fileencodings 猜测,将其转换成内部 encoding 的编码方式。

Python 在写入文件的时候,用 encode() 变成 bytes 再写。而 Vim 从 buffer 写到文件的时候,也是将数据从内部的 encoding 转换成 fileencoding 再写入。

这也就解释了为什么乱码的时候在 Vim 中修改 fileencoding 没什么卵用。

因为在打开文件之后设置 fileencoding 的值不会改变已经载入到 Vim buffer 中的数据,此时的数据已经是转换完成了的,这个设置只会改变写入的时候使用目前的 fileencoding 来写入,所以总结起来就是“打开文件使用了一个编码,写入文件的时候使用了另一个编码”。

而对乱码正确的需求应该是:我想要以特定的编码形式打开这个文件。

参考:

  1. help :edit
  2. help fileencoding
  3. help ++enc
  4. VIM 文件编码识别与乱码处理