puppeteer嘗試-爬鏈家

const puppeteer = require('puppeteer');

(async () => {
  const browser = await (puppeteer.launch({
    //設置超時時間
    timeout: 15000,
    //若是是訪問https頁面 此屬性會忽略https錯誤
    ignoreHTTPSErrors: true,
    // 打開開發者工具, 當此值爲true時, headless總爲false
    devtools: false,
    // 關閉headless模式, true不會打開瀏覽器 false會打開瀏覽器
    headless: true
  }));
  const page = await browser.newPage();



  await page.goto('https://xm.lianjia.com/ershoufang/pg1/');
  /*最大頁數*/
  let max = 10;
  /*爬數據*/
  let all_result = [];


  console.log('開始');
  console.time('計時');
  /*獲取一頁信息*/
  const result = await page.evaluate(max => {
    let data = []; 
    let _max = max||$('.house-lst-page-box a:nth-last-child(2)').html(); //獲取最大頁數
    let elements = document.querySelectorAll('.sellListContent li'); //獲取全部的li
    for (var element of elements){ // 循環 
      let title = element.querySelector('.title a').innerHTML; 
      //抓取連接(href)屬性 
      let url = element.querySelector('.noresultRecommend').href;
      let xiaoqu = element.querySelector('.houseInfo a').innerHTML;
      data.push({title,url,xiaoqu});
    }


    return {
      data:data,
      max:_max
    };
  },max);
  max = result.max;
  console.log('最大頁數:'+max);
  console.log(result.data);
  console.log('當前頁:1');

  all_result = all_result.concat(result.data);

  for (var i = 2; i <= max; i++) {
    await page.goto('https://xm.lianjia.com/ershoufang/pg'+i+'/');
    const result = await page.evaluate(() => {
      let data = []; 
      let elements = document.querySelectorAll('.sellListContent li'); //獲取全部的li
      for (var element of elements){ // 循環 
        let title = element.querySelector('.title a').innerHTML; 
        //抓取連接(href)屬性 
        let url = element.querySelector('.noresultRecommend').href;
        let xiaoqu = element.querySelector('.houseInfo a').innerHTML;
        data.push({title,url,xiaoqu});
      }
      return {
        data:data,
      };
    });
    console.log(result.data);
    console.log('當前頁:'+i);
    all_result = all_result.concat(result.data);
  }
  console.timeEnd('計時');


  console.time('處理數據時間');
  console.log('處理數據開始');
  let xiaoqu_count_array = [];
  xiaoqu_count_array = dealData(all_result);



  /*處理數據*/
  function dealData(all_result) {
    let xiaoqu_count = {};
    let xiaoqu_count_array = [];
    /*聚合*/
    for (var i = all_result.length - 1; i >= 0; i--) {
      var itme = all_result[i];
      var _xiaoqu = itme.xiaoqu.replace(' ','');
      xiaoqu_count[_xiaoqu] = xiaoqu_count[_xiaoqu]||0;
      xiaoqu_count[_xiaoqu]++;
    }
    /*變成數組*/
    for (x in xiaoqu_count){
      xiaoqu_count_array.push({'name':x,'count':xiaoqu_count[x]});
    }

    return xiaoqu_count_array;
  }
  /*排序輸出*/
  function compare(propertyName) {
    return function(object1, object2) {
      var value1 = object1[propertyName];
      var value2 = object2[propertyName];
      if (value2 < value1) {
        return 1;
      } else if (value2 > value1) {
        return -1;
      } else {
        return 0;
      }
    }
  }
  xiaoqu_count_array.sort(compare("count"));
  console.log('xiaoqu_count_array_new');
  console.log(xiaoqu_count_array[xiaoqu_count_array.length-1]);

  console.log('處理數據結束');
  console.timeEnd('處理數據時間');

})();

