按 ‘ 微博 ’ 标签归档

打僵尸大捷报告会

这是一篇迟到的总结,其实今年2月就已经赢了的。写这个总结是为了详解打僵尸程序的进化过程,帮大家看懂它的战术和走位。

众所周知,渣浪微博的僵尸化很严重,并且渣浪无计可施。很多人以为“微博反垃圾”有用(起初我也这么以为),但微博反垃圾这样解释自己的功能:

也就是说,当某用户被举报封号时,渣浪并不会及时清理它和正常用户的关注/被粉关系,直到该用户手动修正粉丝为止(并且只修好他自己的)。其实这是把流程缺失的责任转嫁到用户身上。并且,从这个解释来看,让绝大多数人头疼的僵尸粉,在渣浪眼里是正常用户:不说话当然不会被举报封号啦。

第一次使用微博反垃圾的,会很欣喜,因为立竿见影,一下子粉丝数就降下来了。那是当然,堆积N年的陈年老尸,被火化时肯定狼烟滚滚。但再使用时,它只能帮着清掉从上次大扫除以来积累的垃圾,效果就会令人失望了。

所以我决定自己搞定这件事。从去年11月开始,用Python语言写了个程序,中间随着战斗局势变化,修改几回。大约到了12月中,程序功能基本上就是今天的样子了。

我把僵尸粉分为这样三种:

  • 经典僵尸,就是简单地沉默寡言。
  • 打榜僵尸,“They were once men.” 结群抱团滚滚而来,发博量如超新星爆发。爱豆活动一结束,立即坍缩成黑洞。爆发时显得脑残,坍缩后更像垃圾。
  • 自语僵尸,程控喃喃自语,诉说爱情痛楚和人生感悟,每天一两次,莫名瘆人。这也是目前卖粉的主打产品。

对这三种僵尸的识别处理,是推进程序的主要动力。下面细说程序的演化过程。

首先说说起始状态。一个被僵尸粉占据的帐户,其粉丝列表大约是这样的结构:

被僵尸攻陷的粉丝列表,数字是页数

图中,红色代表僵尸,蓝色代表正常粉丝,灰色代表250页之后、被渣浪隐藏的粉丝列表(可以想象,其中的僵尸依然是多数)。数字是粉丝列表的页数。渣浪的规则:即使看自己的粉丝列表,也只能看至多250页,每页20个(即最多5000个)。假如看别人的,则最多只能看5页(100个)。

我们期待的理想健康状态,当然是下图这样的,红色泡沫被挤空,蓝色真粉致密地聚集在一起:

健康状态的粉丝列表

知道了自己在哪儿,目标在何方,就可以着手制订路线,准备工具。

最初考虑的是渣浪自己的微博API——它自己家的东西嘛,用起来肯定最趁手。但仔细阅读其功能后就会发现,根本没有删除粉丝的接口(曾经有,后来撤了,让人高度怀疑,僵尸粉都是渣浪自己喂养释放的)。

那就只能自备工具了,我使用早有成熟功能库的Python + Selenium。

和网络相关的编程,最简单直接的操作是“访问链接”,于是,可行性预研从这个办法入手。经过调研发现,“访问1个链接就能删除1个粉丝”的功能,在手机浏览器彩版微博(不是手机客户端)可以实现,但彩版微博最多只给看1000个粉丝。

所以程序最初分为两节:第一节从网页版微博抓取粉丝列表(至多5000个),分析僵尸后写进数据库。第二节读取数据库,把标记为僵尸的,通过访问彩版微博删除。删除之后,前250页留下的空位,会从原本隐藏的地方(上面图中所示灰区)抽调名额填补,这样就又可以循环以上过程,轮转不已。

这个方法确实有用,帮着我删除了最初一两千个。还让我发现,刷页不能过快,否则会被微博拒访几分钟。最初的删除速度,可以点这里了解,但此视频的续集就是几分钟的空白页面,飞速删除所节省的时间全赔进去了。从此,大约两秒1个的“稳健”速度一直保持到最新版。认为这个程序不够快的用户,读到这里应该能理解了。

接下来,我开始对程序的分节运行感到不爽。眼前分明一群僵尸,却要等几十分钟后才能看到它们被删除。更重要的是,抓取和删除间隔久远,谁冤枉了,谁漏网了,根本对不上号。所以我开始做即见即删的版本,看到僵尸就立刻操纵鼠标去打开菜单,点删除按钮,不再攒到一起秋后问斩了。

拉菜单点按钮敲回车的操作当然要比访问链接复杂得多,幸好Python + Selenium的功能还挺齐全,很快就搞定了改写工作。

最初程序分两节运行时,只要能把粉丝列表逐页看完就行, 正着看倒着看并不重要 。但到了即见即删的阶段,访问顺序就变得很重要。即见即删的第一版继承了正向浏览的基础,那时的工作方法是:浏览第1页,删除本页上的僵尸,腾出空位来了,刷新本页,把原在第2页的粉丝填上来几个,再删再刷,直到本页全是活粉,再挪到第2页如法炮制。

说真的,假如不考虑效率的话,这个操作过程比现在的版本还花样繁多,令人沉迷,每次运行时我都能盯着看很久。也正是因为看很久,看出问题了:20个位置,前19个都坐满了活粉,只剩1个空位时,程序还不屈不挠地刷呀删呀,每刷只能删1个,太弱智了。

