[转载]QQ空间日志抓器---我的第一个winform小应用(多线程,附源码) - think_fish - 博客园

mikel阅读(1019)

[转载]QQ空间日志抓器—我的第一个winform小应用(多线程,附源码) – think_fish – 博客园.

    (好几个博友都提到了假死的问题,可能是我之前测试的环境网络状态良好,然后机器配置还可以,所以没有看到假死的现象。刚刚换了个环境,假死比较明显。所以各位敬请期待多线程的版本。)

首先非常感谢各位前辈的指点,将程序改成了多线程版本,假死问题已经解决了。对代码也做了部分优化,之前用单独的一个请求去抓第一页然后再用另外的请求去抓取第一页以后的也做了下修改,突然发现用后面的方法一样可以抓取到第一页的数据,所以第一部就是多此一举了。 

    忙豁了近两个星期,终于完工了,可能对于多数人来说这个应用没有什么价值也没有什么挑战性,但对于初次接触winform的我来说还算是小有成就感的。

先来两张程序的截图吧 

      

     界 面比较简单,现在复杂的也不会。还有一个其他空间的单选按钮,这个功能还没有实现,是准备后面拓展功能的。两个文本框第一个为输入QQ号码的,第二个是输 入日志的总页数的,日志的页数分析了很久实在没有找到,所以只好出此下策让用户自己输入了。这个抓取器不能抓取设置了访问权限的空间,哪怕知道问题的答案 也没有办法获取。之后考虑加一个密码输入框,再模拟一个空间主人的权限去抓取试试。 

      

      输入QQ号与日志页数(对于QQ号与日志页数都还没有做验证的-_-!!),页面会自动跳转到空间的日志列表页,点击如上图顶端的开始抓取,程序就会自动运行了。 下面的灰色部分是显示日志抓取的进度。

 

   敲代码的时间比较短,基本上大量的时间都花在了分析上面。QQ空间属于比较另类的博客,整个页面就是一个大的母版页中间的日志列表,日志内容以及其他的相 册什么的全部都是用ajax请求动态加载的,所以之前一直觉得奇怪QQ空间上并没有多大的图片或者什么内容为什么那么耗资源。ajax请求动态加载的内容 都是存在内存里面的。

   最开始是准备用Console程序来解决这个问题,因为之前因为工作的关系写过一个小蜘蛛,心想改一改应该就差不多了,但因为之前的程序逻辑相对比较复杂,要改也不知道从何改起,然后跟博友交流之后选择了用webBrowser。

   WebBrowser的默认属性DocumentText直接就可以把页面中的文本获取到,但是问题来了,这个根本无法获取到动态加载的内容。在 firebug下看,加载的内容都是在一个iframe里面,这时候就一直以为是直接获取iframe的src就可以了。然后想了很多办法想用 webBrowser如何获取iframe里面的内容。就这个耗了两个晚上的时间。这时都还没有想到这边iframe都是ajax动态添加的,所以想要获 取到加载后的iframe也没有办法实现。

   再继续在网上寻找方案,偶然间看到一个问题,如果获取动态加载的所有内容,虽然在那个问题中没有获取到答案,但是基本肯定了QQ空间的日志部分就是动态加 载的。这时候就静下心来在firebug下仔细的分析发送的请求,自己试着写了个GET请求,把firebug下看到的参数拼成个字符串,果然获取到了日 志内容,但接着而来的问题就是获取到的内容是加密过的,GZIP加密,继续在网上找方法解密。解密成功后就是N多的正则匹配了。废话不多说,先上一个流程 图。

 

 

 

个人觉得代码中最关键的部分就是发送请求,然后分析HTML用正则匹配出自己想要的部分。

///
/// 发送一个GET请求
///

///请求的url地址 ///请求的参数集合 ///请求的编码格式 ///接收的编码格式 ///
public static string SendGetRequest(string url, NameValueCollection parameters, Encoding reqencode, Encoding resencode)
{
StringBuilder parassb = new StringBuilder();
if (null != parameters)
{
foreach (string key in parameters.Keys)
{
if (parassb.Length > 0)
parassb.Append("&");
parassb.AppendFormat("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(parameters[key]));
}
}
if (parassb.Length > 0)
{
url += "?" + parassb;
}
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "GET";
req.Accept = "*/*";
req.Headers.Add("Accept-Encoding: gzip");
req.KeepAlive = true;
req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
req.MaximumAutomaticRedirections = 3;
req.Timeout = 600000;
string result = String.Empty;

//读取回应
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
// 将回应全部读入一个 MemoryStream:
MemoryStream ms = new MemoryStream();
Stream res = response.GetResponseStream();
byte[] buffer = new byte[8192];
while (true)
{
int read = res.Read(buffer, 0, 8192);
if (read == 0)
{
// 如果服务器用的是 gzip 的话,只能靠读不出更多数据来判断是否已经读完
Console.WriteLine("Response is terminated due to zero byte reception.");
break;
}
else
{
ms.Write(buffer, 0, read);
}
}
//ms倒回开头
ms.Seek(0, SeekOrigin.Begin);
// 用 GZipInputStream 包裹:
GZipInputStream gzip = new GZipInputStream(ms);
MemoryStream ms2 = new MemoryStream();
try
{
byte[] buffer1 = new byte[1]; // 一点一点读——因为这个服务器的gzip没有Footer,读到结尾的时候会出错,所以为了把最后一个字节都读出来,只能一点一点读
while (true)
{
int read = gzip.Read(buffer1, 0, 1);
if (read == 0) break;
ms2.Write(buffer1, 0, read);

}
}
catch (Exception sa)
{
Console.WriteLine("Exception! " + sa.ToString());
}
Console.WriteLine("Unzipped.");
// 将 ms2(解压后的内容)保存到文件
//, System.Text.Encoding.GetEncoding("gb2312")
Stream fs;

fs = File.Create("r00000000000.txt");

ms2.Seek(0, SeekOrigin.Begin);
ms2.WriteTo(fs);
fs.Close();
//using (StreamReader reader = new StreamReader(req.GetResponse().GetResponseStream(), resencode))
//{
// result = reader.ReadToEnd();
//}
result = System.Text.Encoding.GetEncoding("GB2312").GetString(ms2.ToArray());
return result;
}

        上面的代码就是发送GET请求并获取HTML的一个方法,其中包括了解压的过程。解压的代码部分我没有仔细研究,但是个人认为这样做过于繁琐,有时间会要做进一步的优化。日志列表与日志的主体内容都用的这个方法。解压需要添加如下的引用

using System.IO.Compression;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksums;

using ICSharpCode.SharpZipLib.GZip;

    这个日志取器有一个问题就是如果对方的空间设置了访问权限,比如需要密码才能访问,或本来就没有该问权限的是没有办法抓取下来的,无法获取到列表页的ID,返回的HTML中提示没有权限。这个问题可能也还需要一段时间来分析。

 

现 在我把源码放上来,各位要是有兴趣的可以下载看看,有什么问题或者有什么好的建议非常希望大家能反馈给我,我很想得到高手们的一些指点。 对于这个应用其间还存在很多的不足,但是因为时间的关系,先在这里总结一下,主体部分的抓取分析还是出来了。真诚的希望各位能多给意见,希望能从中再学习 到一些更宝贵的经验。小弟先在此谢过了。

 

渔歌QQ空间日志抓取器源码下载/Files/think_fish/QQZoneApplicantionThread.rar

渔歌QQ空间日志抓取器源码SP1(新增评论抓取功能)下载/Files/think_fish/QQZoneApplicantionSP1.rar

[转载]游戏开发手记:数据存储 - newgame - 博客园

mikel阅读(839)

[转载]游戏开发手记:数据存储 – newgame – 博客园.

最近主要忙着功能开发,一时感觉没什么值得分享的。索性就数据存储这个话题聊聊,顺便自己也理一下思路,希望后面做起来能顺利一点,目前我们项目数据存储还完全没做,只是简单的把每个玩家数据单独存一个文件在硬盘上:-)

