[转载]调用动态类型的扩展方法

mikel阅读(995)

[转载]调用动态类型的扩展方法 – 麒麟.NET – 博客园.

对于一个动态类型来说,你可以认为它包含任意成员,它们都能通过编译。但到了运行时,到底是否拥有这些成员,就真相大白了。如

dynamic test = 7;
Console.Write(test.Name);

编译器无法在编译时知道test的真正类型,因此会使用其运行时的实际类型,而默认对于它的所有调用都是合法的,不会引发任何编译时错误。但它会抛出一个运行时异常。因为在运行时,test为一个int,它不具备Name属性。

在编译时,编译器会根据会生成一些调用所需的上下文环境,如所有已知的静态类型等。但它无法知道在源代码中究竟引入了哪些命名空间。因此,你无法调用动态类型所代表的实际类型的扩展方法,也无法将动态类型作为参数传入扩展方法。如

dynamic size = 5;
var numbers = Enumerable.Range(1, 10);
var error = numbers.Take(size);

但我们有两种方法可以实现这两点,它们看上去可能有点丑陋,但在你需要的时候却会很有用。这两种方法为:

1. 将动态类型强制转换为已知的符合方法签名的静态类型

2. 以静态方法的形式调用

对于将动态类型作为参数传入扩展方法的情况,你可以这样

dynamic size = 5;
var numbers = Enumerable.Range(1, 10);
var workaround1 = numbers.Take((int)size);
var workaround2 = Enumerable.Take(numbers, size);

对于调用动态类型的扩展方法,可以这样

int size = 5;
dynamic numbers = Enumerable.Range(1, 10);
var workaround1 = ((IEnumerable<int>)numbers).Take(size);
var workaround2 = Enumerable.Take(numbers, size);

怎么样,很简单吧?

这其实是我在阅读Jon Skeet的新书C# in Depth, Second Edition时遇到的问题,当时脑子犯懵有点不能理解,于是想起Jon时常活跃于Stackoverflow,何不发帖问问这个问题?没想到仅仅十几分钟的时间,Jon就给予了解答,甚至有人怀疑我是蓄意为之……而且,更令人开心的是,还得到了博客园的朋友Colin Han的回答。

所以,如果你有什么难题一时无法应对,不妨去求助于Stackoverflow,去咨询一下全世界范围内的高手牛人们,相信你一定会得到满意的答复。

[转载]字符串转换成JSON的三种方式

mikel阅读(1152)

[转载]字符串转换成JSON的三种方式 – Snandy – 博客园.

采用Ajax的项目开发过程中,经常需要将JSON格式的字符串返回到前端,前端解析成JS对象(JSON )。
ECMA-262(E3) 中没有将JSON概念写到标准中,但在 ECMA-262(E5) 中JSON的概念被正式引入了,包括全局的JSON对象和Date的toJSON方法。

1,eval方式解析,恐怕这是最早的解析方式了。

1 function strToJson(str){
2 var json = eval('(' + str + ')');
3 return json;
4 }

记得str两旁的小括号哦。
2,new Function形式,比较怪异哦。

1 function strToJson(str){
2 var json = (new Function("return " + str))();
3 return json;
4 }


3,使用全局的JSON对象。

1 function strToJson(str){
2 return JSON.parse(str);
3 }

目前IE8(S)/Firefox3.5+/Chrome4/Safari4/Opera10 已实现了该方法。

使用JSON.parse需严格遵守JSON规范,如属性都需用引号引起来,如下

1 var str = '{name:"jack"}';
2 var obj = JSON.parse(str); // --> parse error

name没有用引号引起来,使用JSON.parse所有浏览器中均抛异常,解析失败。而前两种方式则没问题。
相关:

http://blogs.msdn.com/ie/archive/2008/09/10/native-json-in-ie8.aspx
https://developer.mozilla.org/en/Using_JSON_in_Firefox

[转载]C#程序抓取网页源码实例(winform程序)

mikel阅读(951)

[转载]C#程序抓取网页源码实例(winform程序)-纯野.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.Collections;

namespace CopyHtml
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
//获取指定网页中的源数据

string rl;
WebRequest Request = WebRequest.Create(textBox1.Text.Trim());

WebResponse Response = Request.GetResponse();

Stream resStream = Response.GetResponseStream();

StreamReader sr = new StreamReader(resStream, Encoding.Default);
StringBuilder sb = new StringBuilder();
while ((rl = sr.ReadLine()) != null)
{
sb.Append(rl);
}
textBox2.Text = sb.ToString();//抓取得到的源网页

string he = textBox2.Text.ToString();

textBox3.Text = stripHtml(he);//去除html标签后得到的源网页

Match TitleMatch = Regex.Match(he, “([^<]*)“, RegexOptions.IgnoreCase | RegexOptions.Multiline);//获取网页的标题
string title = TitleMatch.Groups[1].Value;

