记录一次nodejs爬取《17吉他》所有吉他谱

本文记录了一次使用Node.js爬取《17吉他》所有吉他谱的过程,重点讨论遇到的技术挑战,如GBK编码、异步请求、内存溢出等,并分享了解决方案。涉及到的技术包括JavaScript、爬虫和递归。
摘要由CSDN通过智能技术生成

记录一次nodejs爬取《17吉他》所有吉他谱(只探讨技术)

突然就想扒一下吉他谱了,说做就做哈哈,中间也是没有想象中的顺利啊,出现了各种意想不到的坑,包括老生常谈的nodejs异步写法,还有可怕的内存溢出等问题。。我将一步步回顾各种重要的错误及我的解决方法,只贴关键部分代码,只探讨技术。(本篇文章不是入门文章,读者需要具有一定的ES6/7,nodejs能力以及爬虫相关知识)

使用的技术

由于未使用同步写法的nodejs框架,而且各种库也都是回调写法,需要稍作修改,所以对ES6/7的同步写法有一定的要求

nodejs request cheerio(类似jquery) ES6/7 mongoose iconv-lite uuid

观察页面结构获取相关dom元素

我们的最终目的就是获取所有的吉他谱,然后保存到我们的数据库中,我们使用cheerio来获取页面的dom元素,所以首先我们观察一下页面结构,怎么观察我就不说了,说一下我看到的规律

img标签

image

可以看到,吉他谱的图片会带一个alt标签在图片没有显示的时候显示提示信息,我们发现这个提示就是吉他谱的名字,这样我们就可以轻松的知道我们爬下来的图片是哪首歌的了,哈哈!

链接

网站的链接有很多,尤其这种论坛形式的,我们不能全都爬一遍,这样的话又费时间又爬取了很多无效的图片,所以我们需要找到这种吉他谱页面的路由规律:

// 正则
/^http:\/\/www.17jita.com\/tab\/img\/[0-9_]{4,6}.html/
// 对应路由
http://www.17jita.com/tab/img/8088.html
http://www.17jita.com/tab/img/8088_2.html

对于数学问题,代码比语言更清楚~

a 标签

由于我们扒的是整个网站的吉他谱,所以需要递归所有的a标签,为了防止递归无效a标签,我们就使用上面的正则匹配一下对应的路由是否是吉他谱路由

++到这里与前端相关的就基本结束了,剩下的就看nodejs了,我不会直接贴完成后的代码,我会尽量还原我犯的错以及解决方法++

首先我们安装这些东西

npm install --save mongoose request cheerio iconv-lite bagpipe

请求路由下载第一个页面

request ({url: baseUrl,
      'User-Agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
      gzip:true
    }, (err, res, body) => {
        console.log(body)
        // ...
    })

我后来发现,他们居然没有限制UA,所以User-Agent不写是没关系的,然后gzip最好写一下,因为网站用了gzip压缩,不过不写好像也可以。然后。。

第一个坑 (gbk编码)

当你打印body的时候你会发现,中文全是乱码,这年头居然还用gbk我也是醉了,nodejs原生不支持gbk,只能用第三方包解码了,代码如下:

const iconv = require('iconv-lite');
request ({url: baseUrl,
      encoding: null,
      'User-Agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
      gzip:true
    }, (err, res, body) => {
        body = iconv.decode(body, 'gb2312');
        console.log(body)
        // ...
    })

第二个坑(同步写法的request)

现在是2018年了,js在同步写法上以及多了很多创新了,咱们也得赶赶潮流不是,我决定用async来改写这段代码,结果,人家request不支持。。。

const result = await request ({url: baseUrl,
      encoding: null,
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值