我想,爬虫对很多人来说是一个很有魅力的话题,它意味着不用什么努力就拿到了别人辛苦付出的的劳动成果。
其原理就是:服务端请求数据,然后爬取页面内容。常用的请求库是request,常用的爬虫工具是cheerio——它可以像jq一样爬取你想要的dom内容。
npm i cheerio request iconv-lite -S
很多大网站都会反爬虫。但是豆瓣top250的页面还不错。任你上下其手,看完这些电影,应该就不是250了。
下面就将实现这个功能。
访问https://movie.douban.com/top250?start=0,研究页面结构。可得到一下信息:
在业务方面,当我收集了全部数据后,可存放到本地的data.json中。
// spider.js
const fs = require('fs');
const path = require('path')
const originRequest = require("request");
const cheerio = require("cheerio");
const iconv = require("iconv-lite");
// 封装request
function request(url, callback) {
const options = {
url: url,
encoding: null
};
originRequest(url, options, callback);
}
//data作为参数加入到迭代中。
const getData = function (i, data) {
data = data ? data : [];
const url = `https://movie.douban.com/top250?start=${i * 25}`;
request(url, function (err, res, body) {
const html = iconv.decode(body, "utf-8");
const $ = cheerio.load(body);
let dataItem = []
for (let j = 0; j < $('.item .title:first-of-type').length; j++) {
dataItem.push({
title: $('.item .title:first-of-type')[j].children[0].data,
rank: i * 25 + j + 1
})
}
// 衔接数组
data.push(...dataItem);
if (i < 11) {
return getData(i + 1, data)
} else {
console.log('获取数据完成')
fs.writeFile('data.json', JSON.stringify(data), (err) => {
if (!err) {
console.log('写入成功')
} else {
console.log('写入失败')
}
})
}
});
}
getData(0)
这里必须用到到异步循环,所以使用递归来实现,每次递归都把累计请求到的数据迭代到下一次递归中。
执行完毕后,内容就存放到data,json中了。
格式化之后成功拿到标准的json数据:
懦怯囚禁人的灵魂,希望可以让你自由。 ——肖申克的救赎