赞
踩
需求:获取某一个网站,商品的名称+价格;
以下按京东商品列表URL进行测试,
1、搭建node环境,此node安装不多介绍
2、node爬虫工具,安装 npm install crawler
3、创建index.js,直接贴代码
- /**
- * 此js主要是通过PATH_URL,根据源码中的html风格,根据特定的标签获取HTML中的href,写入JSON文件中
- */
- const fs = require('fs');
- const Crawler = require('crawler');
- const _ = require('lodash')
-
- //在爬相关图片信息时,需要得到指定的URL:https://search.jd.com,
- const PATH_URL = 'https://search.jd.com/Search?keyword=%E5%8D%8E%E4%B8%BA%E6%89%8B%E6%9C%BA&enc=utf-8&suggest=5.def.0.base&wq=huawie%E6%89%8B%E6%9C%BA&pvid=b314d64bbf02446187feba4eed246377';
-
- // 为了console输出而定义的变量
- let cnt = 0;
- // 查找到的HTML地址
- let listDataRes = []
-
- // 爬虫抓取
- const c = new Crawler({
- maxConnections: 10,
- retries: 3, // 失败重连3次
- callback: function (error, res, done) {
- if (error) {
- console.log(error)
- } else {
- // 注:抓取图片的规则,需要自己定义
- const $ = res.$;
- console.log(' ------------>title: ', $('title').text())
- const dataList = $('.goods-list-v2 li');
-
- dataList.each((index, dataItem) => {
- let dataRes = {};
- const idKey = dataItem.attribs['data-sku']
-
- // 获取li标签下的标签集合
- const firstChildren = dataItem.children
- firstChildren.forEach(twoItem => {
- // 得到相关div标签
- if (twoItem.type === 'tag' && twoItem.name === 'div') {
- const twoChildren = twoItem.children
-
- twoChildren.forEach(threeItem => {
- // -------> 获取商品价格
- if (threeItem.type === 'tag' && threeItem.name === 'div' && threeItem.attribs.class === 'p-price') {
- const threeChildren = threeItem.children
- // 获取strong标签
- threeChildren.forEach(fourItem1 => {
- if (fourItem1.type === 'tag' && fourItem1.name === 'strong') {
- const fourItem1Children = fourItem1.children
- // 获取i标签
- fourItem1Children.forEach(fiveItem1 => {
- if (fiveItem1.type === 'tag' && fiveItem1.name === 'i') {
- const price = (fiveItem1.children[0]).data
- dataRes.price = price
- }
- })
- }
- })
- }
-
- // -------> 获取商品名称
- if (threeItem.type === 'tag' && threeItem.name === 'div' && threeItem.attribs.class === 'p-name p-name-type-2') {
- const threeChildren2 = threeItem.children
- // 获取strong标签
- threeChildren2.forEach(fourItem2 => {
- if (fourItem2.type === 'tag' && fourItem2.name === 'a') {
- const fourItem2Children = fourItem2.children
- // 获取i标签
- fourItem2Children.forEach(fiveItem3 => {
- if (fiveItem3.type === 'tag' && fiveItem3.name === 'em') {
- const fiveItem3Children = fiveItem3.children
- const fiveItem3ChildrenObj = fiveItem3Children.find(f => f.type === 'text')
- const name = fiveItem3ChildrenObj ? fiveItem3ChildrenObj.data : ''
- dataRes.name = name
- }
- })
- }
- })
- }
- })
- }
- })
-
- if (!_.isEmpty(dataRes)) {
- listDataRes.push(dataRes);
- }
- })
-
- console.log(`${cnt++}`); //这里就是为了自己在console中看到进度,没有实际用处。
- }
- done(); // 函数在回调中完成工作后必须调用它
- }
- });
-
- // 将其相关href写入json文件
- const writeListJson = () => {
- console.log(' =================> 队列为空时,数据处理完成')
- // 写入文件内容(如果文件不存在会创建一个文件)
- fs.writeFile('./jd_data/jd_goods_list.json', JSON.stringify(listDataRes), function (err) {
- if (err) {
- throw err;
- }
- console.log('all requests done and json saved!');
- });
- }
-
- // 指定爬取一个Url,将其添加到队列中
- //绝大多数网站,都有反爬机制。只有小众网站没有。所以我们需要使用以下配置
- //浏览器可以下载,但是服务端爬虫无效。反爬:检测你这个请求是通过浏览器发出来,还是服务端(解决方案:让服务端伪装成浏览器来发这个请求)
- c.queue({
- url: PATH_URL,
- headers: { 'User-Agent': 'requests' }//让服务端伪装成客户端
- });
-
- // 在队列为空时,调用以下函数
- c.on('drain', writeListJson);
4、cmd进入到index.js目录,执行 node index.js,生成如下
注意:简单的页面抓取数据,很容易实现。效果也不错,主要是根据HTML标签规则自定义获取数据。
目前存在一个问题:
例如:打开京东商品URL时,源码中展示的为30个商品信息列表,在鼠标向下滑动时,会自动追加商品数量,滑动到底部时查看源码中商品数量已增加到60个。
(刚开始研究node抓取数据)问题为在以上例子中只能抓取首屏的数据,那么如何滑动滚轮动态加载内容爬取?哪位大哥知道的,劳驾留个言指教一下小弟,先在此谢谢了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。