textBox4.Text = (“网页的标题是:” + title );

}

///

/// 去掉网页中的html标签
///

/// 待转化的字符串 ///
private string stripHtml(string strHtml)
{
Regex objRegExp = new Regex(“<(.|\n)+?>“);
string strOutput = objRegExp.Replace(strHtml, “”);
strOutput = strOutput.Replace(“<", "<"); strOutput = strOutput.Replace(">“, “>”);
return strOutput;
}

// 提取HTML代码中的网址
public static ArrayList GetHyperLinks(string htmlCode)
{
ArrayList al = new ArrayList();

string strRegex = @”(href)[ ]*=[ ]*[“”‘][^””‘#>]+[“”‘]”;

Regex r = new Regex(strRegex, RegexOptions.IgnoreCase);
MatchCollection m = r.Matches(htmlCode);

for (int i = 0; i <= m.Count - 1; i++) { bool rep = false; string strNew = m[i].ToString(); // 过滤重复的URL foreach (string str in al) { if (strNew == str) { rep = true; break; } } if (!rep) al.Add(strNew); } al.Sort(); return al; } } } [/csharp]

[转载]FlashFXP打造自动镜像更新

mikel阅读(1021)

[转载]FlashFXP打造自动镜像更新 – 电仔的博客 – 博客园.

朋友公司最近又买了一台服务器,但是接入的是电信宽带(原先的服务器是网通宽带),朋友想用电信宽带作为镜像,从原服务器上同步(下载)一些视频文件,而且要能够实现每隔一段时间自动扫描更新的文件,然后进行同步,即使服务器重启了也能够自启动

环境:

网通服务器  Windows 2008 Server、Server-U服务器

电信服务器  Windows 2008 Server R2 64X 、FlashFXP_4.0.0.1510

一开始搜索了晚上的文章,有用网络传神、Web Synchronizer等等各种同步软件。

于是尝试,发现网络神传不能够后台运行,也不能够以服务形式运行,而且只能够定时上传故舍弃~

然后是用Web Synchronizer,发现电信服务器的能够连接到网通服务器的21端口上,但是状态一直停留在Scanning,无法完成同步~~放弃……

之后上网搜索了很多种FTP软件,同步工具,发现都不符合要求, 最后把希望寄托在了FlashFXP上。

笔者使用的是FlashFXP_4.0.0.1510_Crack 绿色又是注册版 挺好用的~

经过尝试发现做如下设置即可实现上述功能:

1、建立一个站点, 我建立的是网通服务器的FTP连接

注意:FTP服务器用户 test对应的目录应该要锁定在预同步目录的上一级目录上

设置完成之后点击应用 ,然后点击连接

2、建立队列

连接到刚刚建立的FTP服务器后,找到要同步的目录,右击该目录,选择队列

然后会在队列区看到 刚才建立的队列

右击队列区的那个队列,另存为 test.fqf

3、编辑文件传输规则

编辑文件传输规则是为了确保每次只更新最新的文件

打开 菜单栏 选项>文件传输规则>添加

添加如下两条规则:

4、建立计划任务

Task Scheduler 必须开启~ 否则会出错哦~

点击菜单栏的工具>计划>新建任务

任务名称 test 队列文件选择刚刚新建的那个队列文件 test.fqf

在计划这个标签里面进行如下设置

然后到Windows标签进行如下设置,确保能够自启动

首先勾空 “只有在用户登录后才运行任务”

然后输入管理员或者能够进行相应操做的用户的用户名和密码

日志等等依据个人习惯自行设置吧~

总结:

这样设置,就能够满足一开始提出的问题。并且能够依托于服务进行更新。

但是有几点需要注意:

如果需要同步的文件夹的文件很多或者文件较大时,则应该把检测的间隔时间调大一点,否则会比较占用资源。

Task Scheduler 必须开启~ 否则会出错哦~

[转载]Android JAVA 语言基础例子代码

mikel阅读(926)

[转载]Android JAVA 语言基础例子代码 – Thinker – 博客园.

Android的界面一般都是java开发的,因此对于c++,.net人员来说理解和编写有一个适应过程,最近参考了一下资料,把这些涉的一些java基础使用以例子代码的形式总结起来,记录了这个平台的熟悉过程。

文件目录(涉及了java的一些主要语法)

AnnotDefine.java
AnnotDemo.java             ClassDemo.java
CodeResource_en_US.java    Collection.java
demo.java                  example_en_US.properties
Generic.java               InitDemo.java
IO.java                    LocalResource.java
Nest.java                  PrefsDemo.java
ThreadDemo.java

下载地址:

http://cid-56b433ad3d1871e3.office.live.com/self.aspx/.Public/AndroidJava.rar

至于JAVA和C#的语法区别,可以参考一个有意思的网站

http://www.harding.edu/fmccown/java_csharp_comparison.html

以下是一些简要的说明(JDK),具体的使用和一些说明参考以上的例子

Collections Framework

包:java.util

接口

核心和层次关系

Iterable, Collection, List, Set, SortedSet, Queue, Map, and SortedMap.

image

实现类

实现类约定:

Abstract开头的是抽象类,用于减少多个实现的代码重复

具体的类以接口的名字结尾,如ArrayList实现的事List接口

如下是JDK中的实现类列表

AbstractCollection, AbstractList, AbstractQueue, AbstractSequentialList, AbstractSet,

ArrayBlockingQueue, ArrayDeque, ArrayList, AttributeList, ConcurrentLinkedQueue, ConcurrentSkipListSet, CopyOnWriteArrayList, CopyOnWriteArraySet, DelayQueue, EnumSet, HashSet, JobStateReasons, LinkedBlockingDeque, LinkedBlockingQueue, LinkedHashSet, LinkedList, PriorityBlockingQueue, PriorityQueue, RoleList, RoleUnresolvedList, Stack, SynchronousQueue, TreeSet, Vector

工具类

数组和容器的遍历方法

Collection<String> col = …

Iterator iter = col.iterator();

while (iter.hasNext())

System.out.println(iter.next());

for (String s: col)

System.out.println(s);

嵌套类型Nested Type

There are four kinds of nested classes: static member classes, nonstatic member classes, anonymous classes, and local classes. The latter three categories are known as inner classes.

注释类型annotations

java.lang

Deprecated
Override
SuppressWarnings

java.lang.annotation

Documented
Inherited
Retention
Target

javax.annotation

Generated
PostConstruct
PreDestroy
Resource
Resources

[转载]为Android安装BusyBox —— 完整的bash shell

mikel阅读(1000)

[转载][Android] 为Android安装BusyBox —— 完整的bash shell – 木乃猫的学习笔记 – 博客园.

大家是否有过这样的经历,在命令行里输入adb shell,然后使用命令操作你的手机或模拟器,但是那些命令都是常见Linux命令的阉割缩水版,用起来很不爽。是否想过在Android上使用较完整 的shell呢?用BusyBox吧。不论使用adb连接设备使用命令行还是在手机上直接用terminal emulator都可以。

一、什么是BusyBox ?

BusyBox 是标准 Linux 工具的一个单个可执行实现。BusyBox 包含了一些简单的工具,例如 cat 和 echo,还包含了一些更大、更复杂的工具,例如 grep、find、mount 以及 telnet。有些人将 BusyBox 称为 Linux 工具里的瑞士军刀.简单的说BusyBox就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令。(摘自百度百科)

二、在Android上安装BusyBox

准备:

1. 下载BusyBox的binary,打开这个地址 http://www.busybox.net/downloads/binaries ,选择最新版本,然后下载对应你的设备架构的版本,这里我下载了busybox-armv6l,下面将以这个文件名为示例。

2. 需要有一个命令行的环境,在电脑上使用adb或在手机上使用terminal emulator。

3. 连接手机和电脑,手机的USB Mode设置成None(仅充电),并且开启USB调试模式。

安装:

1. 将busybox-armv6l重命名为busybox

2. 将busybox传入手机的SD卡,可以使用下面的命令或自己想其他办法。

打开terminal(Linux,Mac)或cmd(Windows)

adb push ~/Desktop/busybox /mnt/sdcard

其中的~/Desktop请根据自己的情况替换成正确的路径

3. 输入以下命令,为了在/system目录写入文件

adb shell
su
mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system

使用 ls 检查一下 /system 里是否有 xbin 目录,没有的话输入 mkdir xbin 创建,因为本示例是要把busybox安装到 /system/xbin 。

4. 复制 busybox 文件到 /system/xbin,并为其分配“可执行”的权限

cp /mnt/sdcard/busybox /system/xbin
chmod 755 busybox

5. 这时就可以使用 busybox 的命令了,例如以前没有清屏的clear命令,现在只需输入 busybox clear 就可以实现清屏功能,使用完整版的 ls 只需输入 busybox ls 。

但是每次前面都加上个busybox太麻烦了,所以我们还要继续完成安装。

在 /system/xbin 下输入

busybox --install .

如果想安装到别的目录,则把点替换成别的路径。

至此就安装完成了,比较一下原来的 ls 命令和 busybox 里的 ls 命令。

常见错误:

1. 如果安装时出现这样的错误,

busybox: /bin/zcat: No such file or directory

busybox: /sbin/zcip: Invalid cross-device link

说明没有输入安装路径,正确的示例 busybox –install /system/xbin

2. 如果出现这样的错误,

cp: /system/xbin/busybox: Read-only file system

说明没有正确输入上面第三步的mount命令。

小技巧:

1. busybox 里有 ash 和 hush 还有 sh 这几种 shell,在命令行输入 ash 或 hush,可以像在 bash 里那样,通过按上下键选择刚才输入的命令。

2. android系统本身就有ls命令,busybox里也有ls,输入ls时调用的是android的ls,那么想用busybox的ls就要每次都在前面加个busybox吗?不用,使用alias命令可以搞定。

alias ls='busybox ls'

同样的,cp、mv等二者都有的命令都可以这样搞定。也可以通过修改 /init.rc 来解决。

[转载]推荐14款强大的HTML5素描及绘图工具

mikel阅读(1072)

[转载]推荐14款强大的HTML5素描及绘图工具 – 梦想天空 – 博客园.

我们知道,素描是设计师工作流程中的一个重要环节。本文收集了一些借助 JavaScript和HTML5 Canvas开发的素描工具,这些工具表明,HTML5的确是一个令人兴奋的标记语言。如果你发现了新的基于HTML5 Canvas开发的绘图工具,欢迎在这里与大家分享。

1. Mr. Doob’s Harmony

HTML5 Sketching Tools Every Designers Must Know

如果你喜欢涂鸦,可以试试这款工具,它有各种各样的画笔可用于绘图。

2. Sketch

HTML5 Sketching Tools Every Designers Must Know

一款叫Hakim El Hattab的人开发的一款素描工具,可绘制三维图案。

3. deviantMuro

HTML5 Sketching Tools Every Designers Must Know

一款非常好的用于素描及绘画的工具,有很多强大的功能。

4. Sketchy Structures

HTML5 Sketching Tools Every Designers Must Know

这款绘图工具可以绘制出一些非常特别的场景。

5. Multi-User Sketchpad

HTML5 Sketching Tools Every Designers Must Know

一款支持多人同时在线绘画的工具。

6. Sketchpad

HTML5 Sketching Tools Every Designers Must Know

一款非常棒的绘画工具,看起来很炫啊。

7. Bezier Sketching

HTML5 Sketching Tools Every Designers Must Know

贝塞尔素描工具,最大的特色是定义路径。

8. Gartic Canvas Sketch

HTML5 Sketching Tools Every Designers Must Know

另一款基于WEB的绘图工具。

9. Spirograph

HTML5 Sketching Tools Every Designers Must Know

可以画出很炫的圆形图案的工具。

10. Bomomo

HTML5 Sketching Tools Every Designers Must Know

一款让人惊叹的绘图工具,想了解更多,请访问Bomomo’s gallery.

11. Internet Graffiti Board

HTML5 Sketching Tools Every Designers Must Know

每个人都可以使用的涂鸦板,即时保存和发布。

12. Pschiiit

HTML5 Sketching Tools Every Designers Must Know

这是一个网络涂鸦板的增强版,图案以多边形形式存储在PostGreSQL数据库中。

13. physicSketch

HTML5 Sketching Tools Every Designers Must Know

你在画布上绘制的图形会以重力效应运动。

14. Zwibbler

HTML5 Sketching Tools Every Designers Must Know

另一款基于HTML5 Canvas开发的绘图程序。

(编译来源:梦想天空 原文来自:HTML5 Sketching Tools Every Designers Must Know

[转载]如何使用C#实现网易博客中圈子用户数据的采集

mikel阅读(1135)

[转载]如何使用C#实现网易博客中圈子用户数据的采集 – wuhuacong(伍华聪)的专栏 – 博客园.

新浪博客,网易博客,都是博客中的佼佼者,其中网易提供的圈子信息,更胜一筹,使得一般用户能够通过访问圈子进入相关的群组,或者获取相关圈子用户 的信息等,以实现各种精准营销的目的。虽然新浪遮遮掩掩不提供圈子的相关信息,相对而言,网易博客提供圈子,能够使得更多的人、更多的程序支持,推高博客 的知名度及实用性。网易博客可以通过地址http://q.163.com/ 访问,它是经过两级分类的,如下所示。

点击分类进入即可查看到每个子分类都有很多圈子,圈子累死QQ的群组,是某一兴趣团体的博客,里面收集很多相关的资料及信息,如下所示:

这里不关心圈子的有哪些宝贵学习资料,我更关心的是这些圈子的用户如何采集出来,由于用户都是网易的用户,因此他们一个账户就会对应一个账号,有163.com,163.net,yeah.net,126.com等等的,我们先看看圈子的用户信息是如何显示的。

我们看到上图里面圈子的信息是一个列表,有的圈子多,有的圈子少,不过他们的名称中都会关联一个博客地址的,由于博客地址和邮件地址有一一对应关系,因此可以获取对应的邮件信息,这就是我们所要的重要信息。

下面用一个程序来介绍如何采集圈子的分类、圈子数据以及圈子用户资料信息,测试的程序如下所示:

下面我们来看看按钮”刷新分类数据“的实现代码,主要是获取圈子大类、圈子子类以及保存数据操作,代码如下所示:

private void btnRefreshCategory_Click(object sender, EventArgs e)
{
string url = http://q.163.com/;
string mainTypeReg = <div\\s*style=\”font-size:14px;\”><b><a\\s*?href=\”(?<value>.*?)\”>(?<key>.*?)</a></b></div>;
string subTypeReg = <div\\s*class=\”left\”><a\\s*href=\”(?<value>.*?)\”>(?<key>.*?)</a></div> ;

#region 取得大类

httpHelper.Encoding = Encoding.Default;
string content = httpHelper.GetHtml(url);
Regex re
= new Regex(mainTypeReg, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);
Match mc
= re.Match(content);
Dictionary
<string, string> typeDict = new Dictionary<string, string>();
if (mc.Success)
{
MatchCollection mcs
= re.Matches(content);
foreach (Match me in mcs)
{
string strKey = me.Groups[key].Value;
string strValue = me.Groups[value].Value;
//截取连接前面部分作为大类标识
string newValue = strValue.TrimEnd(/);
int eIndex = newValue.LastIndexOf(/);
newValue
= newValue.Substring(0, eIndex) + /;

if (!typeDict.ContainsKey(strKey))
{
typeDict.Add(strKey, newValue);
}
}
}
#endregion

#region 取得子类
Dictionary
<string, CircleSubTypeInfo> circleDict = new Dictionary<string, CircleSubTypeInfo>();
re
= new Regex(subTypeReg, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);
mc
= re.Match(content);
if (mc.Success)
{
MatchCollection mcs
= re.Matches(content);
foreach (Match me in mcs)
{
string strKey = me.Groups[key].Value;
string strValue = me.Groups[value].Value;
//截取连接前面部分作为大类标识
string typeValue = strValue.TrimEnd(/);
int eIndex = typeValue.LastIndexOf(/);
typeValue
= typeValue.Substring(0, eIndex) + /;

if (!circleDict.ContainsKey(strKey))
{
CircleSubTypeInfo info
= new CircleSubTypeInfo();
info.Name
= strKey;
info.LinkUrl
= strValue;
info.TypeUrlValue
= typeValue;

circleDict.Add(strKey, info);
}
}
}
#endregion

#region 保存数据
Database db
= DatabaseFactory.CreateDatabase();
DbCommand command
= null;
string SQL = “”;

foreach (string key in typeDict.Keys)
{
SQL
= string.Format(Insert into CircleType(TypeName, TypeValue) values(‘{0}’, ‘{1}’) , key, typeDict[key]);
command
= db.GetSqlStringCommand(sql);
db.ExecuteNonQuery(command);
}

foreach (string key in circleDict.Keys)
{
CircleSubTypeInfo info
= circleDict[key];
sql
= string.Format(Insert into CircleSubType(SubTypeName, LinkUrl, TypeUrlValue) values(‘{0}’, ‘{1}’, ‘{2}’) , info.Name, info.LinkUrl, info.TypeUrlValue);
command
= db.GetSqlStringCommand(sql);
db.ExecuteNonQuery(command);
}
#endregion

this.lblTips.Text = 获取分类操作完成;

}


其中主要是采用了正则表达式来对获取的内容进行处理,然后整理出来相关的分类数据放到数据库中,以便获取圈子用户信息作准备。

有了圈子分类信息,我们第二步骤就是看如何获取圈子数据,然后才能通过圈子的唯一ID获取圈子的用户资料,这步也是必须的,获取圈子资料是比较复杂的,需要组装较多的参数获取资料,部分代码如下所示。

foreach (string key in urlDict.Keys)
{
string keyNumberReg = /mapCircleList/(?<d1>[1-9]\\d*)/(?<d2>[1-9]\\d*)*/(?<d3>[1-9]\\d*)/;
Regex re
= new Regex(keyNumberReg, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);

LogTextHelper.WriteLine(string.Format(正在处理类型:{0}, urlDict[key]));
cookie
= new System.Net.CookieContainer();

string urlKey = key;
Match mc
= re.Match(urlKey);
string d1 = mc.Groups[d1].Value;
string d2 = mc.Groups[d2].Value;
string d3 = mc.Groups[d3].Value;
int pageSize = 30;

urlKey = urlKey.Trim(/);//清除前后的/字符
string url = http://q.163.com/dwr/call/plaincall/CircleMainpageBean.getCircleByType2IdInMemberOrder.dwr;
//string refUrl = “http://q.163.com/mapCircleList/2/11/48/?fromCircleCircleMap“;
string refUrl = string.Format(http://q.163.com/{0}/?fromCircleCircleMap, urlKey);
#region 内容正则表达式
StringBuilder circleReg
= new StringBuilder();
circleReg.Append(
s[0-9]\\d*.circleId=(?<circleId>[0-9]\\d*[^;]));
circleReg.Append(
.*?s[0-9]\\d*.circleType1Str=\”(?<circleType1Str>.*?)\”);
circleReg.Append(
.*?s[0-9]\\d*.circleType2Str=\”(?<circleType2Str>.*?)\”);
circleReg.Append(
.*?s[0-9]\\d*.createDateStr=\”(?<createDateStr>.*?)\”);
circleReg.Append(
.*?s[0-9]\\d*.creatorId=(?<creatorId>[0-9]\\d*[^;]));
circleReg.Append(
.*?s[0-9]\\d*.creatorName=\”(?<creatorName>.*?)\”);
circleReg.Append(
.*?s[0-9]\\d*.creatorSpaceUrl=\”(?<creatorSpaceUrl>.*?)\”);
circleReg.Append(
.*?s[0-9]\\d*.description=\”(?<description>.*?)\”);
circleReg.Append(
.*?s[0-9]\\d*.joinDeclaration=\”(?<joinDeclaration>.*?)\”);
circleReg.Append(
.*?s[0-9]\\d*.linkImgUrl=\”(?<linkImgUrl>.*?)\”);
circleReg.Append(
.*?s[0-9]\\d*.memberNum=(?<memberNum>[0-9]\\d*[^;]));
circleReg.Append(
.*?s[0-9]\\d*.name=\”(?<name>.*?)\”);
circleReg.Append(
.*?s[0-9]\\d*.urlName=\”(?<urlName>.*?)\”);
circleReg.Append( .*?s[0-9]\\d*.visitNum=(?<visitNum>[0-9]\\d*[^;]));


通过组装参数数据,然后获取页面数据,对页面数据进行分析即可,主要代码如下所示:

if (mc.Success)
{
string message = string.Format(正在处理类型{0}:{1}, 第{2}次数据, 共处理了{3}, urlDict[key], url, i + 1, j);
CallCtrlWithThreadSafety.SetText(
this.lblTips, message, this);
Application.DoEvents();
Thread.Sleep(
10);

MatchCollection mcs = re.Matches(content);
foreach (Match me in mcs)
{
#region MyRegion
j
++;

int memberNum = 0;
try
{
memberNum
= Convert.ToInt32(me.Groups[memberNum].Value);
}
catch { }
if (memberNum < 50)
{
flag
= false;
break;
}

sql
= string.Format(@”insert into Circle(circleId,circleType1Str,circleType2Str,createDateStr,creatorId,
creatorName,creatorSpaceUrl,description,joinDeclaration,linkImgUrl,memberNum,name2,urlName,SubTypeName)
values(‘{0}’,'{1}’,'{2}’,'{3}’,'{4}’,'{5}’,'{6}’,'{7}’,'{8}’,'{9}’,'{10}’,'{11}’,'{12}’,'{13}’)
, me.Groups[circleId].Value,
UnicodeHelper.UnicodeToString(me.Groups[
circleType1Str].Value.Replace(, “”)), UnicodeHelper.UnicodeToString(me.Groups[circleType2Str].Value.Replace(, “”)),
me.Groups[
createDateStr].Value, me.Groups[creatorId].Value, UnicodeHelper.UnicodeToString(me.Groups[creatorName].Value),
me.Groups[
creatorSpaceUrl].Value, UnicodeHelper.UnicodeToString(me.Groups[description].Value.Replace(, “”)), UnicodeHelper.UnicodeToString(me.Groups[joinDeclaration].Value.Replace(, “”)),
me.Groups[
linkImgUrl].Value, me.Groups[memberNum].Value, UnicodeHelper.UnicodeToString(me.Groups[name].Value.Replace(, “”)), me.Groups[urlName].Value, urlDict[key]);
command
= db.GetSqlStringCommand(sql);
try
{
db.ExecuteNonQuery(command);
}
catch (Exception ex)
{
LogTextHelper.WriteLine(sql);
LogTextHelper.WriteLine(ex.ToString());
}

message = string.Format(正在处理{0}:{1} 正在写入数据{2}次, urlDict[key], url, j);
CallCtrlWithThreadSafety.SetText(
this.lblTips, message, this);
Application.DoEvents();
Thread.Sleep(
10);

#endregion
}
}
else
{
flag
= false;//没有匹配就停止
break;
}

}

构造获取圈子用户信息也是比较复杂的一个过程,需要组装更多的参数来获取相关的数据,部分主要实现代码如下所示:

httpHelper = new HttpHelper();
httpHelper.Encoding
= Encoding.Default;
cookie
= new CookieContainer();
Regex re
= null;
Match mc
= null;
int pageSize = 30;
string url = http://q.163.com/dwr/call/plaincall/CircleBean.getNewCircleUsers.dwr;

foreach (string key in circlelDict.Keys)
{
string circleId = key;
string urlName = circlelDict[key];
string refUrl = string.Format(http://q.163.com/{0}/members/, urlName);

#region 内容正则表达式
StringBuilder circleReg
= new StringBuilder();
circleReg.Append(
s[0-9]\\d*.ageStr=\”(?<ageStr>.*?)\”);
circleReg.Append(
.*?s[0-9]\\d*.city=\”(?<city>.*?[^;])\”);
circleReg.Append(
.*?s[0-9]\\d*.hometownCity=(\”(?<hometownCity>.*?[^;])\”|(?<hometownCity>null)));
circleReg.Append(
.*?s[0-9]\\d*.hometownProvince=(\”(?<hometownProvince>.*?)\”|(?<hometownProvince>null)));
circleReg.Append(
.*?s[0-9]\\d*.name=(\”(?<name>.*?)\”|(?<name>null)));
circleReg.Append(
.*?s[0-9]\\d*.nickname=(\”(?<nickname>.*?)\”|(?<nickname>null)));
circleReg.Append(
.*?s[0-9]\\d*.profileImage140=\”(?<profileImage140>.*?)\”);
circleReg.Append(
.*?s[0-9]\\d*.profileImage60=\”(?<profileImage60>.*?)\”);
circleReg.Append(
.*?s[0-9]\\d*.province=\”(?<province>.*?)\”);
circleReg.Append(
.*?s[0-9]\\d*.qq=(\”(?<qq>.*?)\”|(?<qq>null)));
circleReg.Append(
.*?s[0-9]\\d*.realName=(\”(?<realName>.*?)\”|(?<realName>null)));
circleReg.Append(
.*?s[0-9]\\d*.spaceName=(\”(?<spaceName>.*?)\”|(?<spaceName>null)));
circleReg.Append(
.*?s[0-9]\\d*.userId=(?<userId>[0-9]\\d*[^;]));
circleReg.Append(
.*?s[0-9]\\d*.userName=\”(?<userName>.*?)\”);
#endregion

bool flag = true;
int i = 0;
int j = 0;
List
<CircleMemberInfo> entityList = new List<CircleMemberInfo>();
while (flag)
{
#region 构造提交参数
StringBuilder sb
= new StringBuilder();
sb.AppendFormat(
callCount=1);
sb.AppendFormat(
&page=/{0}/members/, urlName);
sb.AppendFormat(
&httpSessionId=);
sb.AppendFormat(
&scriptSessionId=D4DAC4AD9C3BF9B71C82802BDDBA0C25369);
sb.AppendFormat(
&c0-scriptName=CircleBean);
sb.AppendFormat(
&c0-methodName=getNewCircleUsers);
sb.AppendFormat(
&c0-id=0);//保留字符
sb.AppendFormat(&c0-param0=number:{0}, circleId);//11
sb.AppendFormat(&c0-param1=number:{0}, pageSize);//数量
sb.AppendFormat(&c0-param2=number:{0}, pageSize * i);//0,30,60
sb.AppendFormat(&c0-param3=boolean:true);
sb.AppendFormat(
&batchId={0}, i);

i++;

#endregion


然后我们通过代码来获取页面数据了,实现代码如下:

string content = “”;
try
{
httpHelper.ContentType
= text/plain;
content
= httpHelper.GetHtml(url, cookie, sb.ToString(), true, refUrl);
re
= new Regex(circleReg.ToString(), RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);
mc
= re.Match(content);
}
catch (Exception ex)
{
LogTextHelper.WriteLine(ex.ToString());
break;

}


然后我们就开始用正则表达式来分析返回的数据,以便显示或者添加到数据库中,以供他用,代码实现如下所示:、

MatchCollection mcs = re.Matches(content);
foreach (Match me in mcs)
{
#region MyRegion
j
++;

sql = string.Format(@”insert into CircleMember(userId,userName,realName,nickname,circleId)
values(‘{0}’,'{1}’,'{2}’,'{3}’,'{4}’)
, me.Groups[userId].Value, httpHelper.RemoveHtml(UnicodeHelper.UnicodeToString(me.Groups[userName].Value)),
httpHelper.RemoveHtml(UnicodeHelper.UnicodeToString(me.Groups[
realName].Value.Replace(, “”))), httpHelper.RemoveHtml(UnicodeHelper.UnicodeToString(me.Groups[nickname].Value.Replace(, “”))), circleId);
command
= db.GetSqlStringCommand(sql);
try
{
db.ExecuteNonQuery(command);
}
catch (Exception ex)
{
LogTextHelper.WriteLine(sql);
LogTextHelper.WriteLine(ex.ToString());
}

message = string.Format(正在处理{0} 正在写入数据{1}次, urlName, j);
CallCtrlWithThreadSafety.SetText(
this.lblTips, message, this);
Application.DoEvents();
Thread.Sleep(
10);
#endregion

}


以上就是获取数据的一个完整的过程,其中涉及到获取圈子大类、圈子分类、圈子信息,以及最终获取圈子的用户信息,其中较为详细的介绍了各种数据的正则分析过程,如果您有这方面的应用,一个可以参考下面的代码,第二个也可以参考我的软件《易博搜搜》,其中就涉及到了网易博客圈子的邮件采集,如下所示。


该软件除了可以采集网易博客圈子用户的邮件信息,给营销推广人提供资料外,还可以利用网易博客的找朋友模块,获取相关的用户数据信息,当然也是可以转换为邮件地址信息的了,如下所示。

以上对网易博客的应用的代码实现以及一个较为综合的软件产品介绍,希望能带给大家更多的启示和知识了解。

[转载]黑客伪造Google Android更新,瞄准中国Android用户

mikel阅读(892)

[转载]黑客伪造Google Android更新,瞄准中国Android用户_IT新闻_博客园.

据安全公司赛门铁克(Symantec)报道,Google最新的Android操作系统系统更新似乎被黑客攻破了。

Google刚刚发布一个叫做“Android市场安全工具(Android Market Security Tool)” 的程序来杀死“DroidDream”Android手机病毒,赛门铁克发现的这个病毒软件也叫“Android市场安全工具”,只不过对Google的 程序进行了重新打包。赛门铁克称这个虚假安全工具会发送短信到一个指挥控制服务器。目前他们正在分析病毒代码,这个病毒是在一个第三方应用市场中发现的, 攻击对象是中国用户。

最令人震惊的是这个病毒的代码托管在Google Code 上,采用了Apache许可协议。该病毒表明黑客对Android很感兴趣。

上周Google罕见地强制用户在Android手机上安装了Android市场安全工具,以便除去DroidDream病毒。通常负责向设备 发布更新的都是手机厂商或电信运营商,Google很少自己发布更新。Google之所以这么做是因为Google官方Android应用市场中有50多 款应用感染了DroidDream病毒,该病毒可以盗取用户的IMEI、IMSI等信息,然后发送到一台位于加州Fremont的服务器上。

DroidDream还会下载其他代码到用户的手机上,利用“exploid”和“rageagainstthecage”两个漏洞来感染手 机。Google已经在Android 2.2.2以上版本中打上了补丁,但遗憾的是很多Android用户没有安装最新版Android。卡巴斯基病毒分析师称Google的这个工具并没有修 复遭到攻击的漏洞,只不过除去了DroidDream。

[转载]WordPress 主题制作技巧之一 为 previous_post_link 等链接添加 title 属性

mikel阅读(925)

[转载]WordPress 主题制作技巧之一 [ 为 previous_post_link 等链接添加 title 属性 ] – Liu is Coding – 博客园.

使用 WordPress 自己搭建博客的网友可能越来越多,我用它也有一段时间了,尽管运行效率并不让人满意,但其丰富的插件让人着迷。WordPress 虽然有着众多的免费主题,但我想还是有很多朋友还是倾向于自定义个性鲜明的主题。我打算做一个极其简易的主题,让我的 WordPress 程序像个日记本一样一页一页地翻阅。制作主题和调整程序的过程中遇到一些小问题,本着学习的态度现在把它们记下来,也希望能给遇到这些问题的人提供一点我 的意见。
今天我要说的是:为 previous_post_link 等链接添加 title 属性
previous_post_link 和 lt_next_post_link 是经常用于单文章页面 single.php 中的用来链接上一篇和下一篇文章的函数,用过这两个函数的人会发现,函数执行结果在前台输出之后,当访客的鼠标滑过时是没有任何提示的,这在有时会造成一 定的不便,为了解决这个问题,我决定给 previous_post_link 和 lt_next_post_link 加上 title 属性。
先找到 previous_post_link、lt_next_post_link 以及与其相关的 adjacent_post_link 函数的代码,其代码位于根目录下的 wp-includes/link-template.php 文件中(大约是在1300多行的样子)。当然可以从这个文件里面直接改 previous_post_link、next_post_link、 adjacent_post_link 这三个函数,但是考虑到 link-template.php 是 WordPress 的核心文件,以后不知道哪次升级时就会被替换,所以我在模板文件夹中的 functions.php 中新建了三个函数 (lt_previous_post_link、lt_next_post_link、lt_adjacent_post_link) ,新建的这三个函数在原来函数的基础上增加了 title 属性。这样我模板文件中调用新建的 lt_previous_post_link 和 lt_next_post_link 来链接上一篇和下一篇文章。

代码如下:
1. previous_post_link、lt_next_post_link、adjacent_post_link 函数的代码
2. lt_previous_post_link、lt_next_post_link、lt_adjacent_post_link 函数的代码

效果如下:
1. 在模板中调用 previous_post_link、next_post_link 的效果
2. 在模板中调用 lt_previous_post_link、lt_next_post_link 的效果

OK,完成。