/*page.setViewport*/
/*設置視窗*/
/*viewport <Object>
    width <number> 寬度,單位是像素
    height <number> 高度,單位是像素
    deviceScaleFactor <number> 定義設備縮放, (相似於 dpr)。 默認 1。
    isMobile <boolean> 要不要包含meta viewport 標籤。 默認 false。
    hasTouch<boolean> 指定終端是否支持觸摸。 默認 false
    isLandscape <boolean> 指定終端是否是 landscape 模式。 默認 false。
返回: <Promise>*/


/*page.goto*/
/*到指定頁面*/
/*url <string> 導航到的地址. 地址應該帶有http協議, 好比 https://.
  options <Object> 導航配置,可選值:
    timeout <number> 跳轉等待時間,單位是毫秒, 默認是30秒, 傳 0 表示無限等待。能夠經過page.setDefaultNavigationTimeout(timeout)方法修改默認值
    waitUntil <string|Array<string>> 知足什麼條件認爲頁面跳轉完成,默認是 load 事件觸發時。指定事件數組,那麼全部事件觸發後才認爲是跳轉完成。事件包括:
      load - 頁面的load事件觸發時
      domcontentloaded - 頁面的 DOMContentLoaded 事件觸發時
      networkidle0 - 再也不有網絡鏈接時觸發(至少500毫秒後)
      networkidle2 - 只有2個網絡鏈接時觸發(至少500毫秒後)
    referer <string> Referer header value. If provided it will take preference over the referer header value set by page.setExtraHTTPHeaders().
返回: <Promise<?Response>> Promise對象resolve後是主要的請求的響應。若是有多個跳轉, resolve後是最後一次跳轉的響應*/

/*page.screenshot*/
/*截屏*/
/*options <Object> 可選配置:
  path <string> 截圖保存路徑。截圖圖片類型將從文件擴展名推斷出來。若是是相對路徑,則從當前路徑解析。若是沒有指定路徑,圖片將不會保存到硬盤。
  type <string> 指定截圖類型, 能夠是 jpeg 或者 png。默認 'png'.
  quality <number> 圖片質量, 可選值 0-100. png 類型不適用。
  fullPage <boolean> 若是設置爲true,則對完整的頁面(須要滾動的部分也包含在內)。默認是false
  clip <Object> 指定裁剪區域。須要配置:
    x <number> 裁剪區域相對於左上角(0, 0)的x座標
    y <number> 裁剪區域相對於左上角(0, 0)的y座標
    width <number> 裁剪的寬度
    height <number> 裁剪的高度
  omitBackground <boolean> 隱藏默認的白色背景,背景透明。默認不透明
  encoding <string> 圖像的編碼能夠是 base64 或 binary。 默認爲「二進制」。
返回: <Promise<[Buffer|String]>> Promise對象,resolve後是截圖的buffer
*/
/*  await page.screenshot({
    path: '4399.png',
    type: 'png',
    // quality: 100, 只對jpg有效
    fullPage: true,
    // 指定區域截圖,clip和fullPage二者只能設置一個
    // clip: {
    //   x: 0,
    //   y: 0,
    //   width: 1000,
    //   height: 40
    // }
  });*/

/*page.waitFor*/
/*頁面等待,能夠是時間、某個元素、某個函數*/
/*此方法根據第一個參數的不一樣有不一樣的結果:
若是 selectorOrFunctionOrTimeout 是 string, 
那麼認爲是 css 選擇器或者一個xpath, 根據是否是'//'開頭, 這時候此方法是 page.waitForSelector 或 page.waitForXPath的簡寫
若是 selectorOrFunctionOrTimeout 是 function, 
那麼認爲是一個predicate,這時候此方法是page.waitForFunction()的簡寫
若是 selectorOrFunctionOrTimeout 是 number, 
那麼認爲是超時時間,單位是毫秒,返回的是Promise對象,在指定時間後resolve
不然會報錯*/

主要用到了page的幾個方法javascript

後續數據簡單處理了下,獲得房源最多的小區。css

相關文章
相關標籤/搜索