Sunday, July 26, 2009

下面是几个开门的flash动画地址:

下面是几个开门的flash动画地址:
http://swf.vip2.flashyc.com/Upload/2008-5-27/21416499.swf

http://www.cmqq.net/flash/men1.swf

http://www.cmqq.net/flash/men2.swf

http://www.cmqq.net/flash/men3.swf

http://www.cmqq.net/flash/men4.swf

http://www.cmqq.net/flash/men5.swf

http://www.cmqq.net/flash/men6.swf

http://www.cmqq.net/flash/men7.swf

http://www.518hi.com/html/UploadFile/2007-12/200712198520.swf

http://qq.tqqa.com/QQ348566936/teachsas/yinyong.swf

Tuesday, July 21, 2009

Board logo

标题: [原创]网站生成静态页面,及网站数据采集的攻、防原理和策略 [打印本页]
作者: zkq0 时间: 2005-11-28 15:34 标题: [原创]网站生成静态页面,及网站数据采集的攻、防原理和策略

复制内容到剪贴板
代码:
文章标题:网站生成静态页面,及网站数据采集的攻、防原理和策略
发布时间:2005年11月27日 晚
文章作者:翟振凯 (小琦)
交流方式:
个人站:http://www.xiaoqi.net
技术站:http://www.iisvs.net
商业站:http://www.iisvs.com
QQ:53353866 22336848
关于本文:
本着互联网共享主义精神,特写此文献给建站新手,授人以鱼,不如授人以渔,本文所讲的只是方法和原理,希望大家看完此文,能够从中得到些帮助和启发。
本文从一个ASP程序员的角度用大量实例祥细介绍了动态网站如何生成静态页面原理,又从一个采集程序开发者的角度去祥细介绍了网站数据采集的原理及功防策略。
关于网站生成静态页面,为了让本文读者容易理解,文内列举了目前常用的多种生成静态页面的方法,其中用了很多的实例代码进行说明。
关于网站数据采集攻防,作者本身是一个采集程序的开发者,同时作者也收集研究了多种采集程序,列举了目前国内比较流行的几种防采集策略,并对每种策略作了简单客观的分析评价,希望能给广大站长们提供一些帮助。此章节也把作者原创的防采集方法奉献给大家,目地是为了让大家了解,防采集,不防搜索引擎,是可行的,有效的。
声明:希望各位朋友转载时,不要把原有作者版权去掉,谢谢合作。
由于本人写作水平有限,写的不好的地方,还请大家多多包涵,如要批评或意见,请加我QQ。
目前很多人都开始注重动态页面生成HTML页了,但选择哪种生成HTML的方法和防采集却不防搜索引擎的问题却经常困扰大家。解决此问题则是本文产生的原因。
作者:翟振恺(小琦)


首先祥细说一下常用的几种生成HTML的方法:


生成HTML方法主要步骤只有两个:
一、获取要生成的html文件的内容
二、将获取的html文件内容保存为html文件

我在这里主要说明的只是第一步:如何获取要生成的html文件的内容:
目前常用获取html文件的内容的方法有几下几种:
1、
复制内容到剪贴板
代码:
str="<html标记>内容</html标记>"
str=str&"<html标记>内容</html标记><html标记>数据库读取内容....</html标记>....."
这种方法与是在脚本内写要生成的html内容,不太方便预览生成页面的内容,无法可视化布局页面,更改html模板时会更加复杂。
用这种方法的人很多,但我感觉这种方法是最不方便的。

2、
制作单独的HTML模板页,动态的内容用特定的字符作为标记(如:有人用$title$标记为网页标题),用ADODB.Stream或者Scripting.FileSystemObject将其模板内容载入,然后再用替换方法把原先定好的标记替换为动态内容(如:Replace(载入的模板内容,"$title$",rs("title" ) ) )。