关于性能

网络游戏的数据存储有其特殊性。游戏是交互性比较强的产品,对系统响应时间的要求特别高,如果在处理逻辑时同步地去进行数据库IO是不可接受的。另外玩家在游戏过程中数据变化非常剧烈,也就是说写数据的频率会特别高,如果设计不合理,数据存储是很容易成为系统瓶颈的。

不妨拿BBS系统来做一个比较。我们逛BBS时大部分时间都是在浏览,相比之下发帖行为是小概率事件。用户花20分钟写完一个帖子点击发布按钮,3 秒钟或10秒钟后提示发送成功都是完全可以接受的,甚至提示发送失败要求用户重新再发一次也不是什么大问题。所以对于上述BBS系统,在用户提交请求时同 步去读写数据库是完全可行的。而网络游戏要做的是同时支持数千人以数秒为间隔不停地发贴,要保证响应时间控制在数毫秒内,还要保证发出去的帖其他人能立即 看到。

业内的通行做法是将数据库的职能尽量简化,只拿数据库做数据最终的备份仓库来用。即在服务器进程启动时从数据库中加载所有的全局数据,在玩家上线时 从数据库中加载玩家的所有数据,之后所有的逻辑操作都在内存中进行,从而避免游戏过程中读写数据库带来的响应过慢。变化的数据以一定的时间间隔(一般为数 分钟)异步写入数据库,这样就缓解了数据库写的压力。

很显然,这样一来数据库所需要的功能是如此简单,只需要有GET和SET两个接口就完全够用。所以选择合适的NoSQL数据库来提高数据存取性能也 就理所当然了,必要的时候加入memcache来提高读数据的速度也是顺理成章的事情了。这也是我们现在完全没有数据库只是存文件也能正常开发功能的原因 ——说到底读文件和写文件也就是GET和SET操作嘛,到时候换一下接口就行了。

当然了这套做法是从传统的MMORPG演化而来的。现在大量的手游交互性比较弱,实时性不强,用户量小时处理逻辑时直接去读写数据库往往也完全过得去。但是在系统设计阶段就把数据存储的隐患避免掉还是有好处的,万一哪天游戏火了呢?云风的博客上有具体的案例可以参考:谈谈陌陌争霸在数据库方面踩过的坑(排行榜篇)

关于容灾

丢档可能是游戏服务器程序员永远的噩梦,虽然没亲身经历过,我相信不幸遭遇运营中游戏丢档并处理过数据恢复的程序员心中应该都有不可磨灭的创伤……

就像策划往往不理解为什么写一个100%不会崩溃的程序那么难,软件程序员往往也不理解为什么服务器主机会宕掉,硬盘会直接被写废。实际上在硬件工 程师看来,电脑硬件不断出各种问题才是正常的吧。嗯我想说的是,我们应该在系统设计时就应该考虑好容灾,尽量降低系统故障带来的损失。

进程崩溃

根据前面的讨论,为了快速响应客户端请求,也为了降低数据库写的压力,变化的数据并没有立即写进数据库,而是以一定的时间间隔存盘。这个取巧的做法 其实有很大的问题:我们修改完内存中的数据后就告知客户端操作完成,但这时数据并没有成功落地,如果这时游戏进程异常崩溃就会造成回档,回档的最大时长为 存盘间隔(数分钟)。

那么游戏进程能不能不崩溃呢?有可能,但是比较难,因为游戏进程往往复杂并且迭代很疯狂,要100%保证不崩我觉得还得看具体的语言和框架。还是那句话,我们尽量在设计阶段就把风险规避掉。

主要思路就是用一个稳定的进程来分担风险。前面提到可以加入memcache进程提高读数据的性能,很自然地我们可以利用memcache这个稳定 的进程来暂存数据。方案是这样的:每台有游戏进程运行的主机上都启一个memcache进程并一直运行,读数据时先从memcache读,若读取失败再到 数据库读取,当玩家数据变化时同步写入memcache。这样即使游戏进程崩溃,重启后会首先从memcache中读出正确的数据。

往memcache写数据一般是通过HTTP或socket,会对客户端请求响应速度略有影响,由于两进程在同一主机,一般来说是可以接受的。如果 游戏对响应速度特别敏感,可以用共享内存的方式进行进程间通信,前几年在畅游做MMORPG就是用的这种方式,只是共享内存并不易实现,程序复杂度比较 高。这两种方式没有对错之分,只是需要根据游戏的需求权衡。

主机崩溃

按照之前的设计,游戏进程和memcache都在同一主机,一旦主机崩溃难免会造成丢档。这依旧是一个需要权衡的问题。

  1. 如果小概率的短时间丢档可以忍受,那么就这样了,做好性能测试将存盘时间尽量缩短点就行。毕竟linux是比较稳定的系统,主机崩溃并不是常态。真出了问题等玩家投诉时查日志补偿回去就好了。
  2. 如果游戏对响应速度不敏感,那么将memcache移至另一主机。暂且认为两台主机同时崩溃的概率可以忽略不计。
  3. 如果想两全其美,可以考虑保留原memcache的基础上在另一主机上新增一级memcache。当然这样一来系统就更复杂了,我个人并不推荐。
数据库损坏

游戏数据库硬盘往往使用RAID技术,理论上几乎不可能出现损坏。但是就怕碰上天灾人祸,机房自然灾害也好,程序员误操作也好,如果不做好备份一旦出了问题绝对是致命的,直接毁掉一家公司也不是没可能。