于是做了个改写,每次从250页逆行到第1页,刷完删完不停留,继续上行。这样每次看到的都是新面孔。当有僵尸从第1页正门持续涌入时,逆流而上更是所见常新。程序朴实了,却变得高效。

读到这里,用户应该明白为何程序总是从后往前扫了。至于每次开始程序总是先看第1页,那是因为要读取最大页码,好知道从哪里开始做起。

逆向即见即删版做完后,程序夜以继日地干活,很快把粉丝删成了这样的分布:

典型的删粉进度

这是一个典型的删粉进度。大蓝块是沙里淘金浓缩成的活粉大军,它左边是正门涌入的僵尸粉,右边是有待处理的旧僵尸。

这时我开始担心两件事:一是假如程序还这么傻不拉几地从250扫到1,那么它的大部分时间会浪费在活粉大军上,并且越来越耗时。二是最终删成下图这样时,前250页挤满了活粉,按关注时间排序的新僵尸只从左边进,旧僵尸从右边冒不出来,程序必然熄火。

熄火状态

第二个问题无计可施(也就是说,真粉极多的大用户,不要指望这个程序带来太大的改观),先解决第一个。我在程序里加了几段代码,让它一旦撞到大蓝块,就指数级速降,尽快跳到粉丝列表的头3页去工作。每清完头3页,就相当于把大蓝块往左拽一拽,从右边抽出更多的粉丝列表来。反正在活粉大军前面干活也是干,后面干活也是干,都没有浪费宝贵时间。

读到这里的用户应该能明白,为何250、249之后,突然就skipping active fans,快速地跑到第3页去了。也会有用户问,可有时程序还是继续老实巴交地248、247、246呀。那是因为我担心有些“活粉”会退化成僵尸,所以安排了5%的概率,让程序重新审视活粉大军,看看有没有蜕变了的。

说到活粉的退化,就要谈谈僵尸的定义了。最原始的定义当然是发博少,但怎么才叫少?注册10年的用户发10帖可以称作少,而来微博刚俩月的,发10博就还算可以了,所以发博量要用注册时间来衡量。准确的注册时间并未体现在粉丝列表里,不过从此人ID上可以看出来。通过采集大量的数据,我得到了这些信息:

  • 可以用“来去之间”的ID和注册时间作一个基准(早于他的可斜率外推)。
  • 微博每天用户增长量大约是1,418,780个。
  • 渣浪的用户ID没有4开头的,4000000000-4999999999这段ID不存在。

这些信息给了我一个经验公式。从粉丝列表读到他们的ID时,我大致可以知道他们何时来的微博,再按照每月一博的标准(很宽容了)来衡量,低于这个阈值的,就判为僵尸删除掉。

用户ID和注册时间的对应关系

所以,随着时间的流逝,曾经的活粉退化为僵尸是很有可能的。有人会说这是误判,但我认为,一个人如果喜欢潜水——后面会提到,一些僵尸都比他活跃——那么他对被粉的博主只是日常“视奸”,并未传播博主的信息,留他何用呢?

再说打榜僵尸。这些帐户的存在通常和某明星或某活动有关,是买来的帐户。在演唱会、见面会开始之前,异常活跃。并且抱团互粉,同进同退。单单从粉丝量、关注量、发博量上来看,都不易判为僵尸。下图是一坨样本。

打榜僵尸团样本

严格来说,他们并非僵尸,结群出现到处留言点赞,无非是想吸引你点开他们的页面,看看他们爱豆的最新动态。但他们是为爱豆来的,与我无关,留他们干嘛呢?

单从数字上识别这一类的僵尸很不容易,活动进行期间更是不可能,结群出现时容易感知其命名规律,但这种规律经不起时间考验,不能放到打算长期运行的程序里。幸好活动一过,他们就会闭嘴。于是,我在程序里做了一个新动作:翻检每个粉丝的主页,如果他们持续静默3个月,就判为僵尸。右图里的这些ID,在新规则出台后很快被删了个一干二净。

翻检主页的动作比较耗时,所以程序只在闲时才做。当它扫完一页,没看到经典僵尸时,就会认为咖啡时间到,从数据库里挑选10个最近没看过的ID,一个个翻阅其主页。“微博会员升级啦”、“生日快乐”、“抢了个大红包”这一类的自动信息不计入此人发帖。

读到这里的用户,应该能明白为何程序忽然不刷粉丝列表,而是去浏览用户主页了。

羽翼初丰的程序刚刚开开心心地运行了两三天,我遭遇了来自渣浪的第一次打击:它只给我看两页粉了!这种情况相当于提前进入了被活粉憋死的熄火状态(想象一下上面熄火图中的250改为2)。很有可能是前期可行性测试时,对微博访问过频,被渣浪的系统安全机器人留意到了。

挑战也是机遇嘛,逼迫我提前考虑如何在熄火状态下持续工作了。最终发现,“按最近联系人排序”的话,互动粉丝列表(最多50页)的后半段还能看到许多僵尸粉(并未互动过)。这个列表不会实时更新,删除僵尸后,第二天大约同一时间才会填充新的。不过,每天还能删大约500个,聊胜于无呀。

读到这里的用户应该能明白,为何程序一上来就先从第50页扫描互动粉丝列表了,而且一旦扫完,8小时内不会再碰。昨天有个用户哭着对我说,为什么要删互动粉丝啊?他们都是活粉真粉啊!我拿到她的活粉样本一看,2010年注册的,发帖24,僵尸都更活泼些……

