您现在的位置是:网站首页> 编程资料编程资料

用asp+xmlhttp编写web采集程序_小偷/采集_

2023-05-25 168人已围观

简介 用asp+xmlhttp编写web采集程序_小偷/采集_

web采集程序?网页抓取程序?小倫程序?不管怎么叫,这种程序应用倒是蛮广的。本文不讨论这种使用这种程序引起的版权或道德问题,只谈这种程序在ASP+VBScript环境下的实现 :-)

预备知识:除了一般的ASP+VBScript的知识外,你还需要了解xmlhttp对象和正则表达式对象。xmlhttp对象是时下风头正劲的Ajax的主角;而学好了正则表达式,你再也不用为处理复杂的字符串犯愁。

在编写和调试正则表达式时,RegEx 这个小工具非常有用。 

目录
抓取一个远程网页并保存到本地 
改进:处理乱码 
同时下载远程网页的图片(和其它文件) 
改进:探测真实URL 
改进:避免重复下载 
实战举例(以****为例) 
分析列表页 
内容页的技巧 
分析内容页中的上一页,下一页 
高级主题:UTF-8和GB2312的转换 
更多高级主题:登陆后抓取,客户端伪造 
己有的采集程序 
原文链接:http://gwx.showus.net/blog/article.asp?id=229