数据库备份从技术上其实没什么好说的,就是主从备份读写分离什么的。这里我想分享之前的一点经历。

在上家公司用的数据库是Tokyo Cabinet, 这是一款很简洁的KV数据库。问题是貌似很少有人用,文档也比较匮乏,后来我们在实际部署时不知道是bug还是配置不对,主从数据库总是会有些不同步。折 腾了一段时间后我们干脆换了思路,不依赖主从同步机制了,直接在存盘的时候分别往两个数据库存盘。因为存盘过程是异步的,系统的瓶颈并不在这儿,所以存一 次还是存两次也就无所谓了。如果对数据库的运维不熟悉而头疼的话可以考虑下这个思路:-)

想象中的proxycache

游戏服务器领域其实比较封闭,上文涉及到的NoSQL、memcache都是从Web发展出来的组件,某种程度上来说并不是特别适合游戏服务器。上 面的设计中游戏进程承担了太多数据存储的功能,比如对玩家数据的变化一方面要同步存入memcache,一方面又要掐表计时并按间隔存入数据库;再比如读 数据时先要去memcache中查询,发现缓存失效时还要去数据库中读取。

我认为可以把数据存储部分完全从游戏进程中抽离出来,只提供给游戏进程GET和SET接口,这样游戏进程就可以专注于处理逻辑了。抽离出来的进程也就是想象中的proxycache了,可以用来替代前面设计中的memcache。

proxycache是两种角色的结合体。

首先它作为proxy是游戏进程访问数据库的代理。收到GET请求时自已去向数据库请求后转发回游戏进程,收到SET请求时按照一定的间隔写入数据 库。可以在SET参数中加入延时参数,比如不重要的数据变化可以接受5分钟内存盘,重要的数据变化可以要求立即写入数据库。proxycache内部根据 请求参数排好优先队列后依次存储,这样可以将异常宕机带来的损失降至最低。

其次它作为cache能缓存数据。从数据库读回来的数据和游戏进程写进来的数据都可以缓存起来,不但实现了memcache的功能还简化了游戏进程的逻辑。

当然了现在都只是纸上谈兵而已,希望之后抽个空给实现出来:-)

数据库的选择

我们项目数据库完全没开始做的一个主要原因是还没选好用什么数据库。目前我对数据库的期望是这样的:首先是足够简单的NoSQL数据库,最好是最简 单的Key-Value,根据我们的设计Key只需要string,Value只需要Blob就完全够用了;然后希望是做为独立进程运行;再就是运维要方 便,如果数据文件只有一个那是极好的。

先是看了Redis。坦率地说,我认为Redis并不适合网络游戏。Redis本来是设计为内存数据库,在数据落地方面处理得比较粗 糙,bgsave采用的fork方式,必须预留出足够的内存,怎么都觉得浪费。而且网络游戏运营一段时间后往往数据库中大部分都是冷数据,Redis不分 青红皂白一股脑读进内存实在是有些不可接受。可能还是用作缓存比较对路吧。

再就是MongoDB。功能强大但是复杂度大大超出了我们的期望,出了问题怕是难以驾驭。

现在主要是两个想法:

  1. 用比较熟悉的Tokyo Cabinet,只是这个项目已经多年没有更新了,也没有社区什么的。现在我们用Go语言,自己写个driver肯定是免不了的了。
  2. rocksDB或levelDB的封装。可选项有LedisDBSSDB,还有很多类似的,可真心没法判断是不是靠谱ToT

各位有了解合适的吗?求推荐!

不要只做自媒体人的自媒体

mikel阅读(990)

做了自媒体,结果认识得都是自媒体人,大家互相转发、阅读彼此的文章,点赞评论,玩儿得很high

其实不知道自己已经在一个圈子里面原地打转儿,自己把自己封闭了起来,互联网那么大,很容易就自我封闭了,看似身边很多人,其实这些人都是一个圈子的,没啥新鲜感,也没啥新想法,都是在那谈一个内容,你看我的,我看你的,然后互相帮忙推广

这是不正常的,不开放,需要兼容并蓄的去外面的世界走走看看,多接触不同圈子的人才能有所收获和成长,尽管自媒体人越来越多,各行业的都有,可是大家的能力都是有限的,写日志写个三个月基本上就了解了这个人的能力怎么样,再剩下的就是看他的收获总结的居多,

我也一样,哪那么多干货可发!我又不是神,总得有个消化的过程。

所以说不要做自媒体人的自媒体,那样就没啥意思了。

今天收获很多,转载了两篇很有益的文章,才发现最近一段时间,自己有点儿封闭了,每天看日志,点赞,自己都麻木了,很少像以前那么有时间做项目,推广,建站,写程序,研究分析些东西。

自媒体很好,但是听太多,看太多容易迷失不说,时间都不知不觉的没了,正事儿没干,一天就过去了。

建议还是做好时间管理,别耽误正事儿,闲暇时间看看大家发的日志,挺好。

时间管理和资源管理都是门儿学问,今天转载的文章让我很受益,也推荐大家看看

信任造就微商 也带来了信任危机

mikel阅读(950)

熟人买卖好做,大家有目共睹,微商就是抓住了信任这点儿,才风风火火的让很多人眼热儿

可是信任危机也随之而来,太多人的朋友圈都被刷烂了,刷烦了,每个人一下子都知道刷朋友圈能卖货,结果造成很多人看到晒面膜的都害怕,直接屏蔽了

这就是信任危机的开端,在这么做下去,只能越做越窄,就像雾霾一样,不是一天两天造成的,是过渡透支造成的,一旦出现信任危机,很难挽回

信任如何保持良性循环,还是需要各个行业的数据流通,就像银行和保险行业一样,信用记录成为你在社会上赖以生存的根本,必须要有个行为准则让人们重视自己的信用。

杀熟不能长久,只能让自己缺乏信任,只有做成诚信卖良心产品才能长远发展

微商投机取巧的人太多,一锥子买卖,让人不寒而栗,做烂了一个行业,再做下一个,不可取

从微商再说到自媒体,大家都在拉粉丝,做圈子,找同频的,如果不重视信用,同样会造成恶性循环,让人们打上圈钱的标签,就很难恢复了

[转载]Android自动化测试工具合集 - 杰深的个人博客 - 博客频道 - CSDN.NET

mikel阅读(844)

[转载]Android自动化测试工具合集 – 杰深的个人博客 – 博客频道 – CSDN.NET.

安卓应用自动化测试工具之一 – PerfectoMobile

 

该工具的官方网址:PerfectoMobile.com
背景:美国/以色列公司,该工具已有6年历史。
突出特点:测试脚本可以跨平台(Android/iOS/Blackberry…)执行,号称拥有市面上所有智能机。

 

接下来我们尝试从以下几个方面了解该工具:
脚本编辑器
它有两种方式:一、纯Web的脚本制作界面;二、近年新开发的QTP插件;

 

