网址规范化一直是困扰站长以及搜索引擎的一个问题。据估计,网上有10%-30%的URL是内容相同但URL不一样的不规范化网址。

这就造成几个问题。比如:

对站长来说,多个URL存在分散了页面权重,不利于排名。
对搜索引擎来说,浪费资源,浪费带宽。
搜索引擎发现多个网址内容相同时,不会惩罚,而会尽可能找出那个应该是规范化的网址。但程序毕竟只是程序,可能出错,挑出来的可能不是站长想要的那个规范化网址。
网站上网址规范化问题太严重的话,也可能影响收录。一个权重不很高的域名,能收录的总页面数字是有限的。搜索引擎把资源花在收录不规范的网址上,留下给真正不同内容的资源就减少了。

要解决URL规范化问题也有很多选项,比如:

在Google管理员工具中设置带3W和不带3W的,哪一个是规范化版本
使用301转向,把不规范化URL全部转向到规范化URL
确保使用的CMS系统只产生规范化网址
确保网站上所有站内链接都指向规范化网址
在提交给搜索引擎的网站地图中全部指定规范化网址

但这些方法都各有局限。

Google管理员工具不适用于其他搜索引擎
有的站长因为某种原因做不了301转向
CMS系统大部分情况下不受自己控制
内部链接自己可以控制,但其他人链接到自己网站上就不受控制了

总之,虽然有解决方法备选,但网址规范化到目前为止还是个不小的问题。

前几天Google,雅虎,微软共同发布了一个新的标签canonical tag,用于解决网址规范化问题。

简单说,就是在HTML文件的头部加上这样一段代码:

<link rel=”canonical” href=”http://www.example.com/product.php?item=swedish-fish” />

意义就是这个网页的规范化网址应该是:

http://www.example.com/product.php?item=swedish-fish

下面这些URL都可以加上这段代码:

http://www.example.com/product.php?item=swedish-fish&category=gummy-candy

http://www.example.com/product.php?item=swedish-fish&trackingid=1234&sessionid=5678

这些URL的真正规范化网址就都成为:

http://www.example.com/product.php?item=swedish-fish

简单说,这个标签相当是一个页面内的301转向。区别在于用户并不被转向,还是停留在不变网址上,而搜索引擎会把它当作是301转向处理,也就是说把页面链接的权重都集中到代码中指明的规范化网址上。

另外有几个细节站长需要注意:

这个标签只是一种建议或暗示,而不是指令,它不像robots文件那样是个指令。所以搜索引擎会很大程度上考虑这个代码,但并不是百分之百,还会考虑其他情况来判断规范化网址。这也防止站长有可能把网址弄错。
这段代码既可以使用绝对地址,也可以使用相对地址。通常还是建议使用绝对地址比较保险。
指定的规范化网址上的内容,与其他使用这段代码的非规范化网址内容可以有一些不同,不一定完全一样。比如在电子商务网站上有很多按价钱、颜色,、尺寸升降排序,生成的URL全都不一样,但内容大体相同,只有细小区别,就可以使用这个标签。
指定的规范化网址可以是不存在页面,返回404,也可以是还没有被收录的页面。但是不建议这么做,别没事找事。
这个标签适用于同一个域名内,包括二级域名。但不适用于不同域名之间,防止有人劫持。
别把这个标签当救命草,首先还是得把网站结构做好,尽量避免出现URL规范化问题。这只是最后万不得已的方法。

敏感的人大概能从这个新标准里看到建立大量外部链接的机会。

最后提一句,这个标准被3大搜索引擎Google,雅虎,微软同时支持。

遵循良好的编码风格,可以有效的提高代码的可读性,降低出错几率和维护难度。在团队开发中,使用(尽量)统一的编码风格,还可以降低沟通成本。

网上有很多版本的编码规范,基本上都是遵循 PEP8 的规范:

PEP 0008 – Style Guide for Python Code
Google 的 Python 风格指南
Python Guide - Code Style
Pocoo Styleguide

不要使用 tab 缩进
使用任何编辑器写 Python,请把一个 tab 展开为 4 个空格
绝对不要混用 tab 和空格,否则容易出现 IndentationError

命名

使用有意义的,英文单词或词组,绝对不要使用汉语拼音
package/module 名中不要出现 -

import

  • 所有 import 尽量放在文件开头,在 docstring 下面,其他变量定义的上面
  • 不要使用 from foo imort *
  • import 需要分组,每组之间一个空行,每个分组内的顺序尽量采用字典序,分组顺序是:

    • 标准库
    • 第三方库
    • 本项目的 package 和 module
    • 不要使用隐式的相对导入(implicit relative imports),可是使用显示的相对导入(explicit relative imports),如 from ..utils import validator,最好使用全路径导入(absolute imports)
  • 对于不同的 package,一个 import 单独一行,同一个 package/module 下的内容可以写一起:
  • 为了避免可能出现的命名冲突,可以使用 as 或导入上一级命名空间
  • 不要出现循环导入(cyclic import)