还有潜水员一听我要打僵尸,马上跑来评论:“真粉报到!”“我是活的!”他们假如不吭气还没事,一说话,第二天就上了互动粉丝列表,被程序看到了,发博数本身就可疑,再翻翻主页三个月没说话,就手起刀落了。

同样,我不把这些叫冤杀,如果不想被判为僵尸粉,应该活出自己的精彩来,经营好自己的地盘,不要只在别人家做客。

对于活粉很多的大用户——哪怕僵尸也很多——相信活粉还是能挤满50页(1000个座位)的,这个放僵尸的门缝可能并不存在。

熄火运作了将近1个月,渣浪忽然又开放了250页列表(后来这类事情又发生过两次),迎来了重新开工后的大高峰。

熄火→开工大爆发

从此僵尸粉一溃千里,今年2月,最终删到了5000以下(250页以内),所有粉丝都移出灰区。终于有把握说,我赢得了这场打僵尸的战役。

此后又有几个次要更新,包括对“真是活人”的提前赦免,以及对自语僵尸的判断(逻辑尚在试运行中),都是细枝末节的事了。

最近有些饱受僵尸困扰的用户来下载使用这个程序,有一些给我的反馈里,提出了很好的建议,打开了新的思路。例如,自语僵尸,我这里没几个,而在别人那里则是主要问题。也有抱怨声,比如程序有点慢,为什么要翻看主页,为什么冤杀活粉,等等。我想说,僵尸没有一定之规,几套判断逻辑互相辅助制衡,共同把僵尸逼上绝路,推敲了大半年。随着局势变化,有些看似漫不经心的流程会渐渐凸显其作用。都是我亲自趟过的坑,好不容易填平了的,请不要再把我拽回坑里去了。

删除僵尸粉的自动化

在删除僵尸粉的自动化方面,做了一点微小的工作,免费分享一下。

准备过程有点复杂,既然是免费分享,服务支持是谈不上了,我只介绍大体如何设置,能看懂的应该就克服各种困难了,看不明白的也不能多解释了……

  1. 64位Windows点这里,32位Windows点这里,获得Python编程语言。确认勾选“Add Python 3.8 to PATH”,其他一切按默认设置安装。(约5分钟)
  2. 右击桌面左下角Windows图标,选“运行”,输入pip install selenium安装Selenium,这是用来遥控Chrome浏览器的Python模块。(约1分钟)
  3. 点这里获得Chrome浏览器并一切按默认设置安装(约5分钟,已有Chrome可跳过)。
  4. 点这里获得Chrome Driver,或者,假如你已经有Chrome,可以到这里下载一个版本匹配的Chrome Driver,把解压后的.exe文件放到一个可执行路径目录里,如:C:\Windows。(约2分钟)
  5. 点这里下载僵尸清除程序,解压后存到任何地方都可以(比如桌面)。右击解压后的spamfancleanse.py,Edit with IDLE,把下图所示的开头三行改成你真正的登录信息和用户信息(放心,源代码开放,信息安全经得起同行的严厉审视),Ctrl-S存盘,按F5运行。

对于首次使用、中途也无意外的用户来说,不疾不徐走完上述设置步骤大约需要15分钟。如果你的粉丝总数小于200,那么手工删除更加省时稳妥。