脚本语言
Web端的是基于关键字的脚本设计器“ScriptOnce”;如果用QTP插件,则是VBScript。

 

是否支持录制脚本
Web端是鼠标拖拽的方式制作脚本;QTP插件是否可以支持录制就不清楚了。

 

结果验证
通过对比界面图像来验证测试结果

 

价格
Web端对于设备的使用是按小时收费。QTP插件的费用还不清楚。相信不会比QTP贵吧~ 🙂

安卓应用自动化测试工具之二 – TestDroid

 

该工具的官方网址:TestDroid.com
背景:芬兰公司,近两年刚起步,去年年底开始做云平台。
突出特点:测试脚本可以录制,并转成Robotium/MonkeyRunner脚本。

 

接下来我们尝试从以下几个方面了解该工具:
脚本编辑器
其实就是Eclipse插件。

 

是否支持录制脚本 & 脚本语言
可以用录制的方式产生脚本,并生成Robotium or MonkeyRunner的脚本语言。但这个前提是一定要有被测应用的源代码。官方文档虽然说不

 

用源码也能测,只是抓不到R-Class级别的对象。但笔者试了一下没有源码的apk,好像文本框的顺序还无法辨认。

 

结果检查
貌似可以写判断语句。

 

价格
USD99/Month,买够一年还可以打5折。云端价格暂未公开。

安卓应用自动化测试工具之三 – DroidPilot

 

该工具的官方网址:DroidPilot.cn
背景:深圳公司,今年刚起步。
突出特点:抓取对象能力较强;工具仿制QTP,易于测试人员上手。

 

接下来我们尝试从以下几个方面了解该工具:
脚本编辑器 & 脚本语言
自己写的脚本编辑器,仿QTP使用VBScript语言。

 

是否支持录制脚本
使用脚本设计器,通过抓取的对象设计脚本,然后把设计好的脚本转换成VBScript进行深加工。据开发团队声称,测试工程师在制作脚本的

 

时候录制的效率不一定有制作的效率高,且也不一定灵活。不过他们表明会在后续版本开发录制功能。

 

结果检查
有类似QTP的检查点语句Checkpoint; 也可以写条件判断语句对比属性值。

 

价格
未定,目前开放试用下载,试用期限不够的话还可以跟他们谈。

安卓应用自动化测试工具之四 – LessPainful

 

该工具的官方网址:lesspainful.com
背景:丹麦公司,这两年刚起步。
突出特点:支持iOS & Android;只需提供被测apk和脚本到他们的网站即可测试;脚本很特别。

 

接下来我们尝试从以下几个方面了解该工具:
脚本语言
脚本语言是仿真语言,很有意思。

 

是否支持录制脚本
测试工程师就像写测试用例那样写脚本,都不需要录制功能了。

 

结果检查
不清楚,只是说把写好的脚本提交给他们,就可以在几分钟之内收到结果。脚本中貌似没有检查点之类的语法。

 

价格
按月收费。

安卓应用自动化测试工具之五 – DeviceAnywhere

 

该工具的官方网址:deviceanywhere.com
背景:美国公司,做了好几年了。
突出特点:号称支持所有平台;与测试管理工具整合。

 

接下来我们尝试从以下几个方面了解该工具:
脚本编辑器 & 脚本语言
其实是测试流程设计器,用鼠标拖拽的方式设计测试场景。

 

结果检查
通过图像对比检查结果。

 

工具整合
这家公司提供的是一整套解决方案。不单有测试管理工具,设备监控工具,甚至还有移动应用开发工具。

 

价格
很贵。

安卓应用自动化测试工具之六 – JamoSolutions

 

该工具的官方网址:jamosolutions.com
背景:比利时公司,做了好几年了。
突出特点:提供QTP、Eclipse、Visual Studio插件;可以跨平台iOS/Android/Blackberry。

 

接下来我们尝试从以下几个方面了解该工具:
脚本编辑器 & 脚本语言
因为是通过插件形式工作的,脚本编辑器和脚本语言视乎开发工具(QTP、Eclipse、Visual Studio)而定。

 

结果检查
应该可以通过对比属性值检查结果。

 

价格
不明,估计不会比开发工具贵。

安卓应用自动化测试工具之七 – bsquare – TestQuest CountDown

 

该工具的官方网址:bsquare.com
背景:美国公司,做了好几年了。
突出特点:跨平台;与测试管理工具整合。

 

接下来我们尝试从以下几个方面了解该工具:
脚本编辑器 & 脚本语言
不清楚,听说是根据坐标点和图像判断。

 

结果检查
也不清楚。

 

工具整合
整合这家公司自身的Test Designer/Test Manager/Test Runner之类的工具。

 

价格
不清楚,听说有点贵。

安卓应用自动化测试工具之八 – ZAP-fiX

 

该工具的官方网址:zap-fix.com
背景:美国公司,做了好几年了。
突出特点:QTP插件;跨平台。

 

接下来我们尝试从以下几个方面了解该工具:
脚本编辑器 & 脚本语言
其实是QTP的插件。

 

结果检查
同QTP。

 

跨平台
可以跨Android/iOS测试。

 

价格
不详,肯定不会比QTP卖的贵。


安卓应用自动化测试工具之九 – eggPlant

 

该工具的官方网址:testplant.com
背景:美国公司,做了好几年了。
突出特点:跨平台;整合测试管理工具。

 

接下来我们尝试从以下几个方面了解该工具:
脚本编辑器 & 脚本语言
不详。由于可以跨平台,估计是坐标点或图像比较。

 

结果检查
不详。

 

跨平台
可以跨Android/iOS/Blackberry/Windows Phone等。

 

价格
不详。由于可以与Rational Quality Manager整合,所以估计不会比Rational的工具卖的贵吧。

安卓应用自动化测试工具之十 – Testin

 

该工具的官方网址:testin.cn
背景:北京公司,近两年刚起步。
突出特点:跨平台。

 

接下来我们尝试从以下几个方面了解该工具:
脚本编辑器 & 脚本语言
只能录制脚本,无法编辑。

 

结果检查
不详。

 

跨平台
可以跨Android/iOS,但是好像脚本要分开录制。

 

价格
不详。应该不贵。

安卓应用自动化测试工具之十一 – ExperiTest – SeeTestMobile

 

该工具的官方网址:experitest.com
背景:美国公司,近两年刚起步。
突出特点:可录制;跨平台。

 

接下来我们尝试从以下几个方面了解该工具:
脚本编辑器 & 脚本语言
支持不同工具的Plug-in,脚本语言视乎工具而定。

 

结果检查
图像比较,OCR。

 

跨平台
可以跨Android/iOS/Blackberry/Windows Phone。

 