3、
用XMLHTTP或serverXMLHTTP获取动态页所显示的HTML内容,
复制内容到剪贴板
代码:
我常用的生成html文件的实例:
'-----------------翟振恺(小琦)
'weburl是要获取的动态页地址
'getHTTPPage(weburl)是获取动态页内容的函数
weburl="http://"&Request.ServerVariables("SERVER_NAME")&"/contact.asp?id="&rs("id")&""‘指定动态页地址
body=getHTTPPage(weburl)'用函数取到动态页地址的内容
'-----------------翟振恺(小琦)
此方法最大的好处就是不用费力气专门去写静态的模板页面,只是将原来就有的动态页面转换为HTML静态页面,但生成速度不是太快。

我常用的生成HTML的方法就是第3种:用XMLHTTP获取动态页生成的HTML内容,再用ADODB.Stream或者Scripting.FileSystemObject保存成html文件。

第二步是生成文件的方法:
ASP里常用的有用ADODB.Stream生成文件和Scripting.FileSystemObject生成文件两种
1、

Scripting.FileSystemObject生成文件方法:
复制内容到剪贴板
代码:
'-----------------翟振恺(小琦)
Set fso = CreateObject("Scripting.FileSystemObject")
File=Server.MapPath("要生成文件路径和文件名.htm")
Set txt=fso.OpenTextFile(File,8,True)
data1="文件内容"用WriteLine方法生成文件
txt.WriteLine data1
data2="文件内容"'用Write方法生成文件
txt.Write data2
txt.Close
txt.fso
'-----------------翟振恺(小琦)
2、

ADODB.Stream生成文件方法:
复制内容到剪贴板
代码:
'-----------------翟振恺(小琦)
Dim objAdoStream
set objAdoStream = Server.createObject("ADODB.Stream")
objAdoStream.Type = 1
objAdoStream.Open()
objAdoStream.Write("文件内容")
objAdoStream.SaveToFile 要生成文件路径和文件名.htm,2
objAdoStream.Close()
'-----------------翟振恺(小琦)
再说一下我对HTML防采集却不防搜索引擎蜘蛛的一些经验:

我开发过几个采集程序,也研究过很多采集程序代码,所以对采集程序的原理还算是稍微有些了解。
先说一下采集原理:

采集程序的主要步骤如下:

一、获取被采集的页面的内容
二、从获取代码中提取所有用的数据

一、获取被采集的页面的内容

我目前所掌握的ASP常用获取被采集的页面的内容方法:

