能搜到的 方法,无外乎判断 Http_referer 是否来源于本站和在网页里换行和回车后面添加本站名称和随机字符串。这两个方法对于略懂http协议和正则替换的兄弟来说,完全没用。对于我所知的和网上常用的几种方法具体分析如下:
1 判断http_referer
http_referer是http头中的一段,不管使用VB/VC 的 winsock / inet transfer 控件,还是 使用asp服务器就可以用的 xmlHttpRequest 对象 ( for ajax ) , 抑或是php socket 、python urllib2, 都可以轻易的修改http header , 从而直接修改 http_referer的值。最偷懒的做法就是,把http_referer赋值为你的网站根url或访问的页面url。VB 中的 WebBrowser 控件更是不存在这个问题……大不了抓的慢一些就是了
此方法唯一有效的,可能对采用Adodb.Stream对象的抓取
2 加入随机字串/本站名称/url
对于固定字串,如本站名称和url,很多成型的网页采集程序都直接提供选项可以替换掉,实现起来也很容易。被采集方由于有在页面内放置不可见元素和堆砌关键字的嫌疑,有可能还会被搜索引擎认为作弊,这招很不可取~
对于随机字串,直接用字符串替换是不可以的,但是如果结合页面源码合理的运用正则表达式,一样可以破掉。比如:匹配 [\w]{,16}<br> ,替换为空,就可以删掉处于<br>之前的16位随机字母、数字字符串
3 在网页内加入能中断页面运行的脚本
在网页中加入 诸如 <script>alert("xxx")</script> 之类的脚本,用以阻断页面执行和显示。想出这个方法来的兄弟一定很bt~ 但是又有些可笑。只要不是抓完就直接显示页面的,这个方法根本没用。具体原因不再多说。而且这样对于被采集方网站的用户体验是个很坏的方面。
-------------------------------------------------------------------------------------------------
4 我的方法
前几日要求写一个放采集的程序。要求使一个打印内容的列表页面防采集。前思后想,认为只有一个办法,就是打乱表格的输出次序,采用随机顺序输出,在客户端使用js操作dom调换顺序。这样,服务器端输出的html中的表格非常的乱,但是客户查看和打印时又能正常显示。缺点是,正确的顺序依然要输出到页面上,如果采集方根据这个规律也将表格内容重新排序,仍然是可以读取的。
实现方法如下
<%function swap(byref a,byref b)
dim c
c = a
a = b
b = c
end function
dim nam,tempRND,orders
redim orders(nRS + 1)
redim order(UBound(aRS,1))
orders(0) = join(array(1,2,3,4,5,6,7,8,9,0),",")
randomize
rnd()
i = 0
do while i <= nRS
for j = 0 to ubound(order)
order(j) = j
next
for j = 0 to ubound(order)' step 2
tempRND = int(rnd() * (UBound(order) + 1))
call swap(order(j),order(tempRND))
next
orders(i + 1) = join(order,",")
%>
<tr>
<%
' for j = 0 to UBound(order)
response.write "<td >"
response.Write aRS(order(j),i)
response.write "</td>"
next
' Response.write "</tr><tr>"
%>
</tr>
<%
i = i + 1
loop
%>
<script>
var aOrd = [[<%= join(orders,"],[") %>]];
reOrder("tblList",aOrd);
</script>
客户端重新组合方法如下:
function reOrder(sObj,aOrder)
...{
var o = document.getElementById(sObj).childNodes[0];
...{
try...{
var t = o.childNodes.length;
}catch(E)...{
alert(E.description);
return;
}
}
for(var i = 1; i < o.childNodes.length ;i++)...{
var aReOrder = new Array();
var tr = o.childNodes[i];
for(var j = 0; tr.hasChildNodes() ;j++)...{
aReOrder[aOrder[i][j]] = tr.removeChild(tr.childNodes[0]);
}
for(var j = 0; j < aReOrder.length;j++)...{
tr.appendChild(aReOrder[j]);
}
}
}
</script>
虽然这个不是完全一劳永逸的方法,至少可以难倒大批的不会js的程序员……