价格
SeeTestMobile – $2499USD/Year。

安卓应用自动化测试工具之十二 – AndroidTester

 

该工具的官方网址:androidtester.net
背景:上海公司,近两年刚起步。
突出特点:可录制。

 

接下来我们尝试从以下几个方面了解该工具:
脚本编辑器 & 脚本语言
独立编辑器,Python脚本语言。

 

结果检查
图像比较。

 

跨平台
只支持Android。

 

价格
不详,应该不贵。

安卓应用自动化测试工具之十三 – SmartRobot

 

该工具的官方网址:dongzhousoft.com
背景:北京公司,近两年刚起步。
突出特点:可录制,与测试管理平台整合。

 

接下来我们尝试从以下几个方面了解该工具:
脚本编辑器 & 脚本语言
独立编辑器,可生成Robotium或MonkeyRunner脚本语言。

 

结果检查
不详。

 

跨平台
只支持Android。

 

价格
不详,应该不贵。

安卓应用自动化测试工具之十四 – Others

除了上述介绍的商业工具,Android自动化测试其实还有很多开源工具,大家可以陆续学习,这里尝试列举一些:
1. Robotium – robotium.org – 地球人都知道。
2. MonkeyRunner – 自己上网搜吧~
3. WindRiver – windriver.com – 这家厂其实是做芯片的,但是他们也有一个自动化测试框架,好像是不卖的。
4. Robolectric – http://pivotal.github.com/robolectric/index.html – 这其实是个单元测试框架。
5. Sikuli – sikuli.org – 这家专门做图像比较的。

竞争才有发展 垄断只有伤害

mikel阅读(1058)

这两天接触了两个垄断行业,一个银行,一个广电

发现一个有趣的问题,这些国有垄断的企业都干不过,那些商业化的企业,不管是售后服务还是用户体验都差得好几个时代,好像一个原始社会的产品,一个机器人时代的产品;一个是给银行员工用的,一个是给老百姓用的;…….

下面上个段子:
为什么孙悟空能大闹天宫,却打不过路上的妖怪?大闹天宫时碰到的都是给玉皇大帝打工的,所以大家都是意思意思不是真的卖命,在路上碰到的妖怪都是自己出来创业的所以比较拼!……

嗨,没有竞争只有垄断,除了产生暴利,让服务越来越差之外,没有第二个结果。谁天天吃得饱肚子还在乎用户会不会用的爽不爽?反正用户没得选择!

小米成了互联网企业的代表,也肩负着逆袭传统行业的使命,同样这头台风口上的飞猪,也找来了许多非议和贬斥,不过在说小米之前先体验体验人家的产品和服务再说,不说别的就用户体验一项,反正我觉得比广电强,结果还是胳膊扭不过大腿啊,没办法,人家是国有垄断。

这才明白为什么国外一直反垄断反得那么坚决和激烈,那就是怕一家独大,让用户没了话语权,只能忍气吞声接受非等价的产品和服务,从CPU的intel和AMD,到操作系统的Windows和linux,从收费软件到开源,哪一个都和“垄断” “竞争”这两个词有关。

大家都应该支持那些敢于动垄断者“奶酪”的企业和创新者,有了他们才有了我们用户用得顺手的产品,才有了那么多让人尖叫的产品诞生。

没有垄断,就没有伤害!

[转载]记一次网站收录数和排名的实现 - y-z-f - 博客园

mikel阅读(1002)

[转载]记一次网站收录数和排名的实现 – y-z-f – 博客园.

一、前言

      偶然一次在vs2012默认的项目文件夹里发现了以前自己做的一个关于SEO的类库,主要是用来查询某个网址的收录次数还有网站的排行数,后来重构了下,今天拿出来写篇文章,说说自己是如何思考的并完成的。

 

 

二、问题描述

      首先需要考虑的是能够支持哪些搜索引擎的查询,首先是百度,然后是必应、搜狗、搜搜、360。本来想支持Google但是一想不对,根本不好访问的,所以 暂时不算在内。而我们实际要做的就是根据一个网址能够检索出这个网址的在各个搜索引擎的收录次数以及在不同关键词下的网址排行,这里出入的只有网址还有若 干的关键词,而输出则是该网址在不同搜索引擎下的收录次数以及在各个关键词下的排行数。

      但是这里有个问题,就是排行数,如果检索的网址在前100还好,如果排名很后面,那么问题就来了,那样会让用户等待很长时间才能看到结果,但是用户可能只 想知道排行前100的具体排名,而那些超过的则只要显示100以后就可以了,而这些就需要我们前期考虑好,这样后面的程序才好做。

 

 

三、解决思路

      相信很多人都能够想到,就是利用WebClient将将需要的页面下载下来,然后用正则从中获取我们感兴趣的部分,然后利用程序去处理。而关键难度就是在这个正则的编写,首先我们先从简单的开始。

 

 

四、收录次数

      首先是网站的收录次数,我们可以在百度中输入site:www.cnblogs.com/然后我们就可以看到如下的页面:

      而我们所需要的收录次数就是 5,280,000 这段数字,我们接着查看页面元素:

      接着我们再观察其他的搜索引擎可以发现都是类似的,所以我们的思路这个时候应该就得出了,最后就是如何组织网址,这部分我们看地址栏?wd=site%3Awww.cnblogs.com%2F这段就知道怎么写了。

 

      稍等这个时候我们可能心急一个一个实现,这样后面我们就没法集中的调用,同时也会影响以后的新增,所以我们要规定一个要实现收录数功能的抽象类,这样就能 够在不知晓具体实现的情况统一使用,并且还能够在以后轻松的新增新的搜索引擎,而这种方式属于策略模式(Stategry),下面我们来慢慢分析出这个抽 象类的具体内容。

      首先每个实现这个抽象类的具体类都应该是对应某个搜索引擎,那么就需要有一个基本网址,同时还要留下占位符,比如根据上面百度的这个我们就得出这样一个字符串

http://www.baidu.com/s?wd=site%3A{0}

      其中{0}就是为真正需要检索网址的占位符,获取下载页面的路径是所有具体类都需要的所以我们直接将实现放在抽象类中,比如下面的代码:

///
/// 服务提供者
///

protected String SearchProvider { get; set; }

///
/// 需要检索的网址
///

protected String SiteUrl { get; set; }

///
/// 搜索服务提供网址
///

protected String BaseUrl { get; set; }

///
/// 后页面网址
///

///需要查询的网址 /// 拼接后的网址
protected String GetDownUrl(string site)
{
return string.Format(BaseUrl, HttpUtility.UrlEncode(site));
}

    其中SiteUrlSearchProvider是用来保存检索网址和搜索引擎名称。

      上面我们说了将会利用WebClient来下载页面,所以初始化WebClient的工作也在抽象类中完成,尽可能的减少重复代码,而为了防止阻塞当前线程所以我们采用了Async方法。