注释

  • 文档字符串 docstring, 是 package, module, class, method, function 级别的注释,可以通过 doc 成员访问到,注释内容在一对 """ 符号之间
  • function, method 的文档字符串应当描述其功能、输入参数、返回值,如果有复杂的算法和实现,也需要写清楚
  • 不要写错误的注释,不要无谓的注释
  • 优先使用英文写注释,英文不好全部写中文,否则更加看不懂

异常

  • 不要轻易使用 try/except
  • except 后面需要指定捕捉的异常,裸露的 except 会捕捉所有异常,意味着会隐藏潜在的问题
  • 可以有多个 except 语句,捕捉多种异常,分别做异常处理
  • 使用 finally 子句来处理一些收尾操作
  • try/except 里的内容不要太多,只在可能抛出异常的地方使用,如:
  • 从 Exception 而不是 BaseException 继承自定义的异常类

Class(类)

  • 显示的写明父类,如果不是继承自别的类,就继承自 object 类
  • 使用 super 调用父类的方法
  • 支持多继承,即同时有多个父类,建议使用 Mixin

字符串

  • 使用字符串的 join 方法拼接字符串
  • 使用字符串类型的方法,而不是 string 模块的方法
  • 使用 startswith 和 endswith 方法比较前缀和后缀
  • 使用 format 方法格式化字符串

比较

  • 空的 list, str, tuple, set, dict 和 0, 0.0, None 都是 False
  • 使用 if some_list 而不是 if len(some_list) 判断某个 list 是否为空,其他类型同理
  • 使用 is 和 is not 与单例(如 None)进行比较,而不是用 == 和 !=
  • 使用 if a is not None 而不是 if not a is None
  • 用 isinstance 而不是 type 判断类型
  • 不要用 == 和 != 与 True 和 False 比较(除非有特殊情况,如在 sqlalchemy 中可能用到)
  • 使用 in 操作:
# bad
if d.has_key(k):
    do_something()

# good
if k in d:
    do_something()
  • 用 set 加速 “存在性” 检查,list 的查找是线性的,复杂度 O(n),set 底层是 hash table, 复杂度 O(1),但用 set 需要比 list 更多内存空间

其他

  • 使用列表表达式(list comprehension),字典表达式(dict comprehension, Python 2.7+) 和生成器(generator)
  • dict 的 get 方法可以指定默认值,但有些时候应该用 [] 操作,使得可以抛出 KeyError
  • 使用 for item in list 迭代 list, for index, item in enumerate(list) 迭代 list 并获取下标
  • 使用内建函数 sorted 和 list.sort 进行排序
  • 适量使用 map, reduce, filter 和 lambda,使用内建的 all, any 处理多个条件的判断
  • 使用 defaultdict (Python 2.5+), Counter(Python 2.7+) 等 “冷门” 但好用的标准库算法和数据结构
  • 使用装饰器(decorator)
  • 使用 with 语句处理上下文
  • 有些时候不要对类型做太过严格的限制,利用 Python 的鸭子类型(Duck Type)特性
  • 使用 logging 记录日志,配置好格式和级别
  • 了解 Python 的 Magic Method:A Guide to Python’s Magic Methods, Python 魔术方法指南
  • 阅读优秀的开源代码,如 Flask 框架, Requests for Humans
  • 不要重复造轮子,查看标准库、PyPi、Github、Google 等使用现有的优秀的解决方案

临时修改

  • 查看网卡信息
ifconfig

该命令会打印出所有的网卡信息, 根据打印出的信息, 找到需要设置的网卡进行设置。

  • 临时设置网卡 mtu
ifconfig eth0 mtu 9000
  • 检查效果
    使用 ifconfig eth0 命令, 根据打印出的信息, 查看修改的效果。

永久的修改

修改配置文件 /etc/network/interfaces ,增加一行, 保存退出

mtu 1280
  • 重启网络
/etc/init.d/networking restart
  • 查看效果
ifconfig eth0

相关资料

当使用 MYSQL-python 库的时候, 遇到这个错误:

ImportError: libmysqlclient.so.20: cannot open shared object file: No such file or directory

原因是缺少 libmysqlclient-dev 这个库:

sudo apt-get install libmysqlclient-dev

安装一下就好了, 网上有卸载并重装 MYSQL-python 库的说法, 并不靠谱。