用xmlhttp编写web采集程序

晰带语法着色的版本:http://gwx.showus.net/blog/article.asp?id=229

原创很辛苦,转载请注明原文链接:http://gwx.showus.net/blog/article.asp?id=229

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("<div style='color:#003399; border: solid 1px #003399; background: #EEF7FF; margin: 1px; font-size: 12px; padding: 4px;'>")

    Response.Write(Str &"</div>")

    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("<font color=red>myHttpGet:</font>"+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函数不能正确处理形如<img src="upload/abc.jpg" />和<a href="/upload/abc.gif" ...的内容,要处理这些相对链接,我们可以先用下面的函数把网页中的相对链接都转换成绝对链接

'函数: 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

        '<img src="a.jpg">,<img src="f/a.jpg">,<img src="/ff/a.jpg">

        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()&" <font color=blue>Sleep For "&iSeconds&" Seconds</font>"

    Dim t:t=Timer()

    While(Timer()<t+iSeconds)

        'Do Nothing

    Wend

    D Timer()&" <font color=blue>Sleep For "&iSeconds&" Seconds OK</font>"

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的网页内容采集器

时间: 2024-10-28 23:32:55

用xmlhttp编写web采集程序的相关文章

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

晰带语法着色的版本:http://gwx.showus.net/blog/article.asp?id=229 原创很辛苦,转载请注明原文链接:http://gwx.showus.net/blog/article.asp?id=229 web采集程序?网页抓取程序?小倫程序?不管怎么叫,这种程序应用倒是蛮广的.本文不讨论这种使用这种程序引起的版权或道德问题,只谈这种程序在ASP+VBScript环境下的实现 :-) 预备知识:除了一般的ASP+VBScript的知识外,你还需要了解xmlhttp

使用VBScript和JScript编写WEB应用程序(一) 拙作一片,凑或者看吧:-(

js|jscript|vbscript|web|程序 使用VBScript和JScript编写WEB应用程序 我心飞扬 写这篇文章的动机是看到了大家对VBScript和Javascript的讨论以及另一片类似的文章,觉得有必要将大家的想法加以整理:-),并将我在工作中产生的一些心得拿出来和大家分享,希望对大家有所帮助.当然,水平有限,错误在所难免. Active Server Pages是Microsoft Windows DNA的重要组成部分,使用ASP我们可以很容易的构造功能强大的基于Web

使用VBScript和JScript编写WEB应用程序(二)

js|jscript|vbscript|web|程序 使用VBScript和JScript编写WEB应用程序(二) 我心飞扬 6.数据类型VBScript和JScript的数据类型差别比较大,JScript有6种数据类型:数值型.字符串型.对象型.布尔型.null和undefined.VBScript虽然只有一种数据类型Variant,但其子类型比较丰富.特别是其对数值类型的精细划分使得在进行精确的数值运算时显得比较放心.且配合第2条中所讲到的格式化功能使数据处理更加得心应手.有关这方面的文档请

使用VBScript和JScript编写WEB应用程序(三)

js|jscript|vbscript|web|程序 使用VBScript和JScript编写WEB应用程序(三) 3.区分大小写以及命名习惯 JScript是严格区别大小写的:在每个JScript的关键字,每个JScript命名空间的所有部分中,你可以把大写和小写字母恰当的结合起来使用.这其中包括了你使用的对象模型中所有的关键字.例如,当你使用ASP Response对象时,必须正确地使用大小写字母(如Response.Write),否则JScript会坚决不予承认.同样,如果你为DHTML

用ASP+XMLHTTP编写一个天气预报程序

asp+|xml|程序|天气预报|xml     本人就职于一个本地门户网站,每天网站上的天气都得更新.久而久之感到相当麻烦,于是写了一个定时的新闻小偷,帖出来大家参考一下系统要求: 支持FSO, 服务器UDP TCP/IP 没有屏蔽. 下面是小偷的内容:FileName TianQi.aspWrite By Niaoked QQ408611119www.knowsky.com<% if hour(now)=9 and minute(now)<30 then getCategories() e

编写高性能 Web 应用程序的10个技巧

web|程序|技巧|性能|技巧|性能 本文讨论:常见的 ASP.NET 性能神话 有用的 ASP.NET 性能技巧和诀窍 在 ASP.NET 中处理数据库的一些建议 缓冲以及用 ASP.NET 进行后台处理 本文使用下列技术:ASP.NET,.NET 框架,IIS 用 ASP.NET 编写 Web 应用程序其轻松程度令人难以置信.它是如此的容易,以至于许多开发人员不用花费多少时间来构筑其应用便能获得非常好的性能.在本文中,我将给出10个编写高性能 Web 应用的技巧.我的评论不仅仅局限与 ASP

编写高性能 Web 应用程序的10 个技巧

web|程序|技巧|性能|技巧|性能 技巧 作者:Rob Howard 本文讨论 • 常见 ASP.NET 性能难点 • 面向 ASP.NET 的有用性能提示和技巧 • 在 ASP.NET 中使用数据库的建议 • 使用 ASP.NET 进行缓存和后台处理 本文使用了以下技术:ASP.NET..NET Framework 和 IIS 本页内容 数据层性能 技巧 1 - 返回多个结果集 技巧 2 - 分页的数据访问 技巧 3 - 连接池 技巧 4 - ASP.NET 缓存 API 技巧 5 - 每请

编写高性能Web应用程序的10个入门技巧

web|程序|技巧|性能 使用 ASP.NET 编写 Web 应用程序的简单程度令人不敢相信.正因为如此简单,所以很多开发人员就不会花时间来设计其应用程序的结构,以获得更好的性能了.在本文中,我将讲述 10 个用于编写高性能 Web 应用程序的技巧.但是我并不会将这些建议仅局限于ASP.NET 应用程序,因为这些应用程序只是 Web 应用程序的一部分.本文不作为对 Web应用程序进行性能调整的权威性指南 - 一整本书恐怕都无法轻松讲清楚这个问题.请将本文视作一个很好的起点. 成为工作狂之前,我原

js-真心求教一个问题,关于编写web的外挂工具app或者桌面程序,具体请进,真心谢谢了

问题描述 真心求教一个问题,关于编写web的外挂工具app或者桌面程序,具体请进,真心谢谢了 我编写的过程中遇到一些疑惑不知道如何解决,所以特来真心求教,万望解惑,如果有描述不对或者很low,请谅解. 一个最具体的例子:像前两年12306抢票只能用网页来抢,没有app或者桌面程序,很多朋友都根据12306网站编写了外挂app或者桌面程序,避免老得打开个浏览器. 目前我也想做类似的事情,根据某个http的Web网站写个外挂app或者程序,作为一个程序员,我大致也知道大致的流程是:拼接url->发起