视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
node.js爬取中关村的在线电瓶车信息
2020-11-27 22:04:04 责编:小采
文档

背景

学习nodejs已经有段时间,网上很多nodejs爬虫的文章,所以着手练习写一段,最近打算买一辆电瓶车来上下班,但又不知道哪个好,网上是各说纷纭啊,于是就想着,干脆用node.js自己写一个小爬虫,来爬一下中关村在线里面电瓶车的信息吧。

简介

该demo采用node.js作为爬虫,为方便,有些地方使用es6语法,如有不懂,欢迎咨询😊

步骤

第一步,引入需要的库

var cheerio = require('cheerio');
var fetch = require('node-fetch');

// cheerio 是一个类似浏览器端的jQuery,用来解析HTML的
// fetch 用来发送请求

第二步,设置初始的爬取的入口(我身处杭州,所以地区选了杭州的🤣)

// 初始url
var url = "http://detail.zol.com.cn/convenienttravel/hangzhou/#list_merchant_loc"
// 由于每个a标签下是相对路径,故需要一个根地址来拼接,如下
var urlRoot = "http://detail.zol.com.cn" 
// 存放所有url,之所以用set,是为了防止有相同的而重复爬去
var urls = new Set()
// 存储所有数据
var data = [] 

至此,我们的准备部分结束了😅,接下来,开始表演了

分析网页,思考爬取的方式


每行4款,每页是48款,一共16页

思路:

  • 每次获取当前页48个链接,并点进去之后,拿到该电瓶车的名称和价格(其他信息获取方式一样,自行改就好😂)
  • 第一页的全部完成之后,翻到下一页,继续爬,直到最后一页结束
  • 首先我们定义一个函数如下

    // 这是得到每个页面的48个链接,并开始发送请求
    
    function ad(arg){
    // 参数 arg 先不管
    // 本地化一下需要爬取的链接
    let url2 = arg || url;
    // 请求第一页该网页,拿到数据之后,复制给 app
    var app = await fetch(url2).then(res=>res.text())
    // 然后假装用jQuery解析了
    var $ = cheerio.load(app)
    // 获取当前页所有电瓶车的a标签
    var ele = $("#J_PicMode a.pic")
    // 存放已经爬取过的url,防止重复爬取
    var old_urls = []
    var urlapp = []
    //拿到所有a标签地址之后,存在数组里面,等会儿要开始爬的
    for (let i = 0; i < ele.length; i++) {
    old_urls.push(fetch(urlRoot+$(ele[i]).attr('href')).then(res=>res.text()))
    }
    // 用把URL一块丢给promise处理
    urlapp = await Promise.all(old_urls)
    // 处理完成之后,循环加入jQuery😂
    for (let i = 0; i < urlapp.length; i++) {
    let $2 = cheerio.load(urlapp[i],{decodeEntities: false})
    data.push({
    name:$2(".product-model__name").text(),
    price:$2(".price-type").text()
    })
    }
    // 至此,一页的数据就爬完了
    // console.log(data);
    
    // 然后开始爬取下一页
    var nextURL = $(".next").attr('href')
    // 判断当前页是不是最后一页
    if (nextURL){
    let next = await fetch(urlRoot+nextURL).then(res=>res.text())
    // 获取下一页的标签,拿到地址,走你
    ad(urlRoot+nextURL)
    }
    return data
    }
    ad()

    完整代码如下

    var cheerio = require('cheerio');
    var fetch = require('node-fetch');
    var url = "http://detail.zol.com.cn/convenienttravel/hangzhou/#list_merchant_loc"
    var urlRoot = "http://detail.zol.com.cn"
    // var url = "http://localhost:3222/app1"
    var urls = new Set()
    var data = [] 
    async function ad(arg){
    let url2 = arg || url;
    var app = await fetch(url2).then(res=>res.text())
    var $ = cheerio.load(app)
    var ele = $("#J_PicMode a.pic")
    var old_urls = []
    var urlapp = []
    for (let i = 0; i < ele.length; i++) {
    old_urls.push(fetch(urlRoot+$(ele[i]).attr('href')).then(res=>res.text()))
    }
    urlapp = await Promise.all(old_urls)
    for (let i = 0; i < urlapp.length; i++) {
    let $2 = cheerio.load(urlapp[i],{decodeEntities: false})
    data.push({
    name:$2(".product-model__name").text(),
    price:$2(".price-type").text()
    })
    }
    
    var nextURL = $(".next").attr('href')
    if (nextURL){
    let next = await fetch(urlRoot+nextURL).then(res=>res.text())
    ad(urlRoot+nextURL)
    }
    return data
    }
    ad()

    总结

    下载本文
    显示全文
    专题