1、用serverXMLHTTP组件获取数据
复制内容到剪贴板
代码:
Function GetBody(weburl)
'-----------------翟振恺(小琦)
'创建对象
Dim ObjXMLHTTP
Set ObjXMLHTTP=Server.CreateObject("MSXML2.serverXMLHTTP")
'请求文件,以异步形式
ObjXMLHTTP.Open "GET",weburl,False
ObjXMLHTTP.send
While ObjXMLHTTP.readyState <> 4
ObjXMLHTTP.waitForResponse 1000
Wend
'得到结果
GetBody=ObjXMLHTTP.responseBody
'释放对象
Set ObjXMLHTTP=Nothing
'-----------------翟振恺(小琦)
End Function
调用方法:
GetBody(文件的URLf地址)
2、或XMLHTTP组件获取数据
复制内容到剪贴板
代码:
Function GetBody(weburl)
'-----------------翟振恺(小琦)
'创建对象
Set Retrieval = CreateObject("Microsoft.XMLHTTP")
With Retrieval
.Open "Get", weburl, False, "", ""
.Send
GetBody = .ResponseBody
End With
'释放对象
Set Retrieval = Nothing
'-----------------翟振恺(小琦)
End Function
调用方法:
GetBody(文件的URLf地址)
这样获取的数据内容还需要进行编码转换才可以使用
复制内容到剪贴板
代码:
Function BytesToBstr(body,Cset)
'-----------------翟振恺(小琦)
dim objstream
set objstream = Server.CreateObject("adodb.stream")
objstream.Type = 1
objstream.Mode =3
objstream.Open
objstream.Write body
objstream.Position = 0
objstream.Type = 2
objstream.Charset = Cset
BytesToBstr = objstream.ReadText
objstream.Close
set objstream = nothing
'-----------------翟振恺(小琦)
End Function
调用方法:BytesToBstr(要转换的数据,编码)'编码常用为GB2312和UTF-8
二、从获取代码中提取所有用的数据
目前我掌握的方法有:
1、用ASP内置的MID函数截取需要的数据
复制内容到剪贴板
代码:
Function body(wstr,start,over)
'-----------------翟振恺(小琦)
start=Newstring(wstr,start)
'设置需要处理的数据的唯一的开始标记
over=Newstring(wstr,over)
'和start相对应的就是需要处理的数据的唯一的结束标记
body=mid(wstr,start,over-start)
'设置显示页面的范围
'-----------------翟振恺(小琦)
End Function
调用方法:body(被采集的页面的内容,开始标记,结束标记)
2、用正则获取需要的数据
复制内容到剪贴板
代码:
Function body(wstr,start,over)
'-----------------翟振恺(小琦)
Set xiaoqi = New Regexp'设置配置对象
xiaoqi.IgnoreCase = True'忽略大小写
xiaoqi.Global = True'设置为全文搜索
xiaoqi.Pattern = "”&start&“.+?”&over&“"'正则表达式
Set Matches =xiaoqi.Execute(wstr)'开始执行配置
set xiaoqi=nothing
body=""
For Each Match in Matches
body=body&Match.Value '循环匹配
Next
'-----------------翟振恺(小琦)
End Function
调用方法:body(被采集的页面的内容,开始标记,结束标记)
采集程序祥细思路:
1、取得网站的分页列表页的每页地址
目前绝大部分动态网站的分页地址都有规则,如:
动态页
第一页:index.asp?page=1
第二页:index.asp?page=2
第三页:index.asp?page=3
.....

静态页
第一页:page_1.htm
第二页:page_2.htm
第三页:page_3.htm
.....
取得网站的分页列表页的每页地址,只需要用变量替代每页地址的变化的字符即可如:page_<%="&page&"%>.htm

2、获取被采集网站的分页列表页内容
3、从分页列表代码中提取被采集的内容页面的URL连接地址
绝大部分分页页面里的内容页连接也有固定规则,如:
<a href="url1">连接1</a> <br>
<a href="url2">连接2</a> <br>
<a href="url3">连接3</a> <br>

用以下代码就可以获得一个URL连接集合
复制内容到剪贴板
代码:
'-----------------翟振恺(小琦)
Set xiaoqi = New Regexp
xiaoqi.IgnoreCase = True
xiaoqi.Global = True
xiaoqi.Pattern = ””“.+?”““
Set Matches =xiaoqi.Execute(页面列表内容)
set xiaoqi=nothing
url=""
For Each Match in Matches
url=url&Match.Value
Next
'-----------------翟振恺(小琦)
4、取得被采集的内容页面内容,根据”提取标记“从被采集的内容页面分别截取要取得的数据

因为是动态生成的页面,大多数内容页面内都有相同的html标记,我们可以根据这些有规则的标记提取需要的各个部分的内容。
如:
每个页面都有网页标题<title>网页标题</title>,用我上面写的MID截取函数就可以获得<title></title>之间的值,也可以用正则表达式来获得。
例:body("<title>网页标题</title>","<title>","</title>")


介绍完采集器的祥细原理后,就开始说一下防采集的策略。

目前防采集的方法有很多种,先介绍一下常见防采集策略方法和它的弊端及采集对策:

