利用jquery爬取网页数据,爽得一笔

2020-04-19 16:33:54 浏览数 (1)

以前我们说到爬取网页数据,你可能会第一时间想到scrapy,嗯,那个强大的python爬虫库,然而,有些时候,我们其实要爬取数据并非一定要使用这么强大【笨重】的库来实现,而且,某些时候,可能使用scrapy来爬取我们想到的数据,还比较困难。

举个例子:假如,我们想购买一台腾讯云CVM服务器,这时候你们团队肯定会有一个预算,这时候,可能你们PM想对比一下各种配置的价格,他发现去云官网上看会比较痛苦,需要点好多好多次,然后对比也没有那么直接,那么这时候,他可能会给你提一个需求。

比如,把各个Region的都爬出来,然后CPU的类型选择所有的类型,或者说还有一些杂七杂八的刷选条件,一言以蔽之,就是有些选项是默认,有些需要勾选指定项

最终,需要将这么多分页数据都给爬出来。嗯,以上就是我们要做的事情。

那么,分析一下,有几个难点

1、页面中有一些选项,需要我们选择,并非都是默认,所以,页面加载出来之后,我们需要选择。

2、其次,这个网页中的数据是异步加载的,可以使用curl一下网页,发现我们需要的数据并没有,是一个空架子而已。

3、这里面有分页数据,都爬取下来,举个例子,对于该页,我们需要从第1页点击到第

20页,然后把这些表格中的数据都捞下来。

所以,可以看下我们的任务,这对于选择scrapy来做的化,可能不是特别好实现,就拿页面中的一些form项中的勾选,选择,这点scrapy就并不是特别擅长。

所以,想一想,我们熟悉的什么库比较适合操作dom,然后拿dom中的内容呢?jQuery,很明显,jQuery就非常适合做这样的操作。

使用jQuery获取数据

使用jQuery爬取页面数据,主要要掌握以下几个基本的技能:

1、如何找到需要操作的form元素,然后利用click()方法,选中需要选择的项。

2、如何找到我们需要导出的数据。

3、如何在网页中导出json数据,(注意也可以是其他格式)。

然后我们分析一下,比如这个页面有10页,那其实就是写一个for循环。

代码语言:txt复制
for (var i = 0; i < pageCount;i  ){
    nextPage.click()
    collectData()
}

注意,这里的难点是,click选项之后,页面是需要一定的时间才能加载出数据的,所以,点击之后,我们并不能马上去拿数据,需要等页面加载数据成功,因此上面click之后,马上去搜索数据,很明显不对

那么,该如何办呢?我们写一个等待函数?

代码语言:txt复制
for (var i = 0; i < pageCount;i  ){
    nextPage.click()
    wait(3000)
    collectData()
}

function wait(ms){
    var start = new Date().getTime();
    var end = start;
    while(end < start   ms) {
      end = new Date().getTime();
   }
}

请注意,我一开始也是这么想的,但是,click()之后,页面卡死了,更本不是我们想象的效果,点击之后,刷新到下一页,让后,我们在这里等待个3s左右,让网络把数据加载好,但实际上这个点击之后的过程背后是需要执行js代码的,然而我们的wait函数没有给他那个机会,因此,你看到页面不会有任何变化。

所以,我们不能同步等待,需要异步等待。那么,如何异步等待呢?我想到了setTimeout,

代码语言:txt复制
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

setInterval(travelPages,500)
function travelPages(){
    if(!dataCollecteFinished) return 
    nextPage.click()
    sleep(3000).then(collectData)
}

所以,这里for循环似乎并不好用了,为了异步,我使用了setInterval来代替循环,能执行循环中的条件是,我已经将上页加载的数据抓取完毕。

嗯,这个思路下来,我成功的完成了这个任务。

一些疑问

1、假如入目标页面没有jQuery怎么办,很简单,没有我们就给他注入jQuery,

代码语言:txt复制
(function() {
  var hm = document.createElement("script");
  hm.src = "http://libs.baidu.com/jquery/2.0.0/jquery.min.js";
  var s = document.getElementsByTagName("title")[0]; 
  s.parentNode.insertBefore(hm, s);
})()

2、同样的道理,加入页面没有Promise啥的,都可以使用这种方式注入,但其实那里并没有必要使用Promise,直接写一个setTimeout也是可以的,但是注意全局污染(很可能同时多个搜集器在搜集数据,造成数据混乱,用Promise封装不仅仅是为了优雅,更多的是为了让垃圾回收器一起自动回收掉setTimeout)

3、如何在使用js导出json

代码语言:txt复制
(function (console) {

    console.save = function (data, filename) {

        if (!data) {
            console.error('Console.save: No data')
            return;
        }

        if (!filename) filename = 'console.json'

        if (typeof data === "object") {
            data = JSON.stringify(data, undefined, 4)
        }

        var blob = new Blob([data], {
                type: 'text/json'
            }),
            e = document.createEvent('MouseEvents'),
            a = document.createElement('a')

        a.download = filename
        a.href = window.URL.createObjectURL(blob)
        a.dataset.downloadurl = ['text/json', a.download, a.href].join(':')
        e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        a.dispatchEvent(e)
    }
})(console)

4、如何把json文件转换为xsl,因为产品汪可能更喜欢看xsl

送你一个在线转的网址,https://json-csv.com/

 总结

有时候,使用jQuery来爬取网页数据,也是很方便的,利用jQuery强大的查找dom元素,及操作dom元素的特性,实现起来可能要比scrapy简单的多。

0 人点赞