其它信息:

  1. 删除粉丝是个无法回退的操作,请谨慎使用,作者对使用此免费程序带来的任何后果不承担责任。作者自己是从295,000删到4,400左右的,程序很有效,但很打击虚荣心。
  2. 这个程序并非黑进了渣浪的后台数据库,所有的浏览和删除都和正常的手动操作无异,看到的数据也并无不同。它只是接管了枯燥的翻页和点按鼠标的动作,不叫苦不嫌累而已。另外,“病来如山倒,病去如抽丝”,删除僵尸粉的过程是很“稳健”的,最快两秒一个,不能更快了,否则会被渣浪服务器拒绝访问。
  3. 程序运行时,Chrome受控换页翻屏、菜单弹出收起的各种动作很好看,但不要多看,谨防沉迷。
  4. 如果设置第1步骤未选择“Add Python 3.7 to PATH”,那么第2步骤会出现一闪即关的窗口,内容是抱怨找不到pip在哪里。正常的第2步要花一两分钟才能完成。
  5. 如果你的Chrome开着自动更新,那么就要让Chrome Driver的版本跟上,否则二者相差太多时,程序就打不开Chrome窗口了。当这种事情发生时,到这里来重做一下第4步即可(我一直保持着第4步的链接指向最新版本)。假如设置第4步中Google APIs的站点不好用,可以到其镜像站点获得Chrome Driver。
  6. 如果登录密码含有单引号( ’ ),那么在第5步骤设置密码时,要在密码的单引号之前加个反斜杠( \ ),写为 \’ 。
  7. 开发是在Windows上完成的,设置步骤也只提到Windows,但有使用者反馈:在iOS上程序也可顺利运行,只需下载iOS版的Python、Chrome及Chrome Driver即可。
  8. 随时可以关闭Chrome浏览器窗口中止程序,关闭时,监控小窗里会出现可忽略的错误信息。程序会随时把执行进度存到本地同目录的一个数据库里面,下次运行时会记得处理过谁,没处理过谁。数据库文件是本地同目录的spamfans-userid.db,由程序第一次运行时产生。
  9. 第一次运行时它会根据上面3行代码登录,以后再运行时,它就记得登录状态了(存在上条提到的数据库里)。如果它偶尔忘记,还会根据代码里的信息再填。
  10. 如果程序跑了一段时间后,想转移到另一台机器上运行,除了设置说明里提到的那些步骤外,还要把spamfans-userid.db文件一道拷过去,和spamfancleanse.py放到同一目录下。
  11. 程序运行时,尽量不要把鼠标在Chrome窗口上指来指去,不要把Chrome窗口最小化(用其它窗口遮蔽没事),以免干扰到它。业务十分繁忙的大V最好关闭转发和评论的小黄签提醒,它们可能会让页面元素失效,并使程序异常退出(如其发生,重新运行即可)。
  12. 不是每次运行都需要IDLE打开程序再按F5的,只要把登录信息设置好了,在Windows下双击spamfancleanse.py文件图标即可运行程序。在这种模式下,左击调试监控窗口会造成程序暂停,右击则会继续。
  13. 不建议在多台机器上同时跑这个程序,虽然不会造成误删,也确实能提高效率,但多台机器对粉丝的密集访问可能会被渣浪留意到。被留意到之后,渣浪可能会只让你看少数几页粉丝列表,看不到粉丝列表=不知道谁粉了自己=无法继续删除。
  14. 对“僵尸”的初步定义是发帖少于10,或者跟此人ID体现的注册年代不般配的(很早的ID,却发帖甚少,没有传播力)。程序还会对初筛过的ID一个个翻看主页,最近3个月没说过话的会被移除(原创或转发都算“说话”,而系统产生的生日祝福、会员升级或者抢红包都不算)。躲过一次巡视的并非永久安全了,程序还会根据其发博情况安排下次巡视。如果不想被判为僵尸粉,最重要的不是跑博主这里点赞或发“活粉报到”之类的评论,而是赶紧自己发博转博,提升自己在程序眼里的传播力。次年9月2日,加入了对“会说话的僵尸粉”的判断。这种帐户会隔三岔五地喃喃自语,发表空洞的人生感悟或者爱情宣言。
  15. 有时会在监控窗口里观察到程序针对某个ID反复输出UNSURE,这种问题通常是因为这个用户资料发博甚多,主页却空空如也(渣浪登记的微博数常常大于用户实际的发博数,要不说它渣呢),但程序不确定是服务器原因还是别的什么,所以不敢轻易下手删除。对于这样的用户,另开个浏览器手动删除即可,程序再来观察时会发现已被删除,就不再理它了。
  16. 12月16日,在程序里加了个改进:当逐页扫描撞上沙里淘金浓缩而成的活粉大军时,它会跳过这段漫长的扫描,这样可以节约很多时间。另外,在反复筛查时,又会有较低随机概率扫描活粉大军,确保没有僵尸混进来。
  17. 12月18日发现,渣浪偶然会误报用户数据,把活跃用户的关注、粉丝、发博数报得极低(最甚者以上三个数都是零),造成“这是僵尸粉”的误判。对此偶发问题的应对方法是:当重逢某ID,发现微博所报其发博数急降时,则判为误报,不予理会。对于首次见到的ID,若有此问题,则无法解决。好在这种问题发作频度极低,写好应对代码之后,24小时未重现。
  18. 次年8月17日,解决这个问题:假如一个粉丝(或者自己的小号),确知是个活人,却非常低调,只看不说,表现和僵尸一样,怎么办?两个办法:一是互粉,本程序不会碰互粉帐户。二是做一个文本文件.txt,每行写一个要特赦的用户的10位ID,然后把此文件拖拽到exempt-fans.py文件图标上去。在spamfancleanse.zip压缩包里有一个示例exempted-uid-example.txt。
  19. 次年9月4日,关掉了图片加载。纯文字的页面显示得更快更稳定(我怎么不早这样做呢)。9月11日,支持微博的所有四种语言界面。
  20. 结合《打僵尸大捷报告会》服用,能帮助理解这个程序的执行流程。

微博分享按钮

三年前往博客里添加了一个微博分享按钮,最近发现微博分享方式有WBML新版了,于是按照微博介绍的WBML界面重写了这段代码。

先贴代码。新版的添加微博分享按钮的方法:编辑正在使用的monochrome族主题(其它主题可能要微调)的header.php,做两个改动:

一、在<html>标签后增加wb命名空间:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:wb="http://open.weibo.com/wb">

二、在</head>之前加入以下代码:

<script src="http://tjs.sjs.sinajs.cn/open/api/js/wb.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
jQuery(function(){
//  window.setTimeout(function() {  // Make it asynchronous if using the iframe mode.
    jQuery('div.post').each(function() {
        var url = jQuery(this).find('h2.post_title > a').first().attr('href');
        if (typeof(url) == 'undefined') {
            url = location.href;
        }
        var titlestr = jQuery(this).find('.post_title').text() + ': ' + jQuery(this).find('p').not('.wp-caption-text').text();
        titlestr = titlestr.replace(/\s\s+/g, ' ').substr(0, 110);

        var buttonstr = '<div style="width:95%;text-align:right;margin-top:-40px;margin-bottom:40px;">';

        var param = {
            url:url,
            type:'button',
            addition:'number',
            picture_search:'true',
            title:titlestr,
            ralateUid:'1691250947'  // 关联用户的微博用户号码
        };
        var temp = [];
        for(var p in param) {
            temp.push(p + '="' + encodeURIComponent(param[p] || '') + '"');
        }
        buttonstr += '<wb:share-button ' + temp.join(' ') + '></wb:share-button>';


        buttonstr += '</div>';
        jQuery(this).find('div.post_content').first().after(buttonstr);
    });        // jQuery.div.post.each
//  }, 5000);  // window.setTimeout
});
</script>