具体代码如下所示:

///
/// 查询在该搜索引擎中的收录次数
///

///网站URL public void SearchIncludeCount(string siteurl)
{
SiteUrl = siteurl;
WebClient client = new WebClient();
client.Encoding = Encoding.UTF8;
client.DownloadStringCompleted += DownloadStringCompleted;
client.DownloadStringAsync(new Uri(GetDownUrl(siteurl)));
}

///
/// 检索收录次数的具体实现
/// 子类必须要实现该方法
///

//////protected abstract void DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e);

      当WebClient完成下载后将会回调DownloadStringCompleted方法,而这个方法的是抽象方法也就意味着具体类必须要实现这个方法。

      虽然我们内部的实现是异步的但是对于其他开发者调用这个方法还是同步的,所以我们就需要借助委托因此我们还要新建一个委托类型:

///
/// 当完成一个网站的收录查询后回调
///

public Action OnComplatedOneSite { get; set; }

 

其中SiteIncludeCountResult的结构如下所示:

百度为您找到相关结果约([\w,]+?)个

最后再将获取的字符串去掉逗号就可以强制转换了,这样结果就出来了,具体实现就像下面这样:

///
/// 百度网站收录次数查询
///

public class BaiDuSiteIncludeCount : SiteIncludeCountBase
{
public BaiDuSiteIncludeCount()
{
BaseUrl = "http://www.baidu.com/s?wd=site%3A{0}";
SearchProvider = "百度";
}

protected override void DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
var result = new SiteIncludeCountResult();
result.SiteUrl = SiteUrl;
result.SearchType = SearchProvider;
result.IncludeCount = 0;
Regex reg = new Regex(@"百度为您找到相关结果约([\w,]+?)个", RegexOptions.IgnoreCase | RegexOptions.Singleline);
var matchs = reg.Matches(e.Result);
if (matchs.Count > 0)
{
string count = matchs[0].Groups[1].Value.Replace(",", "");
result.IncludeCount = long.Parse(count);
}
SetCompleted(result);
}
}

      以此类推,其他的都是按照这种就可以了,有兴趣的可以下载我的源码查看。

 

 

五、关键词排名

      我们按照之前的思路,还是要先规定一个抽象类,但是其结构跟上面的抽象类很相似,所以笔者这里直接给出具体的代码:

///
/// 实现关键词查询必须继承该类
///

public abstract class KeyWordsSeoBase
{
protected String BaseUrl { get; set; }

protected String SearchProvider { get; set; }

protected String GetDownUrl(string keyword, string site, long current)
{
return String.Format(BaseUrl, HttpUtility.UrlEncode(keyword), current);
}

protected void SetCompleted(KeyWordsSeoResult result)
{
if (OnComplatedOneKeyWord != null)
{
OnComplatedOneKeyWord(result);
}
}

///
/// 完成一个关键词的查询后回调该委托
///

public Action OnComplatedOneKeyWord { get; set; }

///
/// 查询指定关键词和网站在该搜索引擎中的排行
/// 子类需要重写该方法
///

///关键词 ///网站URL public abstract void SearchRanking(IEnumerable keywords, string site,long count);
}

最大的区别在于具体的实现全部集中在SearchRanking中,通过keywords参数可以看出我们会支持多个关键词的查询,最后不同的就是下载路径的组织,因为涉及到翻页所以多了一个参数。

其中KeyWordsSEOResult的结构如下所示:

///
/// 用于关键词排行查询的委托参数
///

public class KeyWordsSeoResult
{
///
/// 搜索引擎类型
///

public String SearchType { get; set; }

///
/// 关键词
///

public String KeyWord { get; set; }

///
/// 排行
///

public long Ranking { get; set; }
}

      废话不多说,我们来看百度的搜索结果页:

      以上是笔者在百度中搜索程序员的排名第九个的html结构,或许你会觉得很简单只要获取div的id以及网址就可以了,但是很多搜索引擎的路径并不是直接 的路径,而是会先链到百度然后重定向的,如果非要匹配我们就需要多做一件事就是访问这个路径得到真实的路径,那样就会加大这中间的等待时间,所以笔者采用 的是直接截取上图中的<span class=”g”>后面的内容,这样就避免了一次请求。(不知道当初笔者怎么想的,实现的时候并没有采用id那个值而是在内部递增,估计这个id的序号在翻页后会出现问题吧),最后亮出我们神圣的正则表达式:

&lt;span\s+class=""(?:g|c-showurl)""&gt;([^/&amp;]*)

以为这样就大公告成了?错了,在某些结果里面百度会给这个网址加上b标签,而笔者则采用全部赶尽杀绝的方式,利用正则全部删掉(反正又不看页面,只要拿到我想要的就OK了),实现的时候我们可不能直接实现多个关键词的判明,应该是实现一个关键词的,然后循环调用即可了,下面是笔者的单个关键词的实现:

