ajax网站采集实例2
本帖最后由 zhouchanglin 于 2011-2-26 13:53 编辑这个网站http://www.centaline-cis.com/ccom/cpropsrch.aspx,是个典型的ajax请求的网站,也有些特别的地方,它请求的是get的
首先,这个网站要点搜索按钮,才会显示数据,而点击这个按钮,发生了ajax请求和一个post请求,而这个post请求只是为了得到数据的总量,对请求的数据是无用的,真正返回数据的是get的请求
这样了解点击搜索按钮,触发了什么函数就是关键了,搜索按钮的代码<input type="button" onclick="javascript:btnSearchClick()" id="btnSearch" value="搜尋"style="width:60px" width="60px"> ,可以了解到触发了btnSearchClick()函数,function btnSearchClick()
{
document.getElementById("getPagePanel").innerHTML= ""; //clear all parameter
document.getElementById("getResult").innerHTML="";
var curPageNo = document.getElementById('curPageNo');
var curPageSize = document.getElementById('curPageSize');
var curAreaL = document.getElementById('curAreaL');
var curAreaH = document.getElementById('curAreaH');
var curLumpPriceL = document.getElementById('curLumpPriceL');
var curLumpPriceH = document.getElementById('curLumpPriceH');
var curAvgPriceL = document.getElementById('curAvgPriceL');
var curAvgPriceH = document.getElementById('curAvgPriceH');
var curLumpRentL = document.getElementById('curLumpRentL');
var curLumpRentH = document.getElementById('curLumpRentH');
var curAvgRentL = document.getElementById('curAvgRentL');
var curAvgRentH = document.getElementById('curAvgRentH');
var curPropType = document.getElementById('curPropType');
var curStatus = document.getElementById('curStatus');
var curLumpSumOrAvg = document.getElementById('curLumpSumOrAvg');
var curDeco = document.getElementById('curDeco');
var curView = document.getElementById('curView');
var curFloor = document.getElementById('curFloor');
var curShopType = document.getElementById('curShopType');
var curBusiness = document.getElementById('curBusiness');
curPageNo.value = '1';
curPageSize.value = '10';
curAreaL.value = document.getElementById('PropSrch_txtAreaL').value;
curAreaH.value = document.getElementById('PropSrch_txtAreaH').value;
curLumpPriceL.value = document.getElementById('PropSrch_txtLumpPriceL').value;
curLumpPriceH.value = document.getElementById('PropSrch_txtLumpPriceH').value;
curAvgPriceL.value = document.getElementById('PropSrch_txtAvgPriceL').value;
curAvgPriceH.value = document.getElementById('PropSrch_txtAvgPriceH').value;
curLumpRentL.value = document.getElementById('PropSrch_txtLumpRentL').value;
curLumpRentH.value = document.getElementById('PropSrch_txtLumpRentH').value;
curAvgRentL.value = document.getElementById('PropSrch_txtAvgRentL').value;
curAvgRentH.value = document.getElementById('PropSrch_txtAvgRentH').value;
curPropType.value = document.getElementById('PropSrch_ddlPropType').value;
curLumpSumOrAvg.value = document.getElementById('PropSrch_ddlLumpSumOrAvg').value;
curDeco.value = document.getElementById('PropSrch_ddlDeco').value;
curView.value = document.getElementById('PropSrch_ddlView').value;
curFloor.value = document.getElementById('PropSrch_ddlFloor').value;
curShopType.value = document.getElementById('PropSrch_ddlShopType').value;
curBusiness.value = document.getElementById('PropSrch_ddlBusiness').value;
curStatus.value = changeSta();
getPropList('true',orderPrev);
}这个函数大概的意思是把隐藏的表单项的值在请求前,设置成对应的输入框,下拉框等当前用户设置的值,然后ajax请求,也就是getPropList('true',orderPrev)函数的功能;
隐藏的表单项:<input type="hidden" value="" name="PropSrch:cusDistrict" />
<input type=hidden id="curPageNo" value=1>---------当前第几页
<input type=hidden id="curPageSize" value=20>--------每页数量
<input type=hidden id="curAreaL">-----------面積范围左
<input type=hidden id="curAreaH">--------面積范围右
<input type=hidden id="curLumpPriceL">---------售價范围左
<input type=hidden id="curLumpPriceH">-------售價范围右
<input type=hidden id="curAvgPriceL">---------每平方呎售價范围左
<input type=hidden id="curAvgPriceH">-------每平方呎售價范围右
<input type=hidden id="curLumpRentL">------------租金范围左
<input type=hidden id="curLumpRentH">---------租金范围右
<input type=hidden id="curAvgRentL">-------每平方呎租金范围左
<input type=hidden id="curAvgRentH">--------每平方呎租金范围右
<input type=hidden id="curPropType">-----------類別<option value="ALL">全部</option>
<option selected="selected" value="Comm">寫字樓物業</option><option value="Ind">工商物業</option>
<option value="Ret">商舖物業</option>
<input type=hidden id="curStatus">------租/售
<input type=hidden id="curLumpSumOrAvg">-----<select name="PropSrch:ddlLumpSumOrAvg" id="PropSrch_ddlLumpSumOrAvg" onchange="javascript:changeStatus();" style="width:85px;width:85px">
<option selected="selected" value="LumpSum">總數</option><option value="Average">呎價</option>
<input type=hidden id="curDeco">----------裝修
<input type=hidden id="curView">---------景觀
<input type=hidden id="curFloor">----------樓層
<input type=hidden id="curShopType">----------商舖類別
<input type=hidden id="curBusiness">---------行業
当搜索时这些隐藏的表单项的值会根据当前的搜索条件,从新设置,然后ajax.这就还要看getPropList('true',orderPrev)函数的源码;
这是
var lang = 'zh-tw';
var orderPrev = 'default';
function getPropList(init,orderBy)
{
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
{
alert ("Your browser does not support AJAX!");
return;
}
var url;
url ='/getPropList.aspx?';
url += 'init=' + init;//ture getPropList('true',orderPrev);
url += '&pn=' + getPn();//curPageNo当前页
url += '&ps=' + getPs();//curPageSize每页数量
url += '&pt=' + getPt();//curPropTypePropSrch_ddlPropType-----------物業類別:<br />
url += '&al=' + getAl();//PropSrch_txtAreaL--------------<br />面積(平方呎)
url += '&ah=' + getAh();------------//至PropSrch_txtAreaH
url += '&lpl=' + getLpl();//PropSrch_txtLumpPriceL----------------<br />售價(百萬元):
url += '&lph=' + getLph();//至PropSrch_txtLumpPriceH
url += '&lrl=' + getLrl();//PropSrch_txtLumpRentL----------------------------租金(元)
url += '&lrh=' + getLrh();//PropSrch_txtLumpRenth
url += '&apl=' + getApl();//PropSrch_txtAvgPriceL----------->每平方呎售價(元)
url += '&aph=' + getAph();//至PropSrch_txtAvgPriceh
url += '&arl=' + getArl();//PropSrch_txtAvgRentL----------->每平方呎租金(元)
url += '&arh=' + getArh();//至PropSrch_txtAvgRenth
url += '&sta=' + getSta();//PropSrch_ddlStatus----------------租/售:<br />
url += '&la=' + getLa();/*<select name="PropSrch:ddlLumpSumOrAvg" id="PropSrch_ddlLumpSumOrAvg" onchange="javascript:changeStatus();" style="width:85px;width:85px">
<option selected="selected" value="LumpSum">總數</option>
<option value="Average">呎價</option>*/
url += '&dc=' + getDc();//裝修:<br />---------------PropSrch_ddlDeco
url += '&vw=' + getVw();//景觀:<br />
<select name="PropSrch:ddlView" id="PropSrch_ddlView" style="width:130px;width:130px">
url += '&fr=' + getFr();//樓層<select name="PropSrch:ddlFloor" id="PropSrch_ddlFloor" style="width:130px;width:130px">
<option selected="selected" value="ALL">全部</option>
<option value="H">高層</option>
url += '&spt=' + getSpt();//商舖類別:<br />
<select name="PropSrch:ddlShopType" id="PropSrch_ddlShopType"
url += '&bs=' + getBs();//行業PropSrch_ddlBusiness
url += '&dist=' + getDist();//PropSrch_llbDistrict------地區(
url += '&sc=' + lang;//var lang = 'zh-tw';
if(orderBy != 'default')
{
url+= '&ord=' + orderBy;//
orderPrev = orderBy;//
}
else
{
url+= '&ord=default';//default
}
//alert(url);
try {
xmlHttp.onreadystatechange=function(){stateChanged(init)};
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
catch (e)
{
alert(e);}
}里面我加了注视,getPn()等函数在源码里都可以找到,它们的功能都是返回相应的表单的隐藏项的值,而组合成带参数的请求地址,
而里面的xmlHttp.onreadystatechange=function(){stateChanged(init)};
xmlHttp.open("GET",url,true);
xmlHttp.send(null)则是发生ajax的函数,这里知道了xmlHttp.open("GET",url,true);,几已经知道了请求的地址是URL,这样地址是http://www.centaline-cis.com/getPropList.aspx?init=ture&pn=1&ps=10&pt=Comm&al=&ah=&lpl=&lph=&lrl=&lrh=&apl=&aph=&arl=&arh=&sta=ALL&la=LumpSum&dc=ALL&vw=ALL&fr=ALL&spt=ALL&bs=ALL&dist=ALL&sc=zh-tw&ord=default 而这个stateChanged(init)函数是具体的把返回的数据进行设置,所以到这搜索提交这步已经结束了,还有这个地址在浏览器打开查看源码,可能没有想要的数据,不清楚是为什么,用火车测试是有数据返回的
而还有个问题每页解决,那就是翻页
而这就要看页脚部分的源码了,而这个网站页脚部分也是用xmlHttp.onreadystatechange=function(){stateChanged(init)},输出的,这样就有必要了解stateChanged(init)了,function stateChanged(init)
{
if (xmlHttp.readyState==4)
{
if(init == 'true')
{
var intRecordCount = PropSrch.getRecordCount(getPt(), getSta(), getAl(), getAh(), getLpl(), getLph(), getApl(), getAph(), getLrl(), getLrh(), getArl(), getArh(), getLa(), getDc(), getVw(), getFr(), getSpt(), getBs(), getDist(), lang);
document.getElementById("getPagePanel").innerHTML= "<table cellSpacing='0' cellPadding='0' width='974' border='0' align='center'><tr><td align='left' valign='middle' style='padding-top:5px;padding-bottom:5px;padding-left:5px' width='619'>在全港 <font color='#A50743'><b>11667</b></font> 個精選樓盤中,有 <font color='#A50743'><b><label id='lblRecordCount'></label></b></font> 個符合閣下要求,現詳列如下 :</font></td><td align='left' valign='middle' width='175'>每頁顯示<select id=ddlPageSize onchange=javascript:changePage(this.id)><option value=5>5</option><option value=10 selected=true>10</option><option value=15>15</option><option value=20>20</option></select>個樓盤紀錄</td><td align='right' valign='middle' width='170' style='padding-right:5px'><a href='#' id='linkPrevPage' onclick=javascript:changePage(this.id)>上一頁</a><select id=ddlPageNo onchange=javascript:changePage(this.id)></asp :dropdownlist></select><a href='#' id='linkNextPage' onclick=javascript:changePage(this.id)>下一頁</a></td></tr></table>";
document.getElementById("lblRecordCount").innerHTML = intRecordCount.value;
getDdlPage(intRecordCount.value);
document.getElementById("getResult").innerHTML=xmlHttp.responseText;
}
else
{
document.getElementById("getResult").innerHTML=xmlHttp.responseText;
}
}
else
{
document.getElementById("getResult").innerHTML='<img src="/1024/images/img_running.gif" />';
}
}其中<select id=ddlPageNo onchange=javascript:changePage(this.id)></asp :dropdownlist></select>是下拉框翻页的源码;
这个下拉框在getDdlPage(intRecordCount.value);执行后就被设置好了function getDdlPage(intRecordCount)
{
var curPageSize = document.getElementById('curPageSize');
var ddlPageSize = document.getElementById('ddlPageSize');
var ddlPageNo = document.getElementById('ddlPageNo');
for(j=ddlPageNo.length;j>=0;j--)
{
ddlPageNo.remove(j);
}
for(var i=1;i<=Math.ceil(intRecordCount/curPageSize.value);i++)
{
ddlPageNo.options.add(new Option(i,i));
}
}可以知道路过通过下拉框翻页触发了changePage(this.id),function changePage(controlName)
{
var curPageNo = document.getElementById('curPageNo');
var curPageSize = document.getElementById('curPageSize');
var ddlPageNo = document.getElementById('ddlPageNo')
var ddlPageSize = document.getElementById('ddlPageSize');
var linkPrevPage = document.getElementById('linkPrevPage');
var linkNextPage = document.getElementById('linkNextPage');
if(controlName == 'ddlPageSize')
{
curPageSize.value = ddlPageSize.value;
getDdlPage(document.getElementById("lblRecordCount").innerHTML);
getPropList('false',orderPrev);
}
else if(controlName == 'ddlPageNo')
{
curPageNo.value = ddlPageNo.value;
getPropList('false',orderPrev);
}
else if(controlName == 'linkPrevPage')
{
if(parseInt(ddlPageNo.value,10) - 1 > 0)
{
ddlPageNo.value = parseInt(ddlPageNo.value,10) - 1;
curPageNo.value = parseInt(curPageNo.value,10) - 1;
getPropList('false',orderPrev);
}
}
else if(controlName == 'linkNextPage')
{
if(parseInt(ddlPageNo.value,10) + 1 <= ddlPageNo.length)
{
ddlPageNo.value = parseInt(ddlPageNo.value,10) + 1;
curPageNo.value = parseInt(curPageNo.value,10) + 1;
getPropList('false',orderPrev);
}
}
}这个函数包含了点上一页,下一页和下拉框翻页的处理过程,都查补多,下拉框翻页id=ddlPageNo,只看else if(controlName == 'ddlPageNo')
{
curPageNo.value = ddlPageNo.value;
getPropList('false',orderPrev);
}即可,可以了解到时把选择的页数的值给隐藏项curPageNo,然后getPropList发生,也就是前面点搜索时会发生的ajax请求的函数,不同的是这次传递的第一个参数是false,点搜索时是ture,两次不同的地方通过stateChanged(init) 的条件if (xmlHttp.readyState==4)
{
if(init == 'true')可以知道翻页的时候页脚不会被更新,只更新数据,而点搜索时则更新了页脚
这样curPageNo参数的值就代表页数,那么写成http://www.centaline-cis.com/getPropList.aspx?init=false&pn=分页ps=10&pt=Comm&al=&ah=&lpl=&lph=&lrl=&lrh=&apl=&aph=&arl=&arh=&sta=ALL&la=LumpSum&dc=ALL&vw=ALL&fr=ALL&spt=ALL&bs=ALL&dist=ALL&sc=zh-tw&ord=default,就可以访问分页了
ajax地址后每个参数的意思:
pn---------页码
ps-------每页数量
pt-------物業類別
al------面積范围左
ah-------面積范围右
lpl------售價范围左
lph---------售價范围右
lrl-----租金范围左
lrh--------租金范围右
apl----每平方呎售價范围左
aph=&arl=&arh=&sta=ALL&la=LumpSum&dc=ALL&vw=ALL&fr=ALL&spt=ALL&bs=ALL&dist=ALL&sc=zh-tw&ord=defaul
aph-------每平方呎售價范围右
sta--------租/售
la-----------總數 尺寸
dc-----------裝修
vw------景觀
fr----樓層
spt---------商舖類別
bs-----行業
dist-----地區
sc--------url += '&sc=' + lang; //var lang = 'zh-tw';
ord----排序把
想要其他的搜索,改下相应的参数就可以了
而抓包的那个post其实是请求数据的总量,与真正获取数据无关
这个网站分页即是内容页,而这样的往往不好做,因为表格里的每条数据要循环采集,这样路过源码格式不规范,将很难做,还在这个网站还算规范,用循环采到了每条的记录
规则 回复 1# zhouchanglin
多谢楼主帮忙和分享,谢谢。 {:4_180:}{:4_180:}{:4_180:}{:4_180:} 除了狂顶,还要学习中{:4_180:} 支持,这也可以啊,还没用过 感谢楼主。,很不错 谢谢了 顶!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 这个教程很详细,感谢楼主!
页:
[1]