需求:根据关键词搜索 爬取某网站的列表跳转的链接及标题 并导入excel
感觉这次的思路并不是很正确 是一种野路子 个人理解正常的爬虫是爬取页面的内容 而我这次是直接调用接口获取数据 拿到数据后整理 导入excel 感觉还有很大整理及优化空间 遇到的问题 多次疯狂请求会出现验证码 疯狂过分的请求会导致封号和封ip 解决方式用代理 多个账号进行调用接口
新手需要注意一下爬取的网站是否有robots协议
编码
导入所需模块
// 首先导入所需的所有模块
const fs = require('fs'); //引入fs模块 读写作用
const xlsx = require('node-xlsx'); // 引入控制excel的模块
const superagent = require('superagent') // superagent-nodejs处理请求的模块
var request = require("request"); // 引入请求模块
var Promise = require("bluebird");
require('superagent-proxy')(superagent);
注册全局变量
// 全局变量部分
// 小饼干~
var cookie; // 存储登陆cookie 获取请求时需要带上cookie因为每次都更换ip和账号 所以就每次都需要存
// 搜索所有的关键字
var keyword = []
// 获取excle里已有的数据 这里可以优化一下 判断一下是否有这个excel如果没有就新建 如果有就获取
var info = xlsx.parse("./resut.xlsx")
// 搜索关键词 这一步是搜索第几个关键词 思路是 所有关键词 然后通过获取的excel里的数据有几条就是该搜索第几个了
var searchString = keyword[info.length];
// 所有账号
var user = [17*******36, 17*******90, 17******72, 17******5, 17******40]
// 每次随机一个账号
var username = user[Math.floor(Math.random() * user.length)];
// 固定密码 所有的账号密码都是一样的
var password = 'a123456';
// 所有数据 获取到的数据需要标题 链接 和 链接为手动拼接 接口只返回了datainfo
var addInfo = {
name: searchString,
data: [
['title', 'href', 'datainfo']
]
// 请填写无忧代理订单号 这里用的无忧代理 缺点收费 自己倒贴11块钱 其实可以自己动手寻找免费的代理 思路都是一样的
var order = '';
// 要测试的网址
var targetURL = 'http://ip.chinaz.com/getip.aspx';
// 请求超时时间
var timeout = 8000;
// 测试次数
var testTime = 5;
// 间隔多少毫秒调用一次接口
var sleepTime = 5000;
// 获取代理ip的网站
var apiURL = 'http://api.ip.data5u.com/dynamic/get.html?order=' + order + '&sep=3';
获取代理ip
// 获取代理ip异步方法
function getProxyList() {
return new Promise((resolve, reject) => {
var options = {
method: 'GET',
url: apiURL,
gzip: true,
encoding: null,
headers: {},
};
request(options, function (error, response, body) {
try {
if (error) throw error;
var ret = (body + '').match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,5}/g);
resolve(ret);
} catch (e) {
return reject(e);
}
});
});
获取代理ip并测试速度是否能使用
function execute() {
// 调用获取代理ip方法 并测试代理速度
getProxyList().then(function (proxyList) {
var targetOptions = {
method: 'GET',
url: targetURL,
timeout: timeout,
encoding: null,
};
proxyList.forEach(function (proxyurl) {
// 修改全局变量代理ip
proxy = 'http://' + proxyurl
console.log(proxy, 'ip')
var startTimestamp = (new Date()).valueOf();
targetOptions.proxy = 'http://' + proxyurl;
request(targetOptions, function (error, response, body) {
try {
if (error) throw error;
body = body.toString();
var endTimestamp = (new Date()).valueOf();
var time = endTimestamp - startTimestamp
getCookie();
} catch (e) {
console.error(e);
}
});
});
}).catch(e => {
console.log(e);
}).finally(() => {})
}
登陆获取cookie
// 获取登陆饼干
function getCookie() {
// 调用网站的登陆方法
superagent.post('https://www.com')
// 设置代理ip
.proxy(proxy)
.type('form')
.send({
// 需要发送的数据
reqType: 'phoneLogin',
phone: username,
password: password,
})
.end(function (err, res) {
if (err) {
handleErr(err.message);
return;
}
cookie = res.header['set-cookie']; //从response中得到cookie 并赋值到全局变量
getData();
})
}
获取列表 整理数据并导入excel
async function getData() {
// 因为只获取前10页 所以循环十遍 该网站 页面只能看得到10页 但是接口可以继续向后调 为了安全 所以只拿前10页
for (let i = 1; i <= 10; i++) {
// 调用列表的接口
const response = await superagent.post('https://www')
// 设置代理
.proxy(proxy)
.type('form')
// 设置饼干
.set('Cookie', cookie)
// 发送数据
.send({
})
if (JSON.parse(response.text).list !== null) {
// 转译需要的数据 将数据转换成json
let addData = JSON.parse(response.text);
// 取出数据中的list list为我们需要的数据
let list = addData.list;
list.map((res) => {
// 提取我们需要的 title dataid href为拼接后的数据
let getInfo = [res.title, 'https://www' + res._id + '.html', res._id]
// 将提取出的数据存放到所有数据中
addInfo.data.push(getInfo)
})
console.log(i)
} else {
// 同上 这里是不够10页数据的时候
info.push(addInfo)
console.log(username, 'username')
console.log(searchString, 'searchString')
var buffer = xlsx.build(info);
fs.writeFile('./resut.xlsx', buffer, function (err) {
if (err)
throw err;
});
return;
}
}
info.push(addInfo)
// 修改excel文件
var buffer = xlsx.build(info);
fs.writeFile('./resut.xlsx', buffer, function (err) {
if (err)
throw err;
});
}
调用方法
// 最后一部就是调用啦
execute();
项目不足 总结
- 使用了收费代理
- 需要每次都去运行这个node index.js每次完事儿都需要在手动运行 没有实现全部自动
- 感觉路子不对 比如如果需要的数据不是接口返回 是在js中的 就无法实现了 如果在dom中可以使用尝试cheerio来完成
遇到的困难
- 如果遇到js动态加载的dom不知道如何处理 想用puppeteer来爬取 感觉有点杀鸡用牛刀
github地址
转载需标明出处
结语
一次简单的爬虫 希望对你有所帮助 欢迎各位大佬热烈讨论及建议 我们一起解决 顺便圆我js动态加载的dom处理的梦