第一次重写后,IE不稳定地显示按钮、Firefox完全不行(IE竟然胜出,奇迹)。调试发现和一年前的一次优化有关。当时我把分享按钮的JS代码改为异步(橙色代码,页面加载完毕5秒后)运行,而此定时器似与WBML版按钮冲突。

之所以怀疑这个定时器,是因为观察了博客右边栏放置的静态代码“微博关注”按钮。我留意到它总能显示,并且当整个页面加载完毕、网页闲下来时才开始运作。猜想渣浪也发现这些按钮很耗时,于是也在按钮里内置定时器,把我这些外层的定时器顶得不干活了。

另注:渣浪程序员把“关联用户”的设置参数命名为ralateUid,嗯,从上一版延续至今以后也一直会继续错下去的拼写,厚道地猜想这是为了防鹅防寨故意拼错的。另外,微博文档里说抓图选项是searchPic,而快捷设置页里则可以看到是picture_search。我测试之后得知,picture_search是有效参数。

随想杂谈

主张宽容的人和主张报复的人辩论,一定是主张报复的人在言词上“获胜”,如果他们都笃信自己观点的话,那么主张宽容的人没法做到有一句还一句。好处是最后双方都打心眼里认为自己赢了,皆大欢喜。

有效的拒绝,是正面直接的拒绝,不给对方好奇追问的、或者自己都不相信的借口。礼貌的拒绝,是表示“我能理解你这样推荐的好意”。两个合起来,大约就是这样的句子:“养只猫么?啊,不了,谢谢,我多么希望有一天能像你一样喜欢猫。”

多年前曾觉得南方系媒体有内容、敢说,看久了发现(他们触网后更明显),他们跟太阳花区别不大。和北方系媒体相比:北方系睁眼说瞎话,南方系闭眼说梦话。

曾经有小道消息称李敖和柏杨夫人有一腿,李敖回应道:可以怀疑我的道德,但不要怀疑我的审美。一下子烟消云散了。侧面回应对于这种捕风捉影、越辩越黑的小道消息很有用。而对于(理论上应该)有帐本的慈善基金管理,直接公开帐目就是。当事人应该正面回应,侧面调侃由台下的拥趸来做,才是有效的公关。

抄经快递的包装材料时问多少钱,一个人正要答,老板一扬手,他不说话了,老板说,十块。其实我已经问过前面一家了,那家报四块八,只是不乐意费劲帮我锯成十段而已。我也不想拆穿他了,多出来五块就算锯十段的手工费吧,穷人何苦为难穷人。

我对挑拨离间的人耐受力较高,他们目的明确,表达合理,执行有效。反倒是被挑拨动了的人,尤其是起初还是很不错的朋友的,才是我眼里的烂人。

莫淘垃圾。垃圾一直是垃圾,但自己会臭的。

关于儿童在香港街头嘘嘘被摄像事件

一、父母已经做了能想得到的所有努力,并且使用了尿不湿避免孩子直接尿在大街上,可以理解。
二、之所以说“能想得到的”,是还可以再细想:可以和厕所排队的人商量,或找个更隐蔽的场所。
三、旅行前事先预习一下如何对付港灿,会很有帮助。
四、野鸡网和闾丘露薇是个渣渣。

对人名的偏见有时能影响一个人的阅读领域。我从来不读张爱玲,因为这个名字太丑了。同样,我也基本不看闾丘露薇的言论,也不关注她,除非是别人转的撞到我眼里来,究其原因,好像是她的名字太像卫生巾的商标了。

“求知欲强”和“阅读不耐”同时表现在同一人身上,他够得着的人就成了杯具。

对于科研,最打击的话是“这不对”;对于科普,最打击的话是“听不懂、不爱听”。弄错了工作重点,窝火事件就发生了。

很不喜“毕竟他还是个孩子”这种句式。如果孩子运动技能生疏,当然可以再给机会,如果是后天的心智不全甚至恶棍就必须严厉对待。至于“如果是你的孩子你还这么说吗”,这种假设型问题本身毫无意义,即使有意义,作为自己的娃,当然希望他板子挨轻些别打残,可这不妨碍对“他做的事很混蛋”的事实认定。

同一段话,我读出来是这个意思,你读出来是那个意思,这很正常。但我说的是“我没读出来你说的那个意思。”这是事实。你说的是“你怎么随便改别人的意思?”这是攻击。如果你邀人来讨论,又不想听不同的声音,以后就别讨论了。

国宝帮

所谓“元钧”

所谓“元钧”
来源@中国文物研究高飞

通过冀宝斋博物馆一事,我知道原来还有一个“国宝帮”,信奉“真正的国宝在民间,考古专业人士没见过的未必假”,由此神推理“民间收藏一定真”的结论,并断言:凡说他们藏品假的,都是伪专家。

然后,俺在微博上亲眼目睹了一朵国宝帮的奇葩,如果读者没耐心逐条看他的微博,可以通过右图感受一下,此图来自这么一条微博(若已删除很正常,因为最近常常有人踩),展示了三摞“元钧”十件套。为何说是“元钧”呢?微博里有评论对答:

