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