一、判断一个IP在一定时间内对本站页面的访问次数,如果明显超过了正常人浏览速度,就拒绝此IP访问
弊端:
1、此方法只适用于动态页面,如:asp\jsp\php等...静态页面无法判断某个IP一定时间访问本站页面的次数
2、此方法会严重影响搜索引擎蜘蛛对其收录,因为搜索引擎蜘蛛收录时,浏览速度都会比较快而且是多线程。此方法也会拒绝搜索引擎蜘蛛收录站内文件
采集对策:只能放慢采集速度,或者不采
建议:做个搜索引擎蜘蛛的IP库,只允许搜索引擎蜘蛛快速浏览站内内容。搜索引擎蜘蛛的IP库的收集,也不太容易,一个搜索引擎蜘蛛,也不一定只有一个固定的IP地址。
评论:此方法对防采集比较有效,但却会影响搜索引擎对其收录。

二、用javascript加密内容页面

弊端:此方法适用于静态页面,但会严重影响搜索引擎对其收录情况,搜索引擎收到到的内容,也都是加密后的内容
采集对策:建议不采,如非要采,就把解密码的JS脚本也采下来。
建议:目前没有好的改良建议
评论:建议指望搜索引擎带流量的站长不要使用此方法。

三、把内容页面里的特定标记替换为”特定标记+隐藏版权文字“

弊端:此方法弊端不大,仅仅会增加一点点的页面文件大小,但容易反采集
采集对策:把采集来的含有隐藏版权文字内容的版权文字替掉,或替换成自己的版权。
建议:目前没有好的改良建议
评论:自己感觉实用价值不大,就算是加上随机的隐藏文字,也等于画蛇添足。


四、只允许用户登陆后才可以浏览
弊端:此方法会严重影响搜索引擎蜘蛛对其收录
采集对策:目前落伍已经有人发了对策文章 ,具体对策就看这个吧《ASP小偷程序如何利用XMLHTTP实现表单的提交以及cookies或session的发送》
建议:目前没有好的改良建议
评论:建议指望搜索引擎带流量的站长不要使用此方法。不过此方法防一般的采集程序,还是有点效果的。

五、用javascript、vbscript脚本做分页
弊端:影响搜索引擎对其收录
采集对策:分析javascript、vbscript脚本,找出其分页规则,自己做个对应此站的分页集合页即可。
建议:目前没有好的改良建议
评论:感觉懂点脚本语言的人都能找出其分页规则

六、只允许通过本站页面连接查看,如:Request.ServerVariables("HTTP_REFERER")
弊端:影响搜索引擎对其收录
采集对策:不知道能不能模拟网页来源。。。。目前我没有对应此方法的采集对策
建议:目前没有好的改良建议
评论:建议指望搜索引擎带流量的站长不要使用此方法。不过此方法防一般的采集程序,还是有点效果的。

从以上可以看出,目前常用的防采集方法,要么会对搜索引擎收录有较大影响,要么防采集效果不好,起不到防采集的效果。那么,还有没有一种有效防采集,而又不影响搜索引擎收录的方法呢?那就请继续往下看吧,精彩的地方马上呈献给大家。

下面就是我的防采集策略,防采集而又不防搜索引擎

从前面的我讲的采集原理大家可以看出,绝大多数采集程序都是靠分析规则来进行采集的,如分析分页文件名规则、分析页面代码规则。

一、分页文件名规则防采集对策

大部分采集器都是靠分析分页文件名规则,进行批量、多页采集的。如果别人找不出你的分页文件的文件名规则,那么别人就无法对你的网站进行批量多页采集。
实现方法:
我认为用MD5加密分页文件名是一个比较好的方法,说到这里,有人会说,你用MD5加密分页文件名,别人根据此规则也可以模拟你的加密规则得到你的分页文件名。

我要指出的是我们加密分页文件名时,不要只加密文件名变化的部分
如果I代表分页的页码,那么我们不要这样加密
page_name=Md5(I,16)&".htm"

最好给要加密的页码上再跟进一个或多个字符,如:page_name=Md5(I&"任意一个或几个字母",16)&".htm"

因为MD5是无法反解密的,别人看到的会页字母是MD5加密后的结果,所以加人也无法知道你在 I 后面跟进的字母是什么,除非他用暴力****MD5,不过不太现实。

二、页面代码规则防采集对策