@KuangchaoDai_Danmark:既然你在深圳。拿去香港检测啊。全世界现在暂时只承认英国和香港。。 (2012-12-28 16:17)

@中国文物研究高飞:香港碳14我也拿一个测为元代; (2012-12-28 16:20)

可是,亲,你就这么把元钧摞在瓷砖地板上展示?你不心疼它们的釉面?不怕折断底足?不怕一脚踢翻?你内心深处是不是知道货源充足、打个电话就能再订一套?再说这整整齐齐十件套是怎么回事?能还原出怎么样的生活场景?十个笔洗齐刷刷摆在案头,大号的涮排笔、小号的涮勾线笔?你有没有考虑过砚台的感受?

再看此人的微博ID,给自己定位也挺纠结的,有四个ID只用了一天就作废了(我是该有多闲):

2012.05.29 – 2012.10.31:文物鉴赏家2012
2012.11.08:文物鉴赏家
2012.12.03 – 2013.05.19:资深文物收藏鉴赏家
2013.05.28:文物研究三十六载苦辣酸甜老兵
2013.06.19:文物研究与收藏
2013.06.20 – 2013.10.15:中国文物研究
2013.10.29:文物研究
2013.11.05 – :中国文物研究高飞

这条“元钧”的博还不是头一个吸引我的,起初我完全是被一摞宋汝笔洗十件套(微博已删)震惊了——你说这宋朝到元朝的生活方式真连贯啊,干啥都是十件套——那套“宋汝”的正文是征聘经销商的,出手越快,提成越高。俺岂有不帮忙之理,把这条微博转发之后,引爆了广大人民群众的笑点,大家一起来竞价,可惜是Dutch Auction,越喊越低,从八十八喊到二十二,还要货主包邮。经过一夜的轮暴,货主终于忍无可忍,把原博删了,次日压低了嗓子在自己主页里大骂

真他娘的扯蛋!混帐!我发图片让你买我东西了?让你粉我了?让你鉴定了?让你评价了?我发图片真与假和小混蛋有关系吗?你们的东西在哪里?别人没有点名让我评论的东西我那么多年评论过了吗?不自量的去你娘的怀中吸奶去吧!

其实与其说是大骂,还不如说是委屈的咕哝,后面这条就更加怨妇(俺把一票人马的微博链接配齐了,俺真是闲透了):

有些不知天高地厚的东西!你不骂人他难受。自已没有东西就会窝里斗!有何意愿?我发图片是与下面等好友分享学习的。@玉言的世界 @长城艺术 @瓷之雅 @瓷器鉴赏 @古玩精品收藏家 @卜事正宗 @孔明与诸葛 @唐和唐珠宝 @太古山房古美术 @马明生中国著名收藏家鉴定家

意思基本上是说,他这批货是给知根知底的朋友们看的,原奔着酱油铺子去的群众忽然改道过来,搅了他的瓦缸批发生意,实在是不懂江湖规矩。好吧,倘若真是如此,微信对他们其实更合适。风和日暖时,大家各自晒晒假货,互相捧捧臭脚,自娱自乐,没人知晓,没人笑话。

以下是我的自娱自乐:

碰到笨人要帮扶。看见笨贼,打脸就行了,不能教他们长本事。 要想办法使国宝帮坚信:织物要挂着秀。瓷器要摞着秀。碳14最适合测无机物如陶瓷、青铜、石刻。年号和庙号要同时出现在落款里才正宗。Thermoluminescence这种伪科学的东西不要让他们听见。

佛靠金装,人靠衣装。先天不全的假货,晒宝时再用红色字体标注,纯属自毁形象。《笑海千金》有一则:“你若生疮,雪上加霜。”殆与此相类。不过我怎么可能传授给他们修图的本事呢?

有趣的北京晚报

留意这篇微博的截图内容和它上面的“不实消息已处理”。
beijingwanbao-rumor
猛击阅读全文

给一座知名墓葬博物馆的官微的建议

我关注一座知名墓葬博物馆,有一段时间了。去年暮春,这座博物馆的一位资深人士和我在微博上认识,从此常常呼朋唤友,组团泡馆,收获知识也收获友谊,甚是欢乐。忽然一天看到这座博物馆的官微,以为老友开发了另一种渠道的发言平台,果断关注。看了几天,觉得这官微的风格迥异,沉闷枯燥,用词费解。私下一问,果然不是老友主持的。出于对博物馆的喜爱和感谢之情,也出于一份私人友谊,我对这座博物馆的官微有以下建议。