1.抓取一个远程网页并保存到本地
'用于调试的过程,后面会多次调用检查中间结果
Dim inDebug:inDebug=True 
Sub D(Str)
    If inDebug = False Then Exit Sub
    Response.Write("")
    Response.Write(Str &"
")
    Response.Flush()
End Sub

'过程: Save2File
'功能: 把文本或字节流保存为文件
'参数: sContent    要保存的内容
'       sFile       保存到文件,形如"files/abc.htm"
'       bText       是否是文本
'       bOverWrite  是否覆盖己存在文件
Sub Save2File(sContent,sFile,bText,bOverWrite)
    Call D("Save2File:"+sFile+" *是否文本:"&bText)
    Dim SaveOption,TypeOption
    If (bOverWrite = True) Then SaveOption=2 Else SaveOption=1
    If (bText = True) Then TypeOption=2 Else TypeOption=1
    Set Ads = Server.CreateObject("Adodb.Stream")
    With Ads
        .Type = TypeOption 
        .Open
        If (bText = True) Then .WriteText sContent Else .Write sContent
        .SaveToFile Server.MapPath(sFile),SaveOption
        .Cancel()
        .Close()
    End With
    Set Ads=nothing
End Sub

关键的函数
'函数: myHttpGet
'功能: 抓取一个远程文件(网页或图片等)并保存到本地
'参数: sUrl    远程文件的URL
'       bText   是否是文本(网页),下载远程图片是bText=False
'返回: 抓取的内容
Function myHttpGet(sUrl,bText)
    Call D("myHttpGet:"+sUrl+" *是否文本:"&bText)
    'Set oXml = Server.CreateObject("Microsoft.XMLHTTP")
    Set oXml = Server.CreateObject("MSXML2.ServerXMLHTTP")  '服务器版本的XMLHTTP组件
    '理解下面的内容,你可以参考一下MSDN中的MSXML2.ServerXMLHTTP
    With oXml
        .Open "GET",sUrl,False
        .Send
        While .readyState <> 4  '等待下载完毕
            .waitForResponse 1000 
        Wend 
        If bText = True Then
            myHttpGet = bytes2BSTR(.responseBody)
        Else
            myHttpGet = .responseBody
        End If
    End With
    Set oXml = Nothing
End Function

改进:处理乱码
直接读取服务器返回的中文内容会出现乱码,myHttpGet函数中引用的bytes2BSTR的作用是正确读取服务器返回的文件中的双字节文本(比如说中文)
'myHttpGet helper 处理双字节文本
Function bytes2BSTR(vIn)
    strReturn = ""
    For i = 1 To LenB(vIn)
        ThisCharCode = AscB(MidB(vIn,i,1))
        If ThisCharCode < &H80 Then
            strReturn = strReturn & Chr(ThisCharCode)
        Else
            NextCharCode = AscB(MidB(vIn,i+1,1))
            strReturn = strReturn & Chr(CLng(ThisCharCode) * &H100 + CInt(NextCharCode))
            i = i + 1
        End If
    Next
    bytes2BSTR = strReturn
End Function

bytes2BSTR函数的功能也可以利用Adodb.Stream组件通过下面的函数实现,虽然下面的函数可以指定字符集Charset,但它并不能转换编码,即传递"UTF-8"给参数sCset,来读取一张GB2312编码的网页将显示为乱码。
'CharsetHelper可以正确的读取以sCset(如"GB2312","UTF-8"等)编码的文件
Function CharsetHelper(arrBytes,sCset)
    Call D("CharsetHelper: "+sCset)
    Dim oAdos
    Set oAdos = CreateObject("Adodb.Stream")
    With oAdos
        .Type = 1
        .Mode =3    'adModeReadWrite
        .Open
        .Write arrBytes
        .Position = 0
        .Type = 2
        .Charset = sCset
        CharsetHelper = .ReadText 
        .Close
    End With
    Set oAdos = Nothing
End Function 

2.同时下载远程网页的图片(和其它文件)
'函数: ProcessRemoteUrl
'功能: 替换字符串中的远程文件为本地文件并保存远程文件
'参数: strContent  要替换的字符串,即远程网页文件的内容
'       sSavePath   不以/结尾的相对路径,指示远程文件的本地保存路径
'       sPreceding  更改后的URL前缀,如http://somehost/upload/
'返回: 替换远程路径为本地路径之后的新的网页文本内容
Function ProcessRemoteUrl(sContent,sSavePath,sPreceding)
    Call D("ProcessRemoteUrl")

    Set re=new RegExp
    re.IgnoreCase =true
    re.Global=True
    '下面的正则中.SubMatches(4)=文件名全名.SubMatches(5)文件扩展名
    re.Pattern = "((http):(?:\/\/){1}(?:(?:\w)+[.])+(net|com|cn|org|cc|tv|[0-9]{1,4})(\S*\/)((?:\S)+[.]{1}(gif|jpg|jpeg|png|bmp)))"

    Set RemoteFile = re.Execute(sContent)

    Dim SaveFileName
    'RemoteFile     正则表达式Match对象的集合
    'RemoteFileUrl  正则表达式Match对象
    For Each RemoteFileUrl in RemoteFile
        SaveFileName = RemoteFileUrl.SubMatches(4)
        Call Save2File(myHttpGet(RemoteFileUrl,False),sSavePath&"/"&SaveFileName,False,True)
        sContent=Replace(sContent,RemoteFileUrl,sPreceding&SaveFileName)
    Next

    ProcessRemoteUrl=sContent
End Function 
改进:探测真实URL
上面的ProcessRemoteUrl函数不能正确处理形如'函数: DetectUrl
'功能: 替换字符串中的远程文件相对路径为以http://..开头的绝对路径
'参数: sContent    要处理的含相对路径的网页的文本内容
'       sUrl        所处理的远程网页自身的URL,用于分析相对路径
'返回: 替换相对链接为绝对链接之后的新的网页文本内容
Function DetectUrl(sContent,sUrl)
    Call D("DetectUrl:"&sUrl)

    '分析URL
    Dim re,sMatch
    Set re=new RegExp
    re.Multiline=True
    re.IgnoreCase =true
    re.Global=True

    re.Pattern = "(http://[-A-Z0-9.]+)/[-A-Z0-9+&@#%~_|!:,.;/]+/"
    Dim sHost,sPath
    'http://localhost/get/sample.asp
    Set sMatch=re.Execute(sUrl)
    'http://localhost
    sHost=sMatch(0).SubMatches(0)
    'http://localhost/get/
    sPath=sMatch(0)

    re.Pattern = "(src|href)=""?((?!http://)[-A-Z0-9+&@#%=~_|!:,.;/]+)""?"
    Set RemoteFile = re.Execute(sContent)

    'RemoteFile 正则表达式Match对象的集合
    'RemoteFileUrl 正则表达式Match对象,形如src="Upload/a.jpg"
    Dim sAbsoluteUrl
    For Each RemoteFileUrl in RemoteFile
        ',,
        If Left(RemoteFileUrl.SubMatches(1),1)="/" Then
            sAbsoluteUrl=sHost
        Else
            sAbsoluteUrl=sPath
        End If
        sAbsoluteUrl = RemoteFileUrl.SubMatches(0)&"="""&sAbsoluteUrl&RemoteFileUrl.SubMatches(1)&""""
        sContent=Replace(sContent,RemoteFileUrl,sAbsoluteUrl)
    Next

    DetectUrl=sContent
End Function 
改进:避免重复下载
网页中的有些图片,比如spacer.gif重复出现,会被重复下载,壁免这个问题的一个方法是设置一个arrUrls数组,把采集过的文件的URL放在里面,在每次采集前先遍历数组看是否已经采集,然后只参集没有参集过的文件

3.实战举例(以****为例)
****是我最经常去的地方,而且网速不错,就以她为例啦,没有恶意哦:-)

分析列表页
内容页的技巧
分析内容页中的上一页,下一页
想了一下,这部分内容还是晢时不写,免得被BS了  :-),还省得打好多字。 无非是把远程网页采集下来,然后用正则表达式分析提取其中的特定内容,如标题,作者,内容之类的 我有两个小小的经验: 

一是网页源码前后的内容对分析有很大的干扰,你可以用下面的方法先把它支除
'抽取部分内容进行分析,你可以用用EditPlus数字数
'去除前7600和后5000的字符
sPageW=Left(sPageW,Len(sPageW)-5000)
sPageW=Mid(sPageW,7600)

二是你可能不想在对方的服务器上留下连续的浏览记录,下面的一个小函数会有所帮助
'过程: Sleep
'功能: 程序在此晢停几秒
'参数: iSeconds    要暂停的秒数
Sub Sleep(iSeconds)
    D Timer()&" Sleep For "&iSeconds&" Seconds"
    Dim t:t=Timer()
    While(Timer()        'Do Nothing
    Wend
    D Timer()&" Sleep For "&iSeconds&" Seconds OK"
End Sub

'调用举例,晢停,时长随机,在3秒以内
Sleep(Fix(Rnd()*3)) 

三就是多用正则表达式测试工具提高编写正则表达式的效率

4.高级主题:UTF-8和GB2312的转换
这个问题比较复杂,由于我智力和精力方面的原因没有完全搞定,网上己有的资料也大多不完全正确或者不全面,我推荐一个UTF-8和GB2312的转换的C语言的实现供大家参考,它功能完整而且不依赖Windows API函数。
我在试着用ASP+VBScript实现它,有一些不太成熟的经验:

计算机上的文件、操作系统内部的字符串表示都是Unicode的,所以,UTF-8和GB2312之间的转换需要以Unicode为中介 
UTF-8就是Unicode的一个变体,它们之间的相互转换比较简单,参考下图就可以了 
GB2312和Unicode的编码好像是不相关的,不依赖操作系统内部函数进行转换就需要一个编码映射表,指出GB2312和Unicode的编码一一对应的关系,这个编码表大约包含7480×2个项目。 
在ASP文件中,要默认以某和编码(如GB2312)读取一个字符串,需要将ASP的CodePage设为相应代码页(对GB2312是CodePage=936) 
编码转换中还有一些又小又重要的问题我还不知道:-( 
5.更多高级主题:登陆后抓取,客户端伪造等
xmlhttp对象可以以post或get的方法与http服务器交互,可以设置和读取http头,学习一下http协议,并且更深入的了解一些xmlhttp对象的方法和属性,你就可以用它来模拟一个浏览器,自动的做各种以前需要人来做的重复工作。


6.己有的采集程序
本文旨在讨论采集程序在ASP+VBScript环境下的实现,如果你需要一个网页采集程序,下面的链接可能对你有用。 

LocoySpider火车头网页内容采集器 
C#+.Net编写的内容采集器,它的一个重要特点是不将采集来的内容保存到数据库,而是使用自定的POST提交的别的网页,如内容管理系统的新建内容页。免费。 BeeCollector (小蜜蜂采集器) 
PHP+MySQL编写的内容采集器。 风讯内容管理系统 
这个强大的内容管理系统内带有一个ASP的网页内容采集器+查看评论 (0)+发表评论+Trackback地址+Trackbacks (0)2006-8-9正则表达式在网络编程中的运用
分类:Ajax时间:2006-8-9 14:07:47作者:janyin导读: 
正则表达式在网络编程中的运用

[前言:]在我们编写WEB程序时,经常会判断一个字符串的有效性,如;一个串是否是数字、是否是有效的Email地址等等。如果不使用正则表达式,那么判断的程序会很长,并且容易出错,如果使用正则表达式,这些判断就是一件很轻松的工作了。本文全面介绍正则表达式的慨念、格式。并以在PHP、ASP中的应用实例增加读者的感性认识。正则表达式的应用很广,需要大家在学习和实践中不断的总结。

正则表达式简介 
简单的说,正则表达式是一种可以用于模式匹配和替换的强有力的工具。在网络编程中应用广泛,如PHP脚本语言或是JavaScript、VBScript这样的客户端脚本语言都提供了对正则表达式的支持。由此可见,正则表达式已经超出了某种语言或某个系统的局限,成为人们广为接受的概念和功能。 

正则表达式可以让用户通过使用一系列的特殊字符构建匹配模式,然后把匹配模式与数据文件、程序输入以及WEB页面的表单输入等目标对象进行比较,根据比较对象中是否包含匹配模式,执行相应的程序。 

举例来说,正则表达式的一个最为普遍的应用就是用于验证用户在线输入的邮件地址的格式是否正确,如果通过正则表达式验证用户邮件地址的格式正确,用户所填写的表单信息将会被正常处理;反之,如果用户输入的邮件地址与正则表达的模式不匹配,将会弹出提示信息,要求用户重新输入正确的邮件地址。由此可见正则表达式在WEB应用的逻辑判断中具有举足轻重的作用。在后面我们会举例详细介绍。 

正则表达式形式一般如:/love/,其中位于"/"定界符之间的部分就是将要在目标对象中进行匹配的模式。用户只要把希望查找匹配对象的模式内容放入"/"定界符之间即可。为了能够使用户更加灵活的定制模式内容,正则表达式提供了专门的"元字符"。所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。较为常用的元字符包括: "+,"*,?以及{}",或者"\s,\S,\d,\w和\W"等等。为了能够方便用户更加灵活的设定匹配模式,正则表达式允许使用者在匹配模式中利用[]界定匹配于某一个范围的字符而不局限于具体的字符。 

除了我们以上的元字符之外,正则表达式中还具有另外一种较为独特的专用字符,即定位符。定位符用于规定匹配模式在目标对象中的出现位置。较为常用的定位符包括: "^", "$", "\b" 以及 "\B"。 

如果我们希望在正则表达式中实现类似编程逻辑中的"或"运算,在多个不同的模式中任选一个进行匹配的话,可以使用管道符 "|"。例如: 正则表达式中还有一个较为常用的运算符,即否定符 "[^]"。与我们前文所提到的定位符 "^" 不同,否定符 "[^]"规定目标对象中不能存在模式中所规定的字符串。一般来说,当"^"出现在 "[]"内时就被视做否定运算符;而当"^"位于"[]"之外,或没有"[]"时,则应当被视做定位符。 

最后,当用户需要在正则表达式的模式中加入元字符,并查找其匹配对象时,可以使用转义符"\"。例如:/Th\*/,该正则表达式将会与目标对象中的"Th*"而非"The

相关内容

-六神源码网