浏览器抓取网页(环境核心类库puppeteer文档安装第一步获取获取文章详情 )
优采云 发布时间: 2022-02-08 02:20浏览器抓取网页(环境核心类库puppeteer文档安装第一步获取获取文章详情
)
环境核心类库
傀儡师
文档
安装
npm i puppeteer -S
第一步是获取网页的内容
const puppeteer = require('puppeteer');
puppeteer.launch({
// 在导航期间忽略 HTTPS 错误
ignoreHTTPSErrors: true,
// 不在 无头模式 下运行浏览器
headless: false,
// 将 Puppeteer 操作减少指定的毫秒数
slowMo: 250,
// 等待浏览器实例启动的最长时间,0禁用超时
timeout: 0
}).then(async browser => {
// 一个新的 Page 对象
let page = await browser.newPage();
// 启用js
await page.setJavaScriptEnabled(true);
// 打开URL
await page.goto("https://juejin.cn/frontend");
console.log(await page.content())
// 关闭页面
await page.close();
// 关闭浏览器
await browser.close();
})
以上代码可以获取整个页面。测试发现问题已经解决。其实puppeteer有一个特殊的方法可以解决这个问题,page.waitForSelector,等待匹配指定选择器的元素出现在页面上。
const puppeteer = require('puppeteer');
puppeteer.launch({
// 在导航期间忽略 HTTPS 错误
ignoreHTTPSErrors: true,
// 不在 无头模式 下运行浏览器
headless: false,
// 将 Puppeteer 操作减少指定的毫秒数
slowMo: 250,
// 等待浏览器实例启动的最长时间,0禁用超时
timeout: 0
}).then(async browser => {
// 一个新的 Page 对象
let page = await browser.newPage();
// 启用js
await page.setJavaScriptEnabled(true);
// 打开URL
await page.goto("https://juejin.cn/frontend");
// 等待列表出现
await page.waitForSelector('.entry-list-wrap .entry-list .item');
console.log(await page.content())
// 关闭页面
await page.close();
// 关闭浏览器
await browser.close();
})
第二步,获取列表中的标题和链接
const puppeteer = require('puppeteer');
puppeteer.launch({
// 在导航期间忽略 HTTPS 错误
ignoreHTTPSErrors: true,
// 不在 无头模式 下运行浏览器
headless: false,
// 将 Puppeteer 操作减少指定的毫秒数
slowMo: 250,
// 等待浏览器实例启动的最长时间,0禁用超时
timeout: 0
}).then(async browser => {
// 一个新的 Page 对象
let page = await browser.newPage();
// 启用js
await page.setJavaScriptEnabled(true);
// 打开URL
await page.goto("https://juejin.cn/frontend");
// 等待列表出现
await page.waitForSelector('.entry-list-wrap .entry-list .item');
// 获取列表中标题和链接
const list = await page.$$eval('.entry-list-wrap .entry-list .title-row a', list => {
return list.map(item => {
return {
title: item.innerText,
href: item.href,
}
});
});
console.log(list.length)
console.log(list)
// 关闭页面
await page.close();
// 关闭浏览器
await browser.close();
})
第三步,获取文章详情
const puppeteer = require('puppeteer');
puppeteer.launch({
// 在导航期间忽略 HTTPS 错误
ignoreHTTPSErrors: true,
// 不在 无头模式 下运行浏览器
headless: false,
// 将 Puppeteer 操作减少指定的毫秒数
slowMo: 250,
// 等待浏览器实例启动的最长时间,0禁用超时
timeout: 0
}).then(async browser => {
// 一个新的 Page 对象
let page = await browser.newPage();
// 启用js
await page.setJavaScriptEnabled(true);
// 打开URL
await page.goto("https://juejin.cn/frontend");
// 等待列表出现
await page.waitForSelector('.entry-list-wrap .entry-list .item');
// 获取列表中标题和链接
let list = await page.$$eval('.entry-list-wrap .entry-list .title-row a', list => {
return list.map(item => {
return {
title: item.innerText,
href: item.href,
}
});
});
list = list.slice(0, 10)
// 获取文章详情
for (let i = 0; i e.innerHTML)
}
console.log(list[0])
// 关闭页面
await page.close();
// 关闭浏览器
await browser.close();
})
第四步,保存数据
这里不介绍保存到数据库,简单写个json文件。
const puppeteer = require('puppeteer');
const fs = require('fs')
const path = require('path')
puppeteer.launch({
// 在导航期间忽略 HTTPS 错误
ignoreHTTPSErrors: true,
// 不在 无头模式 下运行浏览器
headless: false,
// 将 Puppeteer 操作减少指定的毫秒数
slowMo: 250,
// 等待浏览器实例启动的最长时间,0禁用超时
timeout: 0
}).then(async browser => {
// 一个新的 Page 对象
let page = await browser.newPage();
// 启用js
await page.setJavaScriptEnabled(true);
// 打开URL
await page.goto("https://juejin.cn/frontend");
// 等待列表出现
await page.waitForSelector('.entry-list-wrap .entry-list .item');
// 获取列表中标题和链接
let list = await page.$$eval('.entry-list-wrap .entry-list .title-row a', list => {
return list.map(item => {
return {
title: item.innerText,
href: item.href,
}
});
});
list = list.slice(0, 10)
// 获取文章详情
for (let i = 0; i e.innerHTML)
}
// 保存数据
fs.writeFileSync(path.resolve(__dirname, '../out/articles.json'), JSON.stringify(list, null, 2))
// 关闭页面
await page.close();
// 关闭浏览器
await browser.close();
})
最后进行方法提取等处理
方法文件
const fs = require('fs')
exports.init = async function (browser) {
let page = await browser.newPage();
await page.setJavaScriptEnabled(true);
await page.goto("https://juejin.cn/frontend");
await page.waitForSelector('.entry-list-wrap .entry-list .item');
return page;
}
exports.getList = async function (page) {
let list = await page.$$eval('.entry-list-wrap .entry-list .title-row a', list => {
return list.map(item => {
return {
title: item.innerText,
href: item.href,
}
});
});
return list.slice(0, 10)
}
exports.getListDetail = async function (list, page) {
for (let i = 0; i e.innerHTML)
}
return list
}
exports.writeFile = async function (name, content) {
fs.writeFileSync(name, content)
}
主文件
const puppeteer = require('puppeteer');
const path = require('path')
const methods = require('./methods')
puppeteer.launch({
// 在导航期间忽略 HTTPS 错误
ignoreHTTPSErrors: true,
// 不在 无头模式 下运行浏览器
headless: false,
// 将 Puppeteer 操作减少指定的毫秒数
slowMo: 250,
// 等待浏览器实例启动的最长时间,0禁用超时
timeout: 0
}).then(async browser => {
try {
// 初始化
let page = await methods.init(browser);
// 获取列表中标题和链接
let list = await methods.getList(page)
// 获取文章详情
list = await methods.getListDetail(list, page)
// 保存数据
methods.writeFile(path.resolve(__dirname, '../out/articles.json'), JSON.stringify(list, null, 2))
// 关闭页面
await page.close();
// 关闭浏览器
await browser.close();
} catch (error) {
console.error(error)
// 关闭浏览器
await browser.close();
}
})
项目地址