一、开放思路,多找话头。很多话题,对于博物馆或者考古人士们是理所当然的,而对于我这样的外行却非如此,因为不是理所当然,所以就有趣。我随意想起的话题有:广阳倾王的家庭背景如何?他爹是谁?和当时的皇帝是什么关系?怎么死的?为什么起了那么个差劲的谥号?他爹的下场这么不堪,为什么墓主本人的葬制这么风光?这个墓是怎么被偶然发现的?谁主持的探方和发掘?怎么知道墓被盗过了?怎么确认的墓主人身份?墓主人的身份还有哪些争议的声音?那些柏木条为什么叫作黄肠?题是什么意思?凑是什么意思?天子之制用在诸侯王身上,为什么不算僭越?还有谁用过这种高级葬制?这种葬制从什么时候开始的?为什么后来不时兴了?
二、多发馆藏文物的图片,引发思考和讨论。随意列举几个:那个漆榻的用途是什么?确定么?棺是怎么推进椁里的?马是生祭还是屠宰后祭的?车马坑的两架车有什么不同?为什么不同?柏木为什么不腐烂?白膏泥是怎么个用法?木炭是怎么个用法?车马坑的发掘有什么难点?玉舞人是专给死人佩戴的还是活人也能用?玉觹是怎么用的?袖棁的工艺到底有多复杂?那些鸟骨怎样反映当时的生态环境?那个木枕头在首博也有一件复制品,它龙头上的角到底是朝里还是朝外?
三、介绍馆里的特色项目。小朋友们常去学挖土探方,游戏规则是什么样的?有哪些工具可以用?投壶的规则是怎样?那个铜壶是参考哪些文物制作的?有古代的礼仪实习,古人跪在那么一个木板上就不觉得硌得慌?汉代的贵族衣冠是什么样?为什么不是穿明黄而是穿黑?哪天可以去玩?怎么联系活动?
四、多聊天扯闲白,例如说说你家院子里的那只大狗的逸事啊,说说发大水对你家的影响啊,说说最近为什么在修缮啊,说说路面和地铁交通啊,说说为什么乘摆渡车还要再刷一次公交卡啊,说说夏天蚊子多啊,说说为什么在墓葬值班守夜不觉得害怕啊,说说春节期间守着一堆木头是多么担心啊。

一时就只想起来这么些话题,还是觉得比转发朱总司令生平展和翻拍的汉代养生知识有趣一些。希望老友看到这篇文章不要介意。

关于闪光灯的公益广告(一天被 @ 六百多次的感觉)

no flash

去年这个时候,和文博的一些朋友说起博物馆闪光灯太严重的问题,做了几则公益广告(之一|之二|现场劝告观众的实战),只在微博上流传,并未在现实世界的博物馆付诸实施。不料最近因为 @孔府旧藏服饰展 展厅观众用闪光灯太狠的缘故,被朋友翻出旧图并点名游街。二十四小时不到,广告被 @ 了六百多次。

虽然可以关闭 @ 通知,我还是很好奇大众的思路是怎样的,所以就任凭小黄签不停地弹出。看了看评论,基本上以“爱护文物,关闭闪光灯”出发。我为这些观众的甚高境界感到高兴,不过,他们作为博物馆礼仪的遵循者和倡导者,并不是这些广告的受众。“爱护文物、人人有责”这种口号,对于一些人有用,对于大多数人——包括我自己——都是很苍白无力的。

另外我也看到,很多给开闪的观众报以白眼的,或者冲过去教育他们别开闪的,多半会遭到恶语和白眼的回报。只能徒呼素质太低,无可奈何。素质低么?也许真有点低,不过这是现状,我们没办法一下子提升全民素质。虽然如此,对于实现“关闭闪光灯”这个小目标,还是有希望实现的。

所谓“君子喻以义,下句不敢说”,人为什么谈不拢?因为没有找到共同利益。

设计这两则广告的切入点,是考虑一下,用闪光灯的观众,他们关心的是什么?

他们关心文物么?不。
他们关心其他观众的感受么?不。
那么他们关心什么?
——关心的是照片或者“到此一游”的感觉。

那么,如果我们对他们说,使用闪光灯会对照片的质量、数量产生伤害,他们是不是愿意关闪光灯?
也许会。

闪光灯会影响照片的质量么?会。玻璃罩子上有个大反光,本来闪光灯算是个点光源,但玻璃罩子不是完美平面,而且上头有很多指纹、掌纹、头皮纹,这样就首先会拍到一个油腻腻的大光球。闪光灯一开,照相机就会默认减少曝光时间,展品就暗下来了,被闪亮的部位一片过曝的死白,其余部位漆黑一团。闪光灯和镜头不在一个位置上,会在展品身边留下一个微有恐怖感的鬼影。闪光灯会形成顺光拍摄,使被拍物体失去立体感。

闪光灯会影响照片数量么?会。一开闪光灯,几十张过去,电池小图标就唰唰地由绿到红了。

那么,我们就可以强调这两点,给出实例,让他们从爱护自己照片的角度出发,关掉闪光灯。不用说“爱护文物”,也不用解释为什么博物馆不欢迎闪光灯,如果可以把这些广告制作成小书签,进场时发放给他们,人对免费给自己的东西总是会多看几眼的,就可以省去很多口舌。

如果博物馆能够找到懂行的志愿者,时时在现场巡视,通过实战来演示关闭闪光灯对照片效果的提升,那就再好不过。我本人是能劝一个是一个,其实很多观众是摄影盲,不知道怎么关闪光灯而已,并不是存心跟博物馆做对,不用鄙视他们也不用骂他们,友好地跟他们说“用闪光灯效果很差的,看我给你拍一个”,往往立竿见影,他们会求着你帮着关闪光灯的。帮他关闪光的时候,再拉家常地说“开闪光灯对展品也不好,而且人家会笑话你的相机不专业(注意不要说笑话他不专业)”,效果更佳。这尊喜金刚的效果对比图,就是在首都博物馆佛像厅做现场劝阻的产物,他拍出了上面一张,我就给他演示下面一张,顿时他就求着我了。场面和谐,欢笑道别。

当时这位观众跟进了两个问题。

使用闪光灯的真实效果

一、不拍展品的情况下,我怎么知道现在闪光灯是开还是关(这说明他已经不愿意用开闪的相机对着展品了)?答:对着地面随意拍一张,看看是不是闪了。