如果说我们的内容页面无代码规则,那么别人就无法从你的代码中提取他们所需要的一条条内容。
所以我们要的这一步做到防采集,就要使代码无规则。
实现方法:
使对方需要提取的标记随机化
1、定制多个网页模板,每个网页模板里的重要HTML标记不同,呈现页面内容时,随机选取网页模板,有的页面用CSS+DIV布局,有的页面用table布局,此方法是麻烦了点,一个内容页面,要多做几个模板页面,不过防采集本身就是一件很烦琐的事情,多做一个模板,能起到防采集的作用,对很多人来说,都是值得的。
2、如果嫌上面的方法太麻烦,把网页里的重要HTML标记随机化,也可以。

做的网页模板越多,html代码越是随机化,对方分析起内容代码时,就越麻烦,对方针对你的网站专门写采集策略时,难度就更大,在这个时候,绝大部分人,都会知难而退,因为这此人就是因为懒,才会采集别人网站数据嘛~~~再说一下,目前大部分人都是拿别人开发的采集程序去采集数据,自己开发采集程序去采集数据的人毕竟是少数。

还有些简单的思路提供给大家:
1、把对数据采集者重要,而对搜索引擎不重要的内容用客户端脚本显示
2、把一页数据,分为N个页面显示,也是加大采集难度的方法
3、用更深层的连接,因为目前大部分采集程序只能采集到网站内容的前3层,如果内容所在的连接层更深,也可以避免被采集。不过这样可能会给客户造成浏览上的不便。
如:
大多网站都是 首页----内容索引分页----内容页
如果改成:
首页----内容索引分页----内容页入口----内容页
注:内容页入口最好能加上自动转入内容页的代码
复制内容到剪贴板
代码:
<meta http-equiv="refresh" content="6;url=内容页(http://www.xiaoqi.net)">
其实,只要做好防采集的第一步(加密分页文件名规则),防采集的效果就已经不错了,还是建议两条反采集方法同时使用,给采集者增加采集难度,使得他们知难页退。

至此,全文完,欢迎大家在此讨论与此相关技术,谢谢!
作者:翟振恺(小琦)
网址:iisvs.com http://www.xiaoqi.net
希望大家转载时,不要把作者版权去掉,谢谢合作! 作者: zkq0 时间: 2005-11-29 14:40

Thursday, July 2, 2009

获取指定CLASS内的信息

import java.lang.reflect.*;

/**
* 获取指定CLASS内的信息(方法,包)
*/

public class ClassInfo {

public ClassInfo() {
}

public static void main(String[] args) throws Exception {
String fullClassName;
if (args.length != 1) {
fullClassName = "java.lang.String";
} else {
fullClassName = args[0];
}

Class cls = Class.forName(fullClassName);

// (1.) 创建实例
Object o = cls.newInstance();

// (2.) 取得package名
Package pack = cls.getPackage();
String packageName = pack.getName();
System.out.println("package: " + packageName);
System.out.println();

// (3.) 取得类名
String className = cls.getName();
System.out.println("class name: " + className);
System.out.println();

// (4.) 取成员变量名
Field[] fields = cls.getFields();
int i;
System.out.println("成员变量");
for (i = 0; i < fields.length; i++) {
System.out.println(" " + fields[i].toString());
}
System.out.println();

// (5.) 取得成员方法
Method[] methods = cls.getMethods();
System.out.println("成员方法");
for (i = 0; i < methods.length; i++) {
System.out.println(" " + methods[i].toString());
}
}
}

Java Hashtable example.

/*

Java Hashtable example.

This Java Hashtable example describes the basic operation performed on the hashtable.

*/

import java.util.Hashtable;

import java.util.Enumeration;