protected KeyWordsSeoResult SearchFunc(string key, string siteurl, long total)
{
var result = new KeyWordsSeoResult();
result.KeyWord = key;
result.Ranking = total + 1;
var reg = new Regex(@"&lt;span\s+class=""(?:g|c-showurl)""&gt;([^/&amp;]*)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
var replace = new Regex("", RegexOptions.IgnoreCase | RegexOptions.Singleline);
var client = new WebClient();
long current = 0;
long pos = 0;
for (; ; )
{
String url = GetDownUrl(key, siteurl, current);
String downstr = client.DownloadString(url);
downstr = replace.Replace(downstr, "");
var matchs = reg.Matches(downstr);
foreach (Match match in matchs)
{
pos++;
string suburl = match.Groups[1].Value;
try
{
if (suburl.ToLower() == siteurl.ToLower())
{
result.Ranking = pos;
return result;
}
}
catch
{
continue;
}
}
current += 10;
if (current &gt; total)
{
current -= 10;
if (current &gt;= total)
{
break;
}
current = total;
}
}
return result;
}

注意for循环的结束部分,这里是用来处理分页的,以翻到下一页继续检索。其他的大体部分都跟笔者说的一样,下载页面->正则匹配->根据匹配结果判断。剩下的就是SearchRanking的实现,就是循环关键词,只是这里笔者为每个搜索引擎新建线程来实现,当然这不怎么好,所以读者可以改用更好的方式来做:

public override void SearchRanking(IEnumerable keywords, string site, long count)
{
new Thread(() =&gt;
{
foreach (string key in keywords)
{
KeyWordsSeoResult result = SearchFunc(key, site, count);
result.SearchType = SearchProvider;
SetCompleted(result);
}
}).Start();
}

六、统一管理

      有了这些我们就可以写出一个简洁的类来负责管理,笔者这里直接给出代码:

///
/// 查询网站的收录次数以及排行
///

public class RankingAndIncludeSeo
{
///
/// 关键词列表
///

public IList KeyWordsSeoList { get; private set; }

///
/// 收录次数列表
///

public IList SiteIncludeCountList { get; private set; }

public RankingAndIncludeSeo()
{
KeyWordsSeoList = new List();
SiteIncludeCountList = new List();
}

///
/// 当完成一个关键词的查询后回调该委托
///

public Action OnComplatedAnyKeyWordsSearch { get; set; }

///
/// 当完成一个网站的收录次数查询后回调该委托
///

public Action OnComplatedAnySiteIncludeSearch { get; set; }

///
/// 查询网址的排行
///

///关键词组 ///查询的网址 ///最大限制排行数 public void SearchKeyWordsRanking(IEnumerable keywords, string siteurl, long count = 100)
{
if (keywords == null)
throw new ArgumentNullException("keywords", "必须存在关键词");
if (siteurl == null)
throw new ArgumentNullException("siteurl", "必须存在网站URL");
foreach (KeyWordsSeoBase kwsb in KeyWordsSeoList)
{
kwsb.OnComplatedOneKeyWord = kwsb.OnComplatedOneKeyWord ?? OnComplatedAnyKeyWordsSearch;
kwsb.SearchRanking(keywords, siteurl, count);
}
}

///
/// 查询网址的收录次数
///

///查询的网址 public void SearchSiteIncludeCount(string siteurl)
{
if (siteurl == null)
throw new ArgumentNullException("siteurl", "必须指定网站");
foreach (SiteIncludeCountBase sicb in SiteIncludeCountList)
{
sicb.OnComplatedOneSite = sicb.OnComplatedOneSite ?? OnComplatedAnySiteIncludeSearch;
sicb.SearchIncludeCount(siteurl);
}
}
}

      RankingAndIncludeSEO中提供了公共的委托,如果单个搜索引擎没有提供委托那么就采用这个公共的,如果已经指定了单独的委托就不会被赋值了,而其他开发者调用的时候只要向KeyWordsSeoListSiteIncludeCountList中添加已经实现的类就可以了,方面其他开发者开发出自己的实现并加入其中。

七、小节

      这篇随笔总的来说并不是讲述什么高端技术的,仅仅只是提供一种大致的思路以及结构上的设计,如果读者需要应用于实际开发中,最好加以验证,笔者并不能保证关键词的排名没有任何误差,因为搜索的结果会由于任何因素发生改变。

 

^.^我是源码下载

 

在满足必要的经济的条件下,研究更佳高深的技术.满足自己的野心

为什么都在急功近利

mikel阅读(1005)

昨天写的《10分钟百度钱包赚10元》的日志刚发布,晚上就有人反应说有人因为没注意网址,注册了钓鱼网址而被骗了银行卡好几百万

互联网上乌烟瘴气都是这些急功近利的骗子搞的,多少年的钓鱼网站一直防不胜防,一个项目出来立刻就有人偷奸取巧的想着怎么骗人,造成不懂互联网的谈网赚就是在说怎么骗人一样

今天也巧收到了体验站的推广邮件,很多人都在问自己怎么作弊刷联盟,一个行业要持续发展下去,大家都有钱赚,首先就要建立良性的生态圈,否则会越做越窄,杀鸡取卵的事儿不知道断送了多少项目,又让多少人倾家荡产。

互联网水深的让老鸟儿们都战战兢兢地,步履瞒珊的在走,更何况那些想在互联网上淘金的新手,究其原因就是信任机制缺失,让骗子横行霸道。

拿P2P借贷网站来说吧,很多人在整个借贷网站用虚假信息注册借贷后,然后跑路,又去其他的借贷网站如法炮制的又借钱骗人,更可笑的是连借贷网站 都是圈钱跑路的不少!

 现在,传统企业转型互联网,纷纷触网,被各个营销培训大师忽悠着进去互联网这个江湖,如果再不推出互联网信任体系机制产生良性循环,企业互联网转型时期会更加漫长。

说了这么多互联网的阴暗面,其实还是有很多阳光的东西,比如上面说的体验站联盟一直在抵制作弊,大家协同一致的在建立一个良性的生态圈,共同遵守联盟规则进行规范化行业,只有这样大家才能赚到钱,不至于饿死。

[转载]Linux端口以及防火墙端口的查看命令 | Richard.Z's Blog

mikel阅读(913)

[转载]Linux端口以及防火墙端口的查看命令 | Richard.Z’s Blog.

Linux下如果我们需要知道2809号端口的情况的话,我们可以这样,如下命令:
$netstat -pan|grep 2809
tcp    0   0 0.0.0.0:2809   0.0.0.0:*   LISTEN   9493/java
下面是常用参数的解释:
NETSTAT [-a] [-b] [-e] [-n] [-o] [-p proto] [-r] [-s] [-v] [interval]
-a            显示所有连接和监听端口。
-b            显示包含于创建每个连接或监听端口的可执行组件。在某些情况下已知可执行组件
拥有多个独立组件,并且在这些情况下
包含于创建连接或监听端口的组件序列被显示。这种情况下,可执行组件名
在底部的 [] 中,顶部是其调用的组件,等等,直到 TCP/IP 部分。注意此选项
可能需要很长时间,如果没有足够权限可能失败。

-e            显示以太网统计信息。此选项可以与 -s选项组合使用。

-n            以数字形式显示地址和端口号。
-o            显示与每个连接相关的所属进程 ID。
-p proto      显示 proto 指定的协议的连接;proto 可以是
下列协议之一: TCP、UDP、TCPv6 或 UDPv6。
如果与 -s 选项一起使用以显示按协议统计信息,proto 可以是下列协议之一:
IP、IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 或 UDPv6。
-r            显示路由表。
-s            显示按协议统计信息。默认地,显示 IP、
IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 和 UDPv6 的统计信息;
-p 选项用于指定默认情况的子集。

-v            与 -b 选项一起使用时将显示包含于
为所有可执行组件创建连接或监听端口的组件。

interval      重新显示选定统计信息,每次显示之间
暂停时间间隔(以秒计)。按 CTRL+C 停止重新
显示统计信息。如果省略,netstat 显示当前
配置信息(只显示一次)
netstat -nl | grep 110
看到有结果的话就是可以使用了(则端口号开启了)
先可以看看/etc/services文件,改文件定义了linux里所有的服务及其使用的端口

防火墙端口:
当Linux打开防火墙后,你会发现,从本机登录23端口是没有问题的,但是如果从另一台pc登录该linux系统后,你会发现提示这样的错误:
不能打开到主机的连接, 在端口 23: 连接失败
因为linux防火墙默认是关闭23端口的,如果允许远程登录,可以关掉防火墙,也可以开防火墙开放23端口,具体如下:
即时生效,重启后失效
开启: service iptables start
关闭: service iptables stop
重启后生效
开启: chkconfig iptables on
关闭: chkconfig iptables off
在开启了防火墙时,做如下设置,开启相关端口
修改/etc/sysconfig/iptables 文件,添加以下内容:
-A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 23 -j ACCEPT

查看防火墙 iptables -L
——————
netstat -nupl (UDP类型的端口)
netstat -ntpl (TCP类型的端口)
你可以使用 lsof 命令来查看某一端口是否开放。查看端口可以这样来使用,我就以80端口为例:
lsof -i:80
如果有显示说明已经开放了,如果没有显示说明没有开放。
linux端口和服务:
一、端口和服务的关系
端口号与相应服务的对应关系存放在/etc/services文件中,这个文件中可以找到大部分端口。使用netstat命令
显示的服务名称也是从这个文件中找的。有人说将这个文件中的相应端口号注释掉,就可以禁用该端口。
我试了却不起作用,这种方法应该是没有用的,是误传!将相应端口号注释掉,唯一的作用就是使用netsat
命令时,将不显示服务名(比如ftp)而是显示端口号(比如21)。原理也很简单:netstat无法在/etc/services
文件中找到端口号对应的服务名,自然就无法显示了。所以/etc/services文件只是起到端口号与相应服务的
映射关系,与端口的启动和关闭没有关系!
二、查看本机开放的端口
1、netstat 查看端口和连接
netstat 列出目前已经连接的服务名
netstat -a 列出目前已经连接的和正在监听的服务名
netstat -an 列出目前已经连接的和正在监听的端口号(与上面的命令功能一样,只是不解释端口号对应的服务名)
netstat -ap 在上面命令的基础上列出连接的PID(进程号),用这个PID,可以使用KILL 来杀死连接
例如:某个连接的PID=111,想踢出去就使用 KILL -9 111。ok!
netstat -rn 输出路由表
2、nmap
nmap 127.0.0.1 查看本机开放的端口,会扫描所有端口
nmap -p 1024 65535? 127.0.0.1 扫描指定端口范围
nmap -PT 192.168.1.1-111? 扫描一组范围的电脑
三、关闭和开启端口(服务)
关闭端口的方法:
1、因为每个端口都有对应的服务,因此要关闭端口只要关闭相应的服务就可以了。
2、用IPTABLE对端口进行限制,这样也能使端口不被访问,但端口本身并没有关闭。
在这儿只介绍关闭服务的方法,IPTABLE的应用以后再讨论。
linux中开机自动启动的服务一般都存放在两个地方:
/etc/init.d/文件夹下的服务:
这个文件夹下的服务都可以通过运行相应的SCRIPT来启动或关闭。
例如:启动sendmail服务 ./sendmail start (打开了TCP 25端口)
关闭sendmail服务 ./sendmail stop (关闭TCP 25 端口)
查看sendmail服务当前状态 ./sendmail? status (查看服务是否运行)
/etc/xinetd.d/文件夹下的服务:
这个文件夹下的服务需要通过更改服务的配置文件,并重新启动xinetd才可以。
例如:要启动其中的auth服务,打开/etc/xinetd.d/auth配置文件,更改“disable=no”,保存退出。运行/etc/rc.d/init.d/xinetd restart
要停止其中的auth服务,打开/etc/xinetd.d/auth配置文件,更改“disable=yes”,保存退出。运行/etc/rc.d/init.d/xinetd restart
四、控制开机自动启动的服务
上面说的控制服务开关方法是在启动linux之后进行操作的,如果我想在linux启动时控制哪些服务启动、哪些服务关闭怎么做
控制服务自动启动的方法有3个:
1、更改/etc/rc.d下的对应文件夹:
如果你登陆的默认界面是字符界面,那么修改rc.3文件夹,如果登陆界面默认是图形界面,那么修改rc.5。
在文件夹中,每个服务的名字前都带有“K”或“S”,S就代表这个服务开机自动运行了,把它删了或前缀改为“K”下次就不会启动了。
2、使用ntsysv命令:
输入ntsysv命令,将会出现一个服务列表,需要启动的打“*”,简单。
3、使用chkconfig命令:
让某个服务不自动启动:例如httpd:chkconfig –level 35 httpd? off ;35指的是运行级别
让某个服务自动启动:例如httpd:chkconfig –level 35 httpd? on ;
查看所有服务的启动状态:chkconfig –list
查看某个服务的启动状态:chkconfig –list |grep httpd

[转载]统计博客园个人博客访客的简单方法(接上篇,详细分析篇) - Jaws - 博客园

mikel阅读(826)

[转载]统计博客园个人博客访客的简单方法(接上篇,详细分析篇) – Jaws – 博客园.

接上篇:统计博客园个人博客访客的简单方法 http://www.cnblogs.com/jaws/p/4034029.html。

上篇文章中我做了简单采集与分析,由于访客数较少所以没有对分析结果做过多的对比,仅仅做了技术的实现。这次感谢博客园推荐了我的逗比文档让我采集到了接近2000独立IP的UA。本来是可以采集到5000独立IP。@vons 你站出来,我保证不打你。。。。

进入正题。本次采集有效访客数1964人,截止写稿子。主要对地域和以下图中的参数做了统计。正如前面有朋友说到博客园的用户统计是非大众的,所以大家看看就好。咋们是特殊群体。不过看看数据也挺有意思的。

1.地域

2.操作系统

3.win系细分(其它为非win)

4.浏览器内核(Trident为IE系)

5.浏览器细分

6.IE细分(其它为非IE)

7.移动端(其它为非移动端)

8.Like Gecko

这个统计很有意思。

有兴趣的可以看下这篇文章。UserAgent的历史变迁。http://article.yeeyan.org/view/heart5/19211

IE11伪装成Firefox:避开旧版IE CSS。http://news.mydrivers.com/1/258/258468.htm

总结

以上统计可在:http://rdl.ninja/admin/req_analysis.aspx 查看最新的。

此项目用到了开源js图表:http://Highcharts.com

数据库使用开源stsdb:http://stsdb.com/

浏览器分析不是特别精确,比如Safari没有做统计。主要是熟悉各浏览器的UA差异,再者熟悉Highcharts的使用。此分析结果只做参 考,不能和专业统计系统来比。随着年龄的增长,现在很害怕放弃这个词。所以虽然这个东西简单也没有带来什么特别的价值,不过也算是有始有终了。

最近公司项目中也开始用node了。本来想写写node,可感觉逼格不够高。。所以等有空我来写个nodejs的系列。从node底层开始分析,一步一步实现一个原生C#版的nodejs。

洗澡睡觉。