log(chalk.yellow('页面数据加载完毕'))
// 处理数据,这个函数的实现在下面
await handleData()
// 一个页面爬取完毕以后稍微歇歇,不然太快淘宝会把你当成机器人弹出验证码(虽然我们本来就是机器人)
await page.waitFor(2500)
}
// 所有的数据爬取完毕后关闭浏览器
await browser.close()
log(chalk.green('服务正常结束'))
// 这是一个在内部声明的函数,之所以在内部声明而不是外部,是因为在内部可以获取相关的上下文信息,如果在外部声明我还要传入 page 这个对象
async function handleData() {
// 现在我们进入浏览器内部搞些事情,通过page.evaluate方法,该方法的参数是一个函数,这个函数将会在页面内部运行,这个函数的返回的数据将会以Promise的形式返回到外部
const list = await page.evaluate(() => {
// 先声明一个用于存储爬取数据的数组
const writeDataList: IWriteData[] = []
// 获取到所有的商品元素
let itemList = document.querySelectorAll('.item.J_MouserOnverReq')
// 遍历每一个元素,整理需要爬取的数据
for (let item of itemList) {
// 首先声明一个爬取的数据结构
let writeData: IWriteData = {
picture: undefined,
link: undefined,
title: undefined,
price: undefined
}
// 找到商品图片的地址
let img = item.querySelector('img')
writeData.picture = img.src
// 找到商品的链接
let link: HTMLAnchorElement = item.querySelector('.pic-link.J_ClickStat.J_ItemPicA')
writeData.link = link.href
// 找到商品的价格,默认是string类型 通过~~转换为整数number类型
let price = item.querySelector('strong')
writeData.price = ~~price.innerText
// 找到商品的标题,淘宝的商品标题有高亮效果,里面有很多的span标签,不过一样可以通过innerText获取文本信息
let title: HTMLAnchorElement = item.querySelector('.title>a')
writeData.title = title.innerText
// 将这个标签页的数据push进刚才声明的结果数组
writeDataList.push(writeData)
}
// 当前页面所有的返回给外部环境
return writeDataList
})
// 得到数据以后写入到mongodb
const result = await mongo.insertMany('GTX1080', list)
log(chalk.yellow('写入数据库完毕'))
}
} catch (error) {
// 出现任何错误,打印错误消息并且关闭浏览器
console.log(error)
log(chalk.red('服务意外终止'))
await browser.close()
} finally {
// 最后要退出进程
process.exit(0)
}
}
思考
1、为什么使用Typescript?