public class HashtableExample{

public static void main(String args[]){

// constructs a new empty hashtable with default initial capacity

Hashtable hashtable = new Hashtable();

/*

To specify initial capacity, use following constructor.

燞ashtable hashtable = new Hashtable(100);

燭o create hashtable from map use following constructor

燞ashtable hashtable = new Hashtable(Map myMap);

?/

hashtable.put( "One", new Integer(1) ); // adding value into hashtable

hashtable.put( "Two", new Integer(2) );

hashtable.put( "Three", new Integer(3) );

/*

IMPORTANT : We CAN NOT add primitives to the hashtable. We have to wrap it into one of the wrapper before adding.

*/

/*

To copy all key - value pairs from Map to Hashtable use putAll method.

Signature of putAll method is,

void putAll(Map m)

*/

//get number of keys present in the hashtable

System.out.println("Hashtable contains " + hashtable.size() + " key value pair.");

/*

To check whether Hashtable is empty or not, use isEmpty() method.

isEmpty() returns true is Hashtable is empty, otherwise false.

*/

/*

Finding particular value from the Hashtable :

Hashtable's contains method returns boolean depending upon the presense of the value in given hashtable

Signature of the contains method is,

boolean contains(Object value)

*/

if( hashtable.contains( new Integer(1) ) ){

System.out.println("Hashtable contains 1 as value");

}else{

System.out.println("Hashtable does not contain 1 as value");

}

/*

Finding particular Key from the Hashtable :

Hashtable's containsKey method returns boolean depending upon the presense of the key in given hashtable

Signature of the method is,

boolean containsKey(Object key)

*/

if( hashtable.containsKey("One") ){

System.out.println("Hashtable contains One as key");

}else{

System.out.println("Hashtable does not contain One as value");

}

/*

Use get method of Hashtable to get value mapped to particular key.

Signature of the get method is,

Object get(Object key)

*/

Integer one = (Integer) hashtable.get("One");

System.out.println("Value mapped with key \"One\" is " + one);

/*

IMPORTANT:?get method returns Object, so we need to downcast it.

*/

/*

To get all keys stored in Hashtable use keys method.

Signature of the keys method is,

Enumeration keys()

To get Set of the keys use keySet() method instead.

Set keySet()

*/

System.out.println("Retriving all keys from the Hashtable");

Enumeration e = hashtable.keys();

while( e. hasMoreElements() ){

System.out.println( e.nextElement() );

}

/*

To get all values stored in Hashtable牋牋 use elements method.

Signature of the elements method is,

Enumeration elements()

To get Set of the values use entrySet() method instead.

Set entrySet()

*/

System.out.println("Retriving all values from the Hashtable");

e = hashtable.elements();

while( e. hasMoreElements() ){

System.out.println( e.nextElement() );

}

/*

To remove particular key - value pair from the Hashtable use remove method.

Signature of remove methid is,

Object remove(Object key)

This method returns value that had mapped to the given key, otherwise null if mapping not found.

*/

System.out.println( hashtable.remove("One") + " is removed from the Hashtable.");

}

}

/*

OUTPUT of the above given Java Hashtable Example would be :

Hashtable contains 3 key value pair.

Hashtable contains 1 as value

Hashtable contains One as key

Value mapped with key "One" is 1

Retriving all keys from the Hashtable

One

Three

Two

Retriving all values from the Hashtable

1

3

2

1 is removed from the Hashtable.

*/

Wednesday, July 1, 2009

TOMCAT6+SPRING+HIBERNATE JNDI 数据源配置

1.
在context.xml中的context标签内加入以下代码:

<Resource name="jdbc/mysql" auth="Container"
type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/yourdbname"
username="root"

password="root"

maxActive="20"

maxIdle="10"/>


2、在web.xml中web-app下加入以下代码


<resource-ref>
<description>MySql DataSource</description>
<res-ref-name>jdbc/yourdbname</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>


3. 在SPRING的配置文件中加入如下代码


<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">

<value>java:comp/env/jdbc/yourdbname</value>

</property>
</bean>


4. 最后在你的SPRING配置文件中加入以下代码接管HIBERNATE的配置


<beans>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>这里是加载的HIBERNATE OR 文件</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">

org.hibernate.dialect.MySQLInnoDBDialect

</prop>

</props>

</property>

</bean>

</beans>