zhouchanglin 发表于 2010-12-19 14:00:09

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'>在全港&nbsp;<font color='#A50743'><b>11667</b></font>&nbsp;個精選樓盤中,有&nbsp;<font color='#A50743'><b><label id='lblRecordCount'></label></b></font>&nbsp;個符合閣下要求,現詳列如下 :</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其实是请求数据的总量,与真正获取数据无关

这个网站分页即是内容页,而这样的往往不好做,因为表格里的每条数据要循环采集,这样路过源码格式不规范,将很难做,还在这个网站还算规范,用循环采到了每条的记录

规则

caizhiguang 发表于 2010-12-19 14:12:28

回复 1# zhouchanglin
多谢楼主帮忙和分享,谢谢。

shgaoli 发表于 2010-12-22 01:24:52

{:4_180:}{:4_180:}{:4_180:}{:4_180:}

okok7845 发表于 2010-12-22 05:53:48

除了狂顶,还要学习中{:4_180:}

zk1062 发表于 2011-1-19 11:14:09

支持,这也可以啊,还没用过

di44 发表于 2011-2-22 15:51:30

感谢楼主。,很不错 谢谢了

415439444 发表于 2011-3-27 13:25:52

顶!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

infoseek 发表于 2012-8-10 21:37:45

这个教程很详细,感谢楼主!
页: [1]
查看完整版本: ajax网站采集实例2