前言
基于上一篇文章,趁着公司业务不忙的时候,又悄悄跑过来更新文章,这回我们要讲到关于爬取的数据存储问题了。
必要依赖安装
1. mysql (数据库的,相信各位小伙伴一定不会陌生)
npm install mysql
2.co-mysql (将mysql中异步回调形式,令其可以使用async await形式)
npm install co-mysql
基本配置实现之数据库简单配置
说到数据库,我们首先想到是的登录数据库的一些必要东西,所以下面来讲讲关于数据库的部分小配置。首先我们新建一个config.js。(下面的代码不懂得话,可能要各位自行度娘了。)
const mysql = require('mysql');
var host = 'localhost';
var ip = 'http://127.0.0.1:3000'
var pool = mysql.createPool({
host: '127.0.0.1',
user: 'root',
password: 'XXXXX', //这里的密码根据你们的数据库自行设置
database: 'personal-db',
connectTimeout: 30000})
module.exports = {
ip: ip,
pool: pool,
host: host,
}
代码逻辑实现
1.首先,我们要开始讲讲代码了,其实也很简单。我们接下去走走看看。
const mysql = require('./config'); // 引入我们的config文件
const wrapper = require('co-mysql')
let db = wrapper(mysql.pool); // 这里使用co-mysql 链接起我们的数据库
2. 其次 这个是mysql 插入数据库的语句
let addSql = 'INSERT INTO finance SET ?'
可能很多小伙伴会说,为什么我的sql 总是提示语法错误。我是根据 菜鸟教程上面写的。 问题来了,这个还真不是菜鸟教程写错了,因为目前我们安装的版本是最新的,所以语法会有些许不一样。
低版本写法(引用 ‘www.runoob.com/nodejs/node…’) 有sql基础条件的同学可以跳过。
var addSql = 'INSERT INTO websites(Id,name,url,alexa,country) VALUES(0,?,?,?,?)';
我们自己可以参考 (www.npmjs.com/package/mys…) 这是最新文档的地方,具体如下图。
3. 在代码的实现中
// addSql 是我们上面写的sql语句 obj是我们要存入的数据
await db.query(addSql, obj).catch(err => {
console.log(err);
})
// 就这么几行代码就实现了我们的具体功能了。
代码全部实现
1.修复了上一篇文章部分小问题 (。)
const puppeteer = require('puppeteer')
const baseUrl = 'https://www.yicai.com';
const mysql = require('./config');
const wrapper = require('co-mysql')
let db = wrapper(mysql.pool);
let addSql = 'INSERT INTO finance SET ?'// 等待3000毫秒
const sleep = time => new Promise(resolve => {
setTimeout(resolve, time);})
; (async () => {
const browser = await puppeteer.launch({
headless: false, //浏览器界面启动
slowMo: 200, //放慢浏览器执行速度,方便测试观察
args: ['--no-sandbox'],
dumpio: false,
devtools: true, //开发模式
});
const page = await browser.newPage();
await page.goto(baseUrl, {
waitUntil: 'networkidle2'
}); //由于出现了广告页面,从而影响到点击事件,所以先等待广告页面出现后将其关闭 await page.$eval('.m-layer', (el, value) => el.setAttribute('style', value), 'display: none' ) await page.waitFor(2000) // 等待某个节点的加载
await page.waitForSelector('.u-btn')
for (let index = 0; index < 1; index++) {
await page.waitFor(2000);
await page.click('.u-btn')
}
const result = await page.evaluate(() => {
let apiUrl = 'https://www.yicai.com';
let $ = window.$;
// var items = $('.m-con a') // 不可用这个,由于页面是通过display:none or block来控制的,爬取的数据会是多个页面的叠加 var items = $('#headlist').children('a')
var links = []
if (items.length >= 1) {
items.each((index, item) => {
let it = $(item)
let articleTitle = it.find('h2').text()
let articleIntroduction = it.find('p').text()
let imageAddress = it.find('img').attr('src')
let createdTime = it.find('span').text()
let detailPage = it.attr('href')
links.push({
articleTitle,
articleIntroduction,
imageAddress,
createdTime,
detailPage: apiUrl + detailPage
})
})
}
return links
})
// 暂缓1s
await sleep(1000)
; (async () => {
let allResult = []
for (let i = 0; i < result.length; i++) {
let detailInfo = '';// 文章详情
await page.goto(result[i].detailPage, {
waitUntil: 'networkidle2'
});
// 先判断元素是否存在
const element = await page.$(".m-text");
if (element) {
await page.waitForSelector('.m-text')
}
var obj = await page.evaluate((result, i) => {
let $ = window.$;
if ($("#multi-text").length > 0) {
var pageDom = $('#multi-text')
if (pageDom) {
detailInfo = pageDom[0].innerHTML
}
result[i].detailInfo = detailInfo
return obj = result[i]
} else {
result[i].detailInfo = ''
return obj = result[i]
}
}, result, i)
await db.query(addSql, obj).catch(err => {
console.log(err);
})
allResult.push(obj)
await page.waitFor(2000);
await page.goBack();
}
console.log(JSON.stringify(allResult))
await page.close();
// ------------------------------------------------------------------------------
// 专页测试模块
// await page.goto('https://www.yicai.com/image/100730324.html', {
// waitUntil: 'networkidle2'
// });
// const element = await page.$(".m-text");
// if (element) {
// await page.waitForSelector('.m-text')
// }
// var obj = await page.evaluate(() => {
// let obj = {}
// let $ = window.$;
// if ($("#multi-text").length > 0) {
// var pageDom = $('#multi-text')
// if (pageDom) {
// console.log('11111111111111')
// // https://www.yicai.com/video/100728928.html
// // https://www.yicai.com/image/100730324.html
// detailInfo = pageDom[0].innerHTML
// }else{
// console.log('222222222222222')
// }
// }
// })
// ------------------------------------------------------------------------------
})();
})();
2.实现截图,不弄虚作假。老实本分ing~
写在最后
编写文章只是用于学习,各位小伙伴也要老实本分哦。文章存在许多不足之处,希望路过的小伙伴多加指点,共同进步。