饭否私信格式分析
URL
饭否私信分为两种,一种是我收到的私信,一种是我发出的私信。
- 我收到的私信:http://fanfou.com/privatemsg/p.(1-N)
- 我发出的私信:http://fanfou.com/privatemsg/sent/p.(1-N)
上面的地址中不含饭否ID;需要cookie验证。
结束标志
通过cookie验证后,可以使用数字获得对应页码的私信内容。什么时候是结束呢?假如您的收件箱有1000条私信,每页显示20条,那么当你您输入http://fanfou.com/privatemsg/p.51时,就得不到任何有效的内容了。作为程序,它是寻找如下标志:
1 | <ol class="wa">\s*</ol> |
好友列表
在页面代码中,每页都有一个“向XXX发送私信”的combox列表,条目以昵称+ID组成。如果你的好友很多的话(500+),每条好友(昵称+ID)需要20字节(估算)的话,20*500=10K,大约需要多抓取10K的字节量。
收件箱饭否私信的结构
收到的私信分为两种,一种是有回复信息的(回复原文:…),一种是没有回复的。先从简单的入手,看没有回复的。
所有的私信都在<ol class=”wa”>…</ol>之内,以<li></li>分隔
例如下面这一条,就是一则很规范的私信(与发件人相关的信息都使以正则式表示):
1 2 3 4 5 6 7 8 9 | <li> <a href="/[^"]+" title="[^"]+" class="avatar"><img src="[^"]+" alt="[^"]+" /></a> 来自<a href="[^"]+">[^"]+</a>: <span class="content">没法比较啊,你得说个具体的值,比如100条以下的算少,1000条以上的算多……</span> <span class="stamp time" title="2008-05-30 17:25">约 15 小时前</span> <span class="op"> <a href="/privatemsg.reply/583520">回复</a> <a href="/privatemsg.del/583520" class="post_act">删除</a></span> </li> |
其中,需要记录的信息有:
- 发件人名字;
- 发件人ID;
- 私信内容;
- 时间;
- 私信ID;(便于作删除、回复处理)。
根据以上需求,将上面的私信代码作处理:
1 2 3 4 5 6 7 8 9 10 | <li> <a href="/([^"]+)" title="([^"]+)" class="avatar"><img src="[^"]+" alt="[^"]+" /></a> 来自<a href="[^"]+">[^"]+</a>: <span class="content">([^<]+)</span> <span class="stamp time" title="([^"]+)">[^<]+</span> <span class="op"> <a href="/privatemsg.reply/(\d+)">回复</a> <a href="/privatemsg.del/\d+" class="post_act">删除</a> </span> </li> |
从而得到:
1 2 3 4 5 | $1=fanfou ID; $2=fanfou name; $3=private msg; $4=msg time; $5=msg ID; |
再看一下包含“回复原文”的私信的结构(部分内容已作正则处理):
1 2 3 4 5 6 7 8 9 10 11 | <li> <a href="/([^"]+)" title="([^"]+)" class="avatar"><img src="[^"]+" alt="[^"]+" /></a> 来自<a href="[^"]+">[^"]+</a>: <span class="content">([^<]+)</span> <span class="stamp time" title="([^"]+)">[^<]+</span> <span class="op"> <a href="/privatemsg.reply/(\d+)">回复</a> <a href="/privatemsg.del/\d+" class="post_act">删除</a> </span> <p class="pm-parent">回复原文: 有兴趣就有动力</p> </li> |
与前者相比,只是多了<p class=”pm-parent”>.*?</p>这一段。这是不足为虑的。只要整体加上?这个强有力的正则符号,就能与上面的代码片段归纳到一起。两者结合合的代码如下:
1 2 3 4 5 6 7 8 9 10 | <li> <a href="/([^"]+)" title="([^"]+)" class="avatar"><img src="[^"]+" alt="[^"]+" /></a> 来自<a href="[^"]+">[^"]+</a>: <span class="content">([^<]+)</span> <span class="stamp time" title="([^"]+)">[^<]+</span> <span class="op"> <a href="/privatemsg.reply/(\d+)">回复</a> <a href="/privatemsg.del/\d+" class="post_act">删除</a></span> (?:<p class="pm-parent">([^<]+)</p>)? </li> |
得到的变量为:
1 2 3 4 5 6 | $1=fanfou ID; $2=fanfou name; $3=private msg; $4=msg time; $5=msg ID; $6=parent msg;#回复原文。 |
发件箱饭否私信的结构
抄代码:
1 2 3 4 5 6 7 | <li> <a href="/([^"]+)" title="([^"]+)" class="avatar"><img src="[^"]+" alt="[^"]+" /></a> 发给<a href="[^"]+">[^"]+</a>: <span class="content">海内的像片是真的。</span> <span class="stamp time" title="2008-05-28 20:24">2008-05-28 20:24</span> <span class="op"><a href="/privatemsg.del/576827" class="post_act">删除</a></span> </li> |
这与“我收到的私信”的结构完全一致,只是将原来的“来自”改为“发给”而已。
不出意外,带有“回复原文”的“我收到的私信”的结构是这样的:
1 2 3 4 5 6 7 8 | <li> <a href="/([^"]+)" title="([^"]+)" class="avatar"><img src="[^"]+" alt="[^"]+" /></a> 发给<a href="[^"]+">[^"]+</a>: <span class="content">在自述部分显示的那个网上。</span> <span class="stamp time" title="2008-05-29 17:00">2008-05-29 17:00</span> <span class="op"><a href="/privatemsg.del/579918" class="post_act">删除</a></span> <p class="pm-parent">回复原文: 我也要试一试。</p> </li> |
我们从饭否私信代码上得到的信息就这些。遗憾的是,饭否私信中,关于“回复原文”是以明文内容形式出现,而不是以原私信ID的形式出现。后期处理时通过搜索功能解决此问题并非不能,只是如果饭否官方能够再将此功能完善的话,会省整理者不少力气。
饭否的私信源码分析完毕。至于如何读写cookie,如何写代码,如何以数据库的形式来管理下载的数据,是第二阶段的事情了。待我一一实现。