起源

最近被前同事问是否可以帮他去爬取一个网站的数据,然后他把网站发给我了,之后我就去研究了下,

本来计划用spider-flow 这个东西来爬的,毕竟能不写代码的,为啥我要去写代码,然后研究了下spider-flow 发现满足不了需求,浪费了两天时间,
😄😄😄, 还是老老实实手写把,对spider-flow 感兴趣的可以看看我写的:https://www.mubucm.com/doc/7rBgfYhSzrt

最终效果

图片

作者在写这篇文章的技能和环境

  • 前端略懂一二
  • nodejs 一窍不通
  • 数据库一窍不通
  • window系统
  • puppeteer 版本: 19.7.4
  • node版本: 14.18.0

本文只适合小白阅读,大佬请出门左转~

页面地址

图片

页面分析

  • 一手房预售信息页面信息首页数据从哪里来?

图片

  • 页面执行逻辑

图片

  • 页面渲染逻辑

图片

图片

图片

思路

  • 思路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 官网下载对应的版本

    1. 查看puppeter和chromium的对应关系,找到对应关系 然后在chromium的下载链接后面自己换一下,然后下载https://github.com/chromium/chromium/releases/tag/111.0.5556.0
      图片
      -等了两个小时,发现这个文件是不对的,700m,家里面那个电脑也就是170m。这个思路也是错的
      图片

方法3:chrome与puppeteer版本发生冲突在gitee上找了另一个思路

图片

方法4:puppeteer install Chromium r1095492 error换了个思路,然后进了这个网站

图片

终极原因

我就一直好奇这个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

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',  });

想看源码的可以瞅瞅

源码

免责声明

  • 本项目只是学习使用,无意对此网站进行爬虫等操作

参考资料

// launch.json 配置 
{
  "name": "nodejs-debugger",
  "program": "${workspaceFolder}/index.js",
  "request": "launch",
  "skipFiles": [
      "<node_internals>/**"
  ],
  "type": "node"
},
  • 数据库相关date空字符串处理问题原因,爬了一千多条数据,然后挂了,说插入数据库错误。。。
    图片
    问了下大哥们,好像不行,只能传入date 和null,或者是说把date 变成字符串,哈哈,感觉不好把,有点业余

qinyuanqiblog
20 声望3 粉丝

擅长摸鱼~


引用和评论

0 条评论