起源
最近被前同事问是否可以帮他去爬取一个网站的数据,然后他把网站发给我了,之后我就去研究了下,
本来计划用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
- 本文将以爬取一手房预售房源数据为例
页面分析
- 一手房预售信息页面信息首页数据从哪里来?
- 页面执行逻辑
- 页面渲染逻辑
思路
- 思路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 变成字符串,哈哈,感觉不好把,有点业余
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。