二、那什么时候应该用闪光灯?答:其实什么时候都不需要闪光灯,你眼睛看到了满意的光影,一开闪光灯,光影就改变了。我还放下手中的厚卡片,摸出包里的5D Mark II来向他证明这一点,相机上根本没有闪光灯。我知道这个回答很简短粗暴,但跟他讲——刑侦现场光线过暗时,室内影楼拍全家福时(且是用柔光跳闪),和极亮的背景合影时(例如雪山)——就不是他用得着的知识了。

以上闪光灯效果均为PS获得,我本人还未敢在博物馆做实验。经@螺旋真理允许,使用了他的一张无意间开闪拍到的照片。印证了上面所预测的效果:大白球、死白、鬼影、顺光。只有“其余部分曝光不足”没有验证,现场本身就很亮,想必因为是瓷器,展方对照度没有控制。

对寻人事件的旁观

刚刚看到,波密官方微博决定不再发布和寻人事件相关的更新了,这是从其利益点出发的正解。一开始可能以为这是个迅速提升形象的机会,而事情一旦进入停滞状态,就不好办:如果翻车坠江了,就是路况不好。如果失踪了,就是警方无能。如果遇害了,就是治安太差。作为旅游业支撑的地方,不能承受这些无形资产的损失,所以只能冷处理此事。

昨天和好友聊及此事,态度相似:至今不能排除是新浪微博的研究课题,例如——微博能够调用多少社会力量?如果确实如此,是大恶的结果,公共信心会全面崩盘,以后所有的呼救都是烽火戏诸侯了。虽然有此想法,这个想法只能作为最差预期。而在技术操作上,还是得本着人命至重的态度,假定此事全真,尽力帮助。对此事的信心,应该是帮就帮个彻底,输就输得痛快。底线设置低些,心理无压力。

大众也开始疲劳了。七天前,大家的留言还是一片的安慰和祈祷,现在放眼望去,就是观众席上的互殴。疲劳的主要原因,好像有三个:一、迟迟没有进展。二、虚假传闻太多。三、人性就是这样。

家属这边,可能没有做好事情成为疑案的准备,或者说,没有设置回家的条件。一旦成为疑案,他们久住当地没有意义,也无法空着手坦然回来。

寻人的前线,战线拉得过长,家属和热心帮忙的人也开始有了矛盾。对于助人者,他们停掉自己的生意来帮忙,已经是菩萨行为了。但他们和家属利益点不同,没办法一直这么帮下去。道理上讲,他们帮忙是恩典,不帮忙是本分。但中国的传统是“帮人帮到底,送佛送到西”,无法认可这点。完全不帮忙没有关系,帮忙不帮彻的会挨骂。家属好像也有点滥用助人者的倾向。一听到风吹草动、“高人定位”什么的,不过大脑,不质疑一声“无图无真相”,就催着从林芝连夜穿越通麦天险、走八小时的车程去然乌。这真是想再搭几条人命的事。

围观群众就不用说了,包括我在内,一群暴民。

最后事情可能会闹翻,全部参与者受到伤害,以微博上的骂战收场,或者被新的灾难新闻追尾,中途夭折。

“分享到新浪微博”按钮

在博客的每篇博文后都加入了“分享到新浪微博”按钮。方法是编辑monochrome的主题(theme),在header.php的</head>前加入这么一段代码:

<script type="text/javascript">
jQuery(function() {
    jQuery('div.post_content_wrapper').each(function() {
        var urlstr = jQuery(this).find('h2.post_title > a').first().attr('href');
        if (typeof(urlstr) == 'undefined') {
            urlstr = location.href;
        }
        var _w = 72 , _h = 16;
        var param = {
            url:urlstr,
            type:'3',
            count:'1',                  // 是否显示分享数
            appkey:'',
            title:'',
            pic:'',
            ralateUid:'1691250947',     // 关联用户的微博用户号码
            language:'zh_cn',
            rnd:new Date().valueOf()
        };
        var temp = [];
        for (var p in param) {
            temp.push(p + '=' + encodeURIComponent(param[p] || ''));
        }
        buttonstr = '<div style="width:100%;text-align:right;">';
        buttonstr += '<iframe allowTransparency="true" frameborder="0"';
        buttonstr += ' scrolling="no" src="http://hits.sinajs.cn/A1/weiboshare.html?';
        buttonstr += temp.join('&') + '" width="'+ _w+'" height="'+_h+'"></iframe></div>';
        jQuery(this).find('div.post_content').first().after(buttonstr);
    });
});
</script>

这个代码也许只在monochrome主题下工作,而对于其它的主题,需要稍事修改。

iframe所要显示的参数是从新浪微博开放平台获得的。

程序的小难点在于:显示单篇博文的时候,博文题目只是个简单的header,header上没有链接页面的URL。而显示多篇博文时,每个博文的题目上都链接了其单篇的URL。获取这个URL就需要一个条件判断,也就是这段代码:

var urlstr = jQuery(this).find('h2.post_title > a').first().attr('href');
if (typeof(urlstr) == 'undefined') {
        urlstr = location.href;
}

在自己机器上调好之后,把代码放到博客上时,还遇到一个惊奇。分享按钮根本不显示,好像这段代码根本未被调用一样。后来发现,在我的机器上,可以使用jQuery的缩略写法$(),而在博客网站上,必须老老实实写成jQuery()。