起源
最近被前同事問是否可以幫他去爬取一個網站的數據,然後他把網站發給我了,之後我就去研究了下,
本來計劃用spider-flow 這個東西來爬的,畢竟能不寫代碼的,為啥我要去寫代碼,然後研究了下spider-flow 發現滿足不了需求,浪費了兩天時間,
😄😄😄, 還是老老實實手寫把,對spider-flow 感興趣的可以看看我寫的:https://www.mubucm.com/doc/7rBgfYhSzrt
最終效果
作者在寫這篇文章的技能和環境
- 前端略懂一二
- nodejs 一竅不通
- 數據庫一竅不通
- window系統
- puppeteer 版本: 19.7.4
- node版本: 14.18.0
本文只適合小白閲讀,大佬請出門左轉~
頁面地址
- http://zjj.sz.gov.cn:8004/?__EVENTARGUMENT=3&ddlPageCount=20
- 本文將以爬取一手房預售房源數據為例
頁面分析
- 一手房預售信息頁面信息首頁數據從哪裏來?
- 頁面執行邏輯
- 頁面渲染邏輯
- 項目詳情頁跳轉邏輯:http://zjj.sz.gov.cn/ris/bol/szfdc/projectdetail.aspx?id=126809
- 證件詳情頁跳轉邏輯:http://zjj.sz.gov.cn/ris/bol/szfdc/certdetail.aspx?id=126809
思路
- 思路1:模擬用户操作,像一個正常的用户去點擊然後爬取數據,之後再把數據存儲到數據庫, 然後點擊分頁重複這個操作,直到爬取完所有數據
- 思路2:直接調用獲取數據接口,然後解析數據,之後再把數據存儲到數據庫我們先用思路1的方式來做,
- 本來我想用思路2的做法來做,後來有個問題沒解決,所以先按照思路1來實現
核心代碼講解
puppetter 如何改變頁面的值?
官網api
- 具體代碼,按照20條/頁去爬取
puppetter 如何觸發事件?
- api
- 實例:
page.click(#AspNetPager1 > span:nth-last-of-type(1), {delay: 100})
使用puppetter訪問頁面,如何去解析數據?
- 一開始我還一直被困在這個puppetter api,一直想在這個瀏覽器執行的時候去獲取這些信息,其實這種也是可以的,但是不方便,後來百度發現可以使用cheerio這個庫,像使用jquery把對頁面做操作
- cheerio 遍歷頁面數據
- cheerio 具體代碼
如何把保存數據到數據庫?新建一個house_info 數據庫,然後搞了一個presell 預售表,預售的表結構
sql相關知識查詢數據
- select * from presell
- 更新某一條數據:update presell set name='阿斯頓撒',enterprise=99 WHERE serial=2
- 更新所有的數據:UPDATE presell SET address='深圳'插入數據:INSERT INTO presell (mainKey,serial,id) VALUES (1111,2,3);
- 批量插入數據:INSERT INTO presell ( mainKey, serial, id, NAME, enterprise, address, date ) VALUES ( '10001', '2', '3', '4', '5', '6', '2022-02-06' ),( '10002', '2222', '3', '4', '5', '6', '2022-02-06' )
如何批量插入數據
var mysql = require('mysql2');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'root'
});
connection.query('use house_info')
const array = [
[
1679389969116,
'13',
'深房許字(2023)南山003號',
'http://zjj.sz.gov.cn/ris/bol/szfdc/certdetail.aspx?id=126737',
'方直瓏樾山花園',
'http://zjj.sz.gov.cn/ris/bol/szfdc/ojectdetail.aspx?id=126737',
'深圳市龍廷房地產開發有限公司',
'南山',
'2023-03-02'
],
[
1679389969118,
'13',
'深房許字(2023)南山003號',
'http://zjj.sz.gov.cn/ris/bol/szfdc/certdetail.aspx?id=126737',
'方直瓏樾山花園',
'http://zjj.sz.gov.cn/ris/bol/szfdc/ojectdetail.aspx?id=126737',
'深圳市龍廷房地產開發有限公司',
'南山',
'2023-03-02'
],
]
connection.query(`INSERT INTO presell ( mainKey, serial, idCard, idCardUrl, productName, productUrl, enterprise, location, authorizeDate )
VALUES ?`,[array], function (error, results, fields) {
if (error) {
log.error('批量插入失敗,錯誤信息==>', error)
throw error;
}
// connected!
log.info('批量插入成功', results)
});
開始編碼
- puppetter 環境搞了我兩天,裝了新版本,chrom一直沒有下載下來,😭😭😭,解決方法看後面
先訪問一次
因為第一組分頁的頁面結構和第二組的頁面結構不一樣,所以要搞成不同的邏輯不同的頁面結構,難搞哦
第一頁的時候的頁面結構和邏輯
第二組分頁的頁面機構和邏輯
開始第一輪的輪詢
開始第二輪的輪詢
存儲數據庫的邏輯
下載不了chromium的解決辦法
Failed to set up Chromium r1095492! Set "PUPPETEER_SKIP_DOWNLOAD" env variable to skip download
問題截圖 關鍵詞:Failed to set up Chromium r1095492! Set "PUPPETEER_SKIP_DOWNLOAD" env variable to skip download
這個錯誤信息的意思就是下載chromium 1095492版本失敗,不同的puppeteer 對應的配置不一樣,需要手動下載,然後配置好,就可以解決了,解決步驟 看先問終極解決方案那裏。
問題原因: 下面這張圖是我在家裏面直接更新就好了,一點問題都沒有,在公司電腦已更新就狗帶,太難了
解決辦法:(想直接看答案的,直接跳到終極原因 或者方法5處查看解決辦法)
方法1: 從puppeteer 源碼找到下載的資源
- 修煉不到家,找不到,😄😄😄,後來就放棄了
方法2:從chromium 官網下載對應的版本
-
- 查看puppeter和chromium的對應關係,找到對應關係 然後在chromium的下載鏈接後面自己換一下,然後下載https://github.com/chromium/chromium/releases/tag/111.0.5556.0
-等了兩個小時,發現這個文件是不對的,700m,家裏面那個電腦也就是170m。這個思路也是錯的
- 查看puppeter和chromium的對應關係,找到對應關係 然後在chromium的下載鏈接後面自己換一下,然後下載https://github.com/chromium/chromium/releases/tag/111.0.5556.0
方法3:chrome與puppeteer版本發生衝突在gitee上找了另一個思路
- 我當時找到了這個issue,但是沒有按照這個思路找下去,如果我直接去搜索這個關鍵詞,可能我就不用浪費半天時間了。哈哈谷歌搜索這個關鍵詞
- 看這裏,github地址: https://github.com/wadezhan/billfeller.github.io/issues/232,是個深圳的大佬,感謝~
方法4:puppeteer install Chromium r1095492 error換了個思路,然後進了這個網站
- 看了這個issue:https://github.com/puppeteer/puppeteer/issues/1597#issuecomment-351945645
- 2017年這個問題就存在了,只不過那時候大多數人用了淘寶鏡像可以解決,但是我在2023-03-13的時候用淘寶鏡像就發現沒有那個資源,應該是沒有同步過來
- cnpm 也有這個問題
- Download failed: server returned code 404. URL: https://npmmirror.com/mirrors//chromium-browser-snapshots/Win...
- chromium-browser-snapshots庫
終極原因
我就一直好奇這個Failed to set up Chromium r1095492! 裏面的r1095492是啥東西,後來得到答案才知道,原來是一個所謂的版本號。。。,我一直以為是chromium 的版本,思路錯了,他是一個chromium-browser-snapshots 裏面的版本號
https://commondatastorage.googleapis.com/chromium-browser-sna...
![]()
- 這個沒有梯子上不去:https://registry.npmmirror.com/binary.html?path=chromium-brow...
https://commondatastorage.googleapis.com/chromium-browser-sna...
-下載後的資源大概長這樣,兩天了,你知道我兩天怎麼過來的嗎!!!
- 直接把解壓後的文件丟上去是不行的,必須按照puppeter 的這種格式才行,解壓出來是chrome-win文件夾,
- 然後把拷貝的文件,丟到當前用户下的 .cache/puppeteer 下新建一個win64-1095492文件夾下就好了
- 搞定,下班!!!
- 最後,總結一下,其實自己好多次都已經觸碰到了答案,只是沒有注意到,😄😄,歷時兩天,終於搞定,感謝閲讀,謝謝~
方法5:使用本機的chrom
- 第一步:export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
- 第二步:npm i puppeteer
- 第三步:https://stackoverflow.com/questions/59786319/configure-puppeteer-executablepath-chrome-in-your-local-windows
await puppeteer.launch({ headless: false, args: ['--disable-infobars', '--no-sandbox', '--disable-setuid-sandbox'], // window 如果複製是下面的地址是不行的, executablePath: 'C:\Program Files\Google\Chrome\Application\chrome.exe', // window 要把 地址裏面的 \ 都變成 \ \ ,不然狗帶,忘記是啥原因了,反正就是沒有計算機體系知識不懂,哈哈,大概這種意思 executablePath: 'C:\Program Files\Google\Chrome\Application\chrome.exe', });
想看源碼的可以瞅瞅
源碼
免責聲明
- 本項目只是學習使用,無意對此網站進行爬蟲等操作
參考資料
- puppeteer如何觸發表單提交
- puppeteer如何執行頁面的js方法
- Puppeteer 基本概念介紹
- puppeteer環境部署問題小記
- vscode 如何調試node
// launch.json 配置
{
"name": "nodejs-debugger",
"program": "${workspaceFolder}/index.js",
"request": "launch",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
},
- 數據庫相關date空字符串處理問題原因,爬了一千多條數據,然後掛了,説插入數據庫錯誤。。。
問了下大哥們,好像不行,只能傳入date 和null,或者是説把date 變成字符串,哈哈,感覺不好把,有點業餘