<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>I@laoer.com &#187; Web2.0</title>
	<atom:link href="http://i.laoer.com/tag/web20/feed" rel="self" type="application/rss+xml" />
	<link>http://i.laoer.com</link>
	<description>技术、生活、感悟 -- Laoer的博客</description>
	<lastBuildDate>Mon, 15 Feb 2010 08:36:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>SNS中好友动态功能的设计思路</title>
		<link>http://i.laoer.com/sns-news-feed-design.html</link>
		<comments>http://i.laoer.com/sns-news-feed-design.html#comments</comments>
		<pubDate>Tue, 17 Mar 2009 10:28:20 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[Web2.0]]></category>
		<category><![CDATA[构架设计]]></category>
		<category><![CDATA[SNS]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=171</guid>
		<description><![CDATA[现在大部分SNS网站都有一个功能，就是显示好友的活动状态，比如你的好友上传了一张照片、分享了一篇文章等等动作，都可以显示在你的页面里，这样大大增强了社区的互动性，也成为现在SNS网站的主要特征，对于这样一个功能，从设计角度，还是值得思考的，并不简单，特别是用户越来越多，信息海量增长的时候，我未必能提出十全十美的方案，但我们可以由简如繁梳理一下思路。
首先我们要定义用户的活动消息，也可以理解为一个事件，就是我们举的例子：用户上传照片、与别人结为好友、修改了个人资料等等，动作各有不同，但需要在结构上通用，我们先设计一个
ID //消息ID
UserID //用户ID
MsgType //消息类型，比如加好友、上传照片等不同的类型
EventMsg //消息的内容，这里我们可以用Json的数据格式来描述出不同的活动内容
CreateTime //消息创建时间
这个结构也是个数据库的结构，当用户做个一个动作之后，就会创建这样一个消息，并保存在数据库中，当显示好友的活动信息时，就从这张表里查询自己好友id的数据，并按时间显示，这个做法是一个最简单的实现，但会出现一些问题，当你与一个用户成为好友之后，该好友之前发生的动作会显示出来，而不是在成为好友时点之后的动作，同样，切断好友关系之后也有类似的问题，如果从业务角度和用户体验上可以接受的话，也没什么，但由于信息是按时间排序，有时候会给用户错乱的感觉，还有，这个信息不能删除，如果删除了所有好友就看不到这条信息了，但在Facebook里是则是可以删除好友的动作信息的，这个方法还有一个问题是，所有信息都放在一张大表里，在信息爆炸增长，个人好友也很多的情况下，查询效率会非常低，产生严重的性能障碍，如果对这张表做水平切分，则在实现上复杂了许多，性能也未必好很多，接下来我们再思考是否有更好的解决办法。
在SNS的理论里，个人好友的合理数量在150个左右（最近有文章说Facebook的人均好友数是120人），SNS网站应该是有好友数量的限制的，我们就按人均150个好友来设想，是否可以在用户发生某些动作之后，针对他的所有好友都写入一条信息，所能解决的是，信息是在用户成为好友时点之后写入，用户可以删除好友的活动信息，不影响其他用户的显示，在显示时查询效率要高很多，但是负面效应也十分明显，一个用户的动作有平均150个写入，对于数据库来说开销也非常大，我们想想在这样的设计下，是否可以提高性能。
首先看数据库设计，我们要把信息表和信息与用户的对应表分开，我们上面定义的数据结构保留，我们定义它的表名为Event，我们再新建一张表EventUser，结构如下
ID  //主键
EventID //Event表的ID
FriendUserID //好友的ID
CreateTime //消息创建时间
对FriendUserID做索引，当用户发生动作时，首先将动作信息写入Event表，之后查找用户的所有好友，将EventID、好友ID逐条写入EventUser表，当要显示自己的好友活动信息是，查询EventUser中FriendUserID等于自己ID的信息，并和Event表做一个Join查询就可以了。
进一步提升性能的方法，将Event里的信息缓存，比如用Memcached，EventID做为Key，内容做为Value，这样，查询EventUser是就不用Join Event表，而是从缓存里读取，由于要记录给每个好友的信息，所以EventUser会变得非常大，平均要比我们最初设计的数据容量大150倍，我们对EventUser表做水平切分，根据用户ID做Hash算法，基本上能均匀的分配到所有的表中，至于EventUser水平切分的算法还有多种，根据实际情况来定，总的来说就是把数据分摊掉，同时EventUser里的数据可以不永久保存，做定期删除，可以保持数据容量在一个合理的范围内。
对于用户动作之后的数据写入，可以采用异步的方法，在发生动作时，抛出一个消息，由另外一个线程在做写入操作，如果对每个动作平均150次的写入仍存顾虑，我们可以针对每个用户开出一块内存空间，或是缓存，里面保存最后50条最新的好友动作，并在每条记录里做一个持久化标志，当有50条信息都标志是“未持久化”时，做一次数据库的写入，然后把信息置为“已持久化”，这种非实时写入的方式，可以提高一定的数据库效率，显示时，先从内存中取出，再查数据库。
还有一些问题，对不不同消息类型的处理方式不同，比如用户修改个人资料，并不是每次发生这样的动作都要做一次给朋友做一次“群发”的操作，如果遇到这个人在短时间内做了多次修改个人资料的操作，就给朋友发出多个消息，会产生垃圾信息，让人觉得很怪异，所以对于这样的操作会有一定的时效性，比如在一天之内的修改个人资料，就是一个消息，这时候的处理是更新，而不是插入。
以上是我对SNS中好友动态功能的设计思路，可能还有一些未想到的问题，还需要认真思考。
]]></description>
			<content:encoded><![CDATA[<p>现在大部分SNS网站都有一个功能，就是显示好友的活动状态，比如你的好友上传了一张照片、分享了一篇文章等等动作，都可以显示在你的页面里，这样大大增强了社区的互动性，也成为现在SNS网站的主要特征，对于这样一个功能，从设计角度，还是值得思考的，并不简单，特别是用户越来越多，信息海量增长的时候，我未必能提出十全十美的方案，但我们可以由简如繁梳理一下思路。</p>
<p>首先我们要定义用户的活动消息，也可以理解为一个事件，就是我们举的例子：用户上传照片、与别人结为好友、修改了个人资料等等，动作各有不同，但需要在结构上通用，我们先设计一个</p>
<p>ID //消息ID<br />
UserID //用户ID<br />
MsgType //消息类型，比如加好友、上传照片等不同的类型<br />
EventMsg //消息的内容，这里我们可以用Json的数据格式来描述出不同的活动内容<br />
CreateTime //消息创建时间</p>
<p>这个结构也是个数据库的结构，当用户做个一个动作之后，就会创建这样一个消息，并保存在数据库中，当显示好友的活动信息时，就从这张表里查询自己好友id的数据，并按时间显示，这个做法是一个最简单的实现，但会出现一些问题，当你与一个用户成为好友之后，该好友之前发生的动作会显示出来，而不是在成为好友时点之后的动作，同样，切断好友关系之后也有类似的问题，如果从业务角度和用户体验上可以接受的话，也没什么，但由于信息是按时间排序，有时候会给用户错乱的感觉，还有，这个信息不能删除，如果删除了所有好友就看不到这条信息了，但在Facebook里是则是可以删除好友的动作信息的，这个方法还有一个问题是，所有信息都放在一张大表里，在信息爆炸增长，个人好友也很多的情况下，查询效率会非常低，产生严重的性能障碍，如果对这张表做水平切分，则在实现上复杂了许多，性能也未必好很多，接下来我们再思考是否有更好的解决办法。</p>
<p>在SNS的理论里，个人好友的合理数量在150个左右（<a href="http://tech.sina.com.cn/i/2009-03-02/07232868882.shtml" target="_blank">最近有文章说Facebook的人均好友数是120人</a>），SNS网站应该是有好友数量的限制的，我们就按人均150个好友来设想，是否可以在用户发生某些动作之后，针对他的所有好友都写入一条信息，所能解决的是，信息是在用户成为好友时点之后写入，用户可以删除好友的活动信息，不影响其他用户的显示，在显示时查询效率要高很多，但是负面效应也十分明显，一个用户的动作有平均150个写入，对于数据库来说开销也非常大，我们想想在这样的设计下，是否可以提高性能。</p>
<p>首先看数据库设计，我们要把信息表和信息与用户的对应表分开，我们上面定义的数据结构保留，我们定义它的表名为Event，我们再新建一张表EventUser，结构如下</p>
<p>ID  //主键<br />
EventID //Event表的ID<br />
FriendUserID //好友的ID<br />
CreateTime //消息创建时间</p>
<p>对FriendUserID做索引，当用户发生动作时，首先将动作信息写入Event表，之后查找用户的所有好友，将EventID、好友ID逐条写入EventUser表，当要显示自己的好友活动信息是，查询EventUser中FriendUserID等于自己ID的信息，并和Event表做一个Join查询就可以了。</p>
<p>进一步提升性能的方法，将Event里的信息缓存，比如用Memcached，EventID做为Key，内容做为Value，这样，查询EventUser是就不用Join Event表，而是从缓存里读取，由于要记录给每个好友的信息，所以EventUser会变得非常大，平均要比我们最初设计的数据容量大150倍，我们对EventUser表做水平切分，根据用户ID做Hash算法，基本上能均匀的分配到所有的表中，至于EventUser水平切分的算法还有多种，根据实际情况来定，总的来说就是把数据分摊掉，同时EventUser里的数据可以不永久保存，做定期删除，可以保持数据容量在一个合理的范围内。</p>
<p>对于用户动作之后的数据写入，可以采用异步的方法，在发生动作时，抛出一个消息，由另外一个线程在做写入操作，如果对每个动作平均150次的写入仍存顾虑，我们可以针对每个用户开出一块内存空间，或是缓存，里面保存最后50条最新的好友动作，并在每条记录里做一个持久化标志，当有50条信息都标志是“未持久化”时，做一次数据库的写入，然后把信息置为“已持久化”，这种非实时写入的方式，可以提高一定的数据库效率，显示时，先从内存中取出，再查数据库。</p>
<p>还有一些问题，对不不同消息类型的处理方式不同，比如用户修改个人资料，并不是每次发生这样的动作都要做一次给朋友做一次“群发”的操作，如果遇到这个人在短时间内做了多次修改个人资料的操作，就给朋友发出多个消息，会产生垃圾信息，让人觉得很怪异，所以对于这样的操作会有一定的时效性，比如在一天之内的修改个人资料，就是一个消息，这时候的处理是更新，而不是插入。</p>
<p>以上是我对SNS中好友动态功能的设计思路，可能还有一些未想到的问题，还需要认真思考。</p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/sns-news-feed-design.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>从邮件服务商取得用户通讯录的方法</title>
		<link>http://i.laoer.com/grab-contacts-from-email-provide.html</link>
		<comments>http://i.laoer.com/grab-contacts-from-email-provide.html#comments</comments>
		<pubDate>Wed, 11 Mar 2009 05:47:39 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[Web2.0]]></category>
		<category><![CDATA[cURL]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SNS]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=143</guid>
		<description><![CDATA[我们在使用facebook、开心网这些SNS网站的时候，里面有一项功能，就是通过邮件邀请好友，它可以导出你在Hotmail、Gmail、Yahoo、网易、新浪等Web Mail里的通讯录，然后给这些好友发送邀请信，这种病毒式营销推广方式起到了非常好的效果，facebook、开心网这些网站得以迅速壮大，这项功能也成了SNS网站的标配，从技术角度，我们就来探讨一下实现这项功能的原理和方法。
先说Gmail、Hotmail，Google和MS还是非常强大的，Google提供了Account Authentication API，它允许第三方的网站通过它的认证服务后，通过Google的Service取得用户的数据，包括通讯录等，MS也有Windows Live ID服务，不过我对微软的东西研究的不深，MSDN上找到的Windows Live ID SDK的资料，http://msdn.microsoft.com/en-us/library/bb404787.aspx。
接下来说说其他邮件系统的取得方式，主要的原理就是通过模拟用户行为，登陆Web Mail系统，取得用户通讯录的信息，很多Web Mail都提供通讯录CSV格式的下载服务，我们取得这个CSV文件就可以了，网易的邮件系统似乎已经不提供CSV文件的下载，那只能通过通讯录页面的HTML分析，来取得信息，所以相对复杂一些，而Sohu的通讯录虽然前端采用了Ajax，但后端取得通讯返回的格式是Json，应该是最方便。
接下来说模拟用户行为，其实就是通过在自己服务器端向Web Mail发送相对的HTTP请求，而模拟出用户登陆的行为，在Linux下，我们用cURL这个组件，在编译PHP的时候把cURL编译进去，使PHP支持cURL，cURL非常好用，也非常强大，在libcurl里有大多数开发语言的支持，如果使用JAVA的话，还可以使用Apache的HttpClient。
我们要模拟出用户登陆Web Mail的过程，我们就要对通常情况下，登陆Web Mail的HTTP请求过程有所了解，HttpWatch是一个非常好的工具，在做为插件安装倒IE和FireFox上，在IE或是FireFox里就可以看到所有的HTTP请求的信息了。

我们看看网易163的邮件的登陆过程
00:00:00.000    跳转提示
+ 0.000        0.231    1543    2352    POST    200    text/html; charset=UTF-8    http://reg.163.com/login.jsp?type=1&#38;url=http://entry.mail.163.com/coremail/fcg/ntesdoor2?lightweight%3D1%26verifycookie%3D1%26language%3D-1%26style%3D35
0.231    1543    2352    1 request
00:00:00.462        0.177    0    0    GET    (History Cache)    image/x-icon    http://reg.163.com/favicon.ico
00:00:00.469    网易电子邮箱 &#8211; 简约3.0Beta
+ 0.000        0.118    1703    604    GET    302    Redirect to http://g4a30.mail.163.com/jy3/main.jsp?sid=gAJQIqzzbBwvsaVoDhzztmnXQvBRiMuz    http://entry.mail.163.com/coremail/fcg/ntesdoor2?lightweight=1&#38;verifycookie=1&#38;language=-1&#38;style=35&#38;username=xxx
+ 0.245        0.366    [...]]]></description>
			<content:encoded><![CDATA[<p>我们在使用<a href="http://www.facebook.com" target="_blank">facebook</a>、<a href="http://www.kaixin001.com" target="_blank">开心网</a>这些SNS网站的时候，里面有一项功能，就是通过邮件邀请好友，它可以导出你在Hotmail、Gmail、Yahoo、网易、新浪等Web Mail里的通讯录，然后给这些好友发送邀请信，这种病毒式营销推广方式起到了非常好的效果，facebook、开心网这些网站得以迅速壮大，这项功能也成了SNS网站的标配，从技术角度，我们就来探讨一下实现这项功能的原理和方法。</p>
<p>先说Gmail、Hotmail，Google和MS还是非常强大的，Google提供了<a href="http://code.google.com/intl/zh-CN/apis/accounts/" target="_blank">Account Authentication API</a>，它允许第三方的网站通过它的认证服务后，通过Google的Service取得用户的数据，包括通讯录等，MS也有Windows Live ID服务，不过我对微软的东西研究的不深，MSDN上找到的Windows Live ID SDK的资料，<a href="http://msdn.microsoft.com/en-us/library/bb404787.aspx">http://msdn.microsoft.com/en-us/library/bb404787.aspx</a>。</p>
<p>接下来说说其他邮件系统的取得方式，主要的原理就是通过模拟用户行为，登陆Web Mail系统，取得用户通讯录的信息，很多Web Mail都提供通讯录CSV格式的下载服务，我们取得这个CSV文件就可以了，网易的邮件系统似乎已经不提供CSV文件的下载，那只能通过通讯录页面的HTML分析，来取得信息，所以相对复杂一些，而Sohu的通讯录虽然前端采用了Ajax，但后端取得通讯返回的格式是Json，应该是最方便。</p>
<p>接下来说模拟用户行为，其实就是通过在自己服务器端向Web Mail发送相对的HTTP请求，而模拟出用户登陆的行为，在Linux下，我们用<a href="http://curl.haxx.se/" target="_blank">cURL</a>这个组件，在编译PHP的时候把cURL编译进去，使PHP支持cURL，cURL非常好用，也非常强大，在<a href="http://curl.haxx.se/libcurl/" target="_blank">libcurl</a>里有大多数开发语言的支持，如果使用JAVA的话，还可以使用Apache的<a href="http://hc.apache.org/httpclient-3.x/" target="_blank">HttpClient</a>。</p>
<p>我们要模拟出用户登陆Web Mail的过程，我们就要对通常情况下，登陆Web Mail的HTTP请求过程有所了解，<a href="http://www.httpwatch.com/" target="_blank">HttpWatch</a>是一个非常好的工具，在做为插件安装倒IE和FireFox上，在IE或是FireFox里就可以看到所有的HTTP请求的信息了。</p>
<p><img class="alignnone size-full wp-image-144" title="httpwatch" src="http://i.laoer.com/wp-content/uploads/2009/03/httpwatch.jpg" alt="httpwatch" width="600" height="293" /></p>
<p>我们看看网易163的邮件的登陆过程</p>
<p>00:00:00.000    跳转提示<br />
+ 0.000        0.231    1543    2352    POST    200    text/html; charset=UTF-8    http://reg.163.com/login.jsp?type=1&amp;url=http://entry.mail.163.com/coremail/fcg/ntesdoor2?lightweight%3D1%26verifycookie%3D1%26language%3D-1%26style%3D35<br />
0.231    1543    2352    1 request<br />
00:00:00.462        0.177    0    0    GET    (History Cache)    image/x-icon    http://reg.163.com/favicon.ico<br />
00:00:00.469    网易电子邮箱 &#8211; 简约3.0Beta<br />
+ 0.000        0.118    1703    604    GET    302    Redirect to http://g4a30.mail.163.com/jy3/main.jsp?sid=gAJQIqzzbBwvsaVoDhzztmnXQvBRiMuz    http://entry.mail.163.com/coremail/fcg/ntesdoor2?lightweight=1&amp;verifycookie=1&amp;language=-1&amp;style=35&amp;username=xxx<br />
+ 0.245        0.366    1664    6788    GET    200    text/html;charset=GBK    http://g4a30.mail.163.com/jy3/main.jsp?sid=gAJQIqzzbBwvsaVoDhzztmnXQvBRiMuz<br />
+ 0.422        0.158    0    0    GET    (Cache)    text/css    http://mimg.126.net/p/jy3style/lib/0903090940/jscss/globle.css<br />
+ 0.659        0.087    0    0    GET    (Cache)    application/x-javascript    http://mimg.126.net/p/jy3style/js/0903090940/tools.js<br />
+ 0.816        0.067    0    0    GET    (Cache)    text/css    http://mimg.126.net/p/jy3style/lib/0903090940/cmcss/skin_blue.css<br />
+ 0.998        0.578    1586    5521    GET    200    text/html;charset=GBK    http://g4a30.mail.163.com/jy3/top.jsp?sid=gAJQIqzzbBwvsaVoDhzztmnXQvBRiMuz<br />
+ 1.015        0.624    1589    24844    GET    200    text/html;charset=GBK    http://g4a30.mail.163.com/jy3/folder.jsp?sid=gAJQIqzzbBwvsaVoDhzztmnXQvBRiMuz<br />
+ 1.025        0.316    1590    10490    GET    200    text/html;charset=GBK    http://g4a30.mail.163.com/jy3/welcome.jsp?sid=gAJQIqzzbBwvsaVoDhzztmnXQvBRiMuz<br />
+ 1.034        3.174    1592    2043    GET    200    text/html;charset=GBK    http://g4a30.mail.163.com/jy3/justfresh.jsp?sid=gAJQIqzzbBwvsaVoDhzztmnXQvBRiMuz<br />
+ 1.280        0.439    0    0    GET    (Cache)    text/css    http://mimg.126.net/p/jy3style/lib/0903090940/jscss/globle.css<br />
+ 1.632        0.407    0    0    GET    (Cache)    text/css    http://mimg.126.net/p/jy3style/lib/0903090940/jscss/globle.css<br />
+ 1.647        0.432    0    0    GET    (Cache)    text/css    http://mimg.126.net/p/jy3style/lib/0903090940/jscss/welcome2.css<br />
+ 1.876        0.235    0    0    GET    (Cache)    text/css    http://mimg.126.net/p/jy3style/lib/0903090940/jscss/globle.css<br />
+ 2.179        0.117    0    0    GET    (Cache)    application/x-javascript    http://mimg.126.net/p/jy3style/js/0903090940/tools.js<br />
+ 2.263        0.167    0    0    GET    (Cache)    application/x-javascript    http://mimg.126.net/p/jy3style/js/0903090940/tools.js<br />
+ 2.354        0.207    0    0    GET    (Cache)    application/x-javascript    http://mimg.126.net/p/jy3style/js/0903090940/tools.js<br />
+ 2.488        0.209    0    0    GET    (Cache)    text/css    http://mimg.126.net/p/jy3style/lib/0903090940/cmcss/skin_blue.css<br />
+ 2.614        0.152    0    0    GET    (Cache)    text/css    http://mimg.126.net/p/jy3style/lib/0903090940/cmcss/skin_blue.css<br />
+ 2.619        0.192    0    0    GET    (Cache)    application/x-javascript    http://mimg.126.net/p/jy3style/js/0903090940/welcome.js<br />
+ 2.740        0.325    0    0    GET    (Cache)    text/css    http://mimg.126.net/p/jy3style/lib/0903090940/cmcss/skin_blue.css<br />
4.208    9724    50290    20 requests<br />
00:00:00.878        0.124    0    0    GET    (History Cache)    image/x-icon    http://www.163.com/favicon.ico<br />
00:00:03.572    网易电子邮箱 &#8211; 简约3.0Beta<br />
+ 0.000        0.541    0    0    GET    (Cache)    text/html; charset=GB2312    http://mimg.163.com/tianqi/city_simple/58367_090311.html<br />
+ 0.531        0.715    1424    250    GET    304    text/css    http://mimg.163.com/jy3style/lib/jscss/ifr_weather2.css<br />
+ 1.614        0.245    0    0    GET    (Cache)    image/gif    http://mimg.163.com/jy3style/lib/images/weather2.gif<br />
1.859    1424    250    3 requests</p>
<p>首先，将用户名和密码POST到http://reg.163.com/login.jsp?type=1&amp;url=http://entry.mail.163.com/coremail/fcg/ntesdoor2?lightweight%3D1%26verifycookie%3D1%26language%3D-1%26style%3D35，reg.163.com是网易通行证，后面的url是用户登陆网易通行证后要转向的地址，在这里我们看到就是http://entry.mail.163.com/coremail/fcg/ntesdoor2，这就是网易邮件的入口，在我们模拟登陆的时候，可以不传这个url过去，至于用户名和密码表单的name，看mail.163.com的HTML代码就知道了。相关错误处理，在POST到http://reg.163.com/login.jsp这个地址之后，返回的信息要取得的，因为如果用户输错了用户名或是密码，还是应该要提示用户的，而且在错误的情况下，也不用往下进行了，reg.163.com返回的错误页面里有“您的密码不正确”或是“用户名不正确”这样的信息，以此就可以判断用户是否成功登陆了。</p>
<p>之后我们要模拟用户访问http://entry.mail.163.com/coremail/fcg/ntesdoor2?lightweight=1&amp;verifycookie=1&amp;language=-1&amp;style=35&amp;username=xxx，就是登陆邮件的过程，注意，这里是个GET方法，用POST方法是不行的，访问entry.mail.163.com这个URL之后，会返回一个302码，就是要Redirect转向，到http://g4a30.mail.163.com/jy3/main.jsp?sid=gAJQIqzzbBwvsaVoDhzztmnXQvBRiMuz这个地址，这也就是大家看到的邮件登陆进去的首页了，注意这个sid要抓出来，应该是登陆的一个token，还有http://g4a30.mail.163.com这个地址，网易邮件是个集群，有非常多的服务器，你们每次上去的服务器是随随机的，用你的sid访问其他服务器也是没问题的，比如http://g1a98.mail.163.com/jy3/main.jsp?sid=gAJQIqzzbBwvsaVoDhzztmnXQvBRiMuz，所以这个服务器地址你可以写死。</p>
<p>解析来我们要看看网易邮件通讯录的URL，在UI看到是http://g4a30.mail.163.com/jy3/address/addrlist.jsp?sid=gAJQIqzzbBwvsaVoDhzztmnXQvBRiMuz&amp;gid=all，我们模拟用户访问这个URL，然后抓取这个页面的内容HTML，分析一下，就可以了，在PHP里有个很好的HTML Parser工具<a href="http://simplehtmldom.sourceforge.net/" target="_blank">PHP Simple HTML DOM Parser</a>，可以像jQuery一样取得页面元素，这样就很方便的取得页面信息了。</p>
<p>其他一些Web Mail的登陆过程分析也是类似的，如果是取得CSV文件就更简单了，通过取到的通讯录内容，就可以在SNS网站上邀请了。</p>
<p>在这里我向国内这些大的门户网站或是Mail服务商提个建议，现在的互联网是一个开放化、平台化的趋势，网站应该开放自己的资源，可以让第三方的的应用更方便的访问，固步自封是不能发展的，试想如果QQ开放他的好友平台，引入第三方应用，那它将轻松超过Facebook，成为世界第一大SNS社区。</p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/grab-contacts-from-email-provide.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Twitter的Libraries</title>
		<link>http://i.laoer.com/twitter-libraries.html</link>
		<comments>http://i.laoer.com/twitter-libraries.html#comments</comments>
		<pubDate>Fri, 13 Feb 2009 02:50:39 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[Web2.0]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=64</guid>
		<description><![CDATA[在公司上不了http://apiwiki.twitter.com/，难道又被封了？找个代理上去看看吧，把它的Libraries记录下，备用
ActionScript/Flash

TwitterScript by Michael Galpin. AS3 API, originally from Twitter, now open sourced.
SWX Twitter API by Aral Balkan.


C++

QTwitLib by Bradley Lackey &#38; Maks Zolin. C++ library for Linux, Windows, and Mac.  Currently in beta.


C#/.NET

Yedda Twitter Library by Yedda. Every Twitter API method has an equivalent .NET method in this wrapper library.
TwitterooCore API by Eric Willis/RareEdge Design Group. Binary [...]]]></description>
			<content:encoded><![CDATA[<p>在公司上不了<a href="http://apiwiki.twitter.com/" target="_blank">http://apiwiki.twitter.com/</a>，难道又被封了？找个代理上去看看吧，把它的Libraries记录下，备用</p>
<h1><span style="font-size: medium;">ActionScript/Flash</span></h1>
<ul>
<li><a href="http://code.google.com/p/twitterscript/">TwitterScript</a> by Michael Galpin. AS3 API, originally from Twitter, now open sourced.</li>
<li><a id="p-b47a634da6f3697aaf7a482040508de2655f7ee3" class="WikiLink" name="p-b47a634da6f3697aaf7a482040508de2655f7ee3" href="http://apiwiki.twitter.com/SWX+Twitter+API">SWX Twitter API</a> by Aral Balkan.</li>
</ul>
<p><a name="C++"></a></p>
<h1><span style="font-size: medium;">C++</span></h1>
<ul>
<li><a href="http://twitlib.googlecode.com/">QTwitLib</a> by Bradley Lackey &amp; Maks Zolin. C++ library for Linux, Windows, and Mac.  Currently in beta.</li>
</ul>
<p><a name="C/NET"></a></p>
<h1><span style="font-size: medium;">C#/.NET</span></h1>
<ul>
<li><a href="http://devblog.yedda.com/index.php/twitter-c-library/">Yedda Twitter Library</a> by Yedda. Every Twitter API method has an equivalent .NET method in this wrapper library.</li>
<li><a href="http://rareedge.com/twitteroo/blog/">TwitterooCore API</a> by Eric Willis/RareEdge Design Group. Binary .NET library that can be used in any .NET project.</li>
<li><a href="http://code.google.com/p/twitterizer/">Twitterizer</a> originally by DigitallyBorn, but now open source. Written for .NET 2.0.</li>
<li><a href="http://code.google.com/p/tweetsharp/">tweet#</a> by Daniel Crenna. &#8220;100% coverage of the REST and Search APIs&#8221;.</li>
</ul>
<p><a name="Javanbsp"></a></p>
<h1><span style="font-size: medium;">Java</span></h1>
<ul>
<li><a href="http://yusuke.homeip.net/twitter4j/en/index.html">Twitter4J</a> by Yusuke Yamamoto.  BSD licensed and Maven aware pure java interface for the Twitter API.</li>
<li><a href="http://code.google.com/p/java-twitter/">java-twitter</a> by DeWitt Clinton.  Pure java interface for the Twitter API.</li>
<li><a href="http://www.winterwell.com/software/jtwitter.php">jtwitter</a> by Daniel Winterstein. Open-source pure Java Interface to Twitter.</li>
</ul>
<p><a name="ObjectiveC/Cocoa"></a></p>
<h1>Objective-C/Cocoa</h1>
<ul>
<li><a href="http://mattgemmell.com/2008/02/22/mgtwitterengine-twitter-from-cocoa">MGTwitterEngine</a> by Matt Gemmell.  Integrate Twitter support into your Cocoa app.</li>
</ul>
<p><a name="Perl"></a></p>
<h1>Perl</h1>
<ul>
<li><a href="http://search.cpan.org/%7Ejmcada/App-Tweet-1.02/lib/App/Tweet.pm">App::Tweet</a> by Joshua McAdams.  Tweet on Twitter from the command line.</li>
<li><a href="http://search.cpan.org/%7Ecthom/Net-Twitter-1.08/lib/Net/Twitter.pm">Net::Twitter</a> by Chris Thompson.  Perl interface to Twitter.</li>
<li><a href="http://search.cpan.org/%7Edmaki/Twitter-Shell-0.03/lib/Twitter/Shell.pm">Twitter::Shell</a> by Daisuke Maki.  Twitter from your shell.</li>
</ul>
<p><a name="nbsp"></a></p>
<p><a name="PHP"></a></p>
<h1>PHP</h1>
<ul>
<li><a href="http://www.phpclasses.org/browse/package/4075.html">My Twitter</a> by Andres Scheffer. Set and retrieve a Twitter user&#8217;s status.</li>
<li><a href="http://www.phpclasses.org/browse/package/4216.html">Twitter</a> by Felix Oghina.  Update the status of a Twitter user.</li>
<li><a href="http://github.com/jdp/twitterlibphp">TwitterLibPHP</a> by Justin Poliey.  Manipulate a Twitter user account.</li>
<li><a href="http://lab.arc90.com/2008/06/php_twitter_api_client.php">Arc90_Service_Twitter</a> by Matt Williams.  Open source Twitter API client.</li>
<li><a href="http://code.google.com/p/php-twitter/">PHP Twitter</a> by Aaron Brazell, original code from David Billingham.</li>
<li><a href="http://pear.php.net/package/Services_Twitter">PEAR Services_Twitter</a> by Joe Stump and David Jean Louis.</li>
<li><a href="http://classes.verkoyen.eu/twitter/">PHP Twitter</a> by Tijs Verkoyen. BSD Licensed.</li>
</ul>
<p><a name="nbsp"></a></p>
<p><a name="PL/SQL"></a></p>
<h1>PL/SQL</h1>
<ul>
<li><a href="http://apextoday.blogspot.com/2008/06/getting-friends-timeline-from-twitter.html">OraTweet</a> by Noel Portugal. PL/SQL procedures to get friends timeline and post updates.</li>
</ul>
<p><a name="nbsp"></a></p>
<p><a name="Python"></a></p>
<h1>Python</h1>
<ul>
<li><a href="http://code.google.com/p/python-twitter/">python-twitter</a> by DeWitt Clinton. This library provides a pure Python interface for the Twitter API.</li>
</ul>
<ul>
<li><a href="http://andrewprice.me.uk/projects/twyt/">python-twyt</a> by Andrew Price. BSD licensed Twitter API interface library and command line client.</li>
<li><a href="http://github.com/dustin/twitty-twister/tree/master">twitty-twister</a> by Dustin Sallings.  A Twisted interface to Twitter.</li>
</ul>
<p><a name="Ruby"></a></p>
<h1>Ruby</h1>
<ul>
<li><a id="p-d2decd2cbaebb69086c75e7e302cdc868bc3d55d" class="WikiLink" name="p-d2decd2cbaebb69086c75e7e302cdc868bc3d55d" href="http://apiwiki.twitter.com/Twitter4R">Twitter4R</a> by Susan Potter.  Open-source Ruby library for the Twitter REST API.</li>
<li><a href="http://rubyforge.org/projects/twittery">Twittery</a> by Chris Ledet.  Lightweight class for Twitter&#8217;s API.</li>
<li><a href="http://twitter.rubyforge.org/">Twitter</a> by John Nunemaker.  Command line twits and an api wrapper using Hpricot.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/twitter-libraries.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
