python爬虫怎么爬同一个网站的多页数据-请问爬虫如何爬取动态页面的内容?
现在网页大多是动态网页,尤其是内容丰富,值得爬取的网站,几乎无一例外是动态的,比如狗东、淘宝和知乎,而且还有不少反爬手段,这些都大大提升了爬虫难度,尤其是淘宝,为了反爬不惜影响到正常用户使用。
面对这些动态网页,通常的手法都是监听、抓包、分析js文件,这些都不简单,而且还麻烦。
对于这些网站,有一款神器可以实现降维打击,那就是Google出品的爬虫工具 Puppeteer。它本质上是一个chrome浏览器,只不过可以通过代码进行各种操控。
比如模拟鼠标点击、键盘输入等等,有点像按键精灵,而网页很难分清楚这是人类用户还是爬虫,所以限制也就无处谈起。
这不,即使js文件弄得再复杂也好,压根不用看,模仿用户操作就行,直接获取信息!
并且使用起来非常简单,是所有可以爬取动态网页的库里最简单的一个,使用的语言是node.js。
但坏处也很明显,那就是速度慢。它等于每次运行都会启动一个Chrome浏览器,所以运行效率上远远比不过其它库,并不适合爬取大数据。但对于小爬虫来说绰绰有余了,并且我们还可以优化一下,让它能胜任更多任务。
接下来以我写过的爬取jd商品页面的小爬虫为例,功能是监控商品是否上架,来看看这款小爬虫有多简单。
运行后是这样: />
1.安装Puppeteer:
先安装Puppeteer库,用到的也就只有这个库:
npm install puppeteer
2.开始链接网页
链接网页也非常简单,只需要几行代码:
const puppeteer = require('puppeteer')
//启动浏览器const browers = await puppeteer.launch()
//启动新页面const page = await browers.newPage()
//链接网址await page.goto(url)
这样子就链接成功了!Puppeteer.launch()还可以接收很多参数,但这里我们用到的只有headless,默认为ture,如果是false的话会显示浏览器界面。我们可以利用这个特性实现弹出窗口提醒,一旦发现有符合条件的商品就将headless改成false。
3.爬取商品信息
在链接网页后接下来就是爬取商品信息,然后进行分析。
网址:妙控板 />
3.1获取相对应的元素标签
通过页面可以看到,一旦有同类商品会出现在旁边的同类夺宝里,我们只需要爬取那里的信息就行了,有两种方式:
一种是$eval,相当于js里的document.querySelector,只爬取符合的第一个元素;
另一种为$$eval,相当于js里的document.querySelectorAll,爬取所有符合的元素;
它们接收的第一个参数是元素地址,第二个参数是回调函数,操作和document.querySelector一样,来看代码:
//拿到同类夺宝里的所有子元素const goods = page.$$eval('#auctionRecommend > div.mc > ul > li', ele => ele)
3.2.分析商品信息
现在已经拿到了同类夺宝里所有商品的标签信息,接下来开始分析信息。
获取里面所有商品的名称,然后对照关键字是否存在,如果存在则将headless改为false弹出窗口提醒,如果不存在则在半小时后再次链接。
Puppeteer提供了一个等待命令page.waitFor(),不仅可以按时间等待,也可以按某个元素的加载进度进行等待。
const goods = page.$$eval('#auctionRecommend > div.mc > ul > li', el => {
//错误和关键字不存在都会返回false try {
for (let i = 0; i < el.length; i++) {
let n = el[i].querySelector('div.p-name').textContent
if(n.includes('妙控板')){
return true
} else {
return false
}
}
} catch (error) {
return false
}
})
if(!bool){
return console.log('网页已打开,不再监控')
}
//根据goods里面的回调函数返回ture或false来决定是否开启浏览器界面await goods.then(async (b) => {
if(b){
console.log('有货了!')
await page.waitFor(2000)
await browers.close()
return requestUrl(false)
} else {
console.log('还没货')
console.log('三十分钟后再尝试')
await page.waitFor(1800000)
await browers.close()
return requestUrl(true)
}
})
4.优化代码
对于这个小爬虫来说,损失的效率并不多,没什么优化的必要,但作为一个强迫症,还是希望能去掉的尽量去掉。
4.1拦截图片
在这个爬虫里,我们根本不用看任何图片信息,所以所有图片都没有加载的必要,为了提升一点点运行效率,将所有图片拦截掉:
//开启拦截器await page.setRequestInterception(true)
await page.on('request',interceptedRequest => {
//判断加载的url是否以jpg或png结尾,符合条件将不再加载 if(interceptedRequest.url().endsWith('.jpg') || interceptedRequest.url().endsWith('.png')){
interceptedRequest.abort();
}else{
interceptedRequest.continue();
}
})
4.2调整窗口大小
在浏览器弹出时,会发现打开的窗口显示范围很小,不仅不方便浏览,可能还会导致点击或输入等操作出错,所以还是有必要进行调整:
await page.setViewport({
width: 1920,
height: 1080,
})
至此,所有代码已经完成了,试试效果吧!
5.完整代码
const puppeteer = require('puppeteer')
const url = 'https://paipai.jd.com/auction-detail/114533257?entryid=p0120003dbdnavi'
const requestUrl = async function(bool){
const browers = await puppeteer.launch({headless:bool})
const page = await browers.newPage()
await page.setRequestInterception(true)
await page.on('request',interceptedRequest => {
if(interceptedRequest.url().endsWith('.jpg') || interceptedRequest.url().endsWith('.png')){
interceptedRequest.abort();
}else{
interceptedRequest.continue();
}
})
await page.setViewport({
width: 1920,
height: 1080,
})
await page.goto(url)
const goods = page.$$eval('#auctionRecommend > div.mc > ul > li', el=>{
try {
for (let i = 0; i < el.length; i++) {
let n = el[i].querySelector('div.p-name').textContent
if(n.includes('妙控板')){
return true
} else {
return false
}
}
} catch (error) {
return false
}
})
if(!bool){
return console.log('网页已打开,不再监控')
}
await goods.then(async (b)=>{
if(b){
console.log('有货了!')
await page.waitFor(2000)
await browers.close()
return requestUrl(false)
} else {
console.log('还没货')
console.log('三十分钟后再尝试')
await page.waitFor(1800000)
await browers.close()
return requestUrl(true)
}
})
}
requestUrl(true)
也可以通过Github获取完整代码:watchJd.js
如果对你有帮助,欢迎关注我,我会持续输出更多好文章!
python爬虫怎么爬同一个网站的多页数据-请问爬虫如何爬取动态页面的内容?相关推荐
- python爬虫怎么爬同一个网站的多页数据-如何用Python爬数据?(一)网页抓取
如何用Python爬数据?(一)网页抓取 你期待已久的Python网络数据爬虫教程来了.本文为你演示如何从网页里找到感兴趣的链接和说明文字,抓取并存储到Excel. 需求 我在公众号后台,经常可以收到 ...
- python爬取多页数据_python爬虫实现爬取同一个网站的多页数据代码实例
本篇文章小编给大家分享一下python爬虫实现爬取同一个网站的多页数据代码实例,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 一.爬虫的目的 从网上获 ...
- scrapy爬取动态页面
文章目录 简介 查看目标网站 代码部分 简介 现在在整理原来写过的东西,这是一个比较简单的爬虫项目,就是进行动态页面的爬取,主要的难点是实现模拟点击. 查看目标网站 查看目标网站: 但是这不是我们的目 ...
- Scrapy爬取动态页面下载图片(以抓取360图片为例)
当我们想要抓取一个页面的内容时,要做的第一件事不是写代码,而是分析页面,确定这是一个静态页面还是动态页面.抓取静态页面的方法十分简单,直接解析html源码再进行分析解析即可,如果不太明白,可以参考我上 ...
- node 没有界面的浏览器_node.js爬虫入门(二)爬取动态页面(puppeteer)
之前第一篇爬虫教程node.js爬虫入门(一)爬取静态页面讲解了静态网页的爬取,十分简单,但是遇到一些动态网页(ajax)的话,直接用之前的方法发送请求就无法获得我们想要的数据.这时就需要通过爬取动态 ...
- Python之web开发(六):python使用django框架搭建网站之登陆页搭建不同页面之间跳转
[写在前面]:有关urls及path函数的应用详见:https://blog.csdn.net/weixin_44322778/article/details/102598346 [官方说明]: 规划 ...
- php爬虫爬取百度的内容,爬虫(一)抓取百度页面的内容
最近在实习,导师又没得项目让我一起做东西,就自己坐在一边瞎鼓捣东西 那闲着也是闲着,想来写写爬虫 爬虫百度百科上的定义如下 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页 ...
- 爬取静态页面分页内容
静态准备爬取静态页面分页知识,因为写博客现在目的是当笔记一样,当学过知识梳理一遍,如果有观众,不喜勿喷,不足之处可以多多指点 工具:python3.6 操作系统:linux 浏览器:谷歌浏览器 创建项 ...
- python爬取动态页面图片_python动态网页爬取:爬取pexel上的图片
前言 同样的,我们在写一个爬虫前要明确自己想要爬取的东西是什么,明确下载目标数据在浏览器的操作如何 对于动态网页的爬取,在网页地址不变的情况下,我们首先要明确如何获取AJAX请求 首先我们看看这个网站 ...
最新文章
- CCNA基础知识汇总
- 聊聊flink的AscendingTimestampExtractor
- 如何在 Linux 中启用 Shell 脚本的调试模式
- 我觉得要技术者上升到整体去考虑会好点
- SpringMVC日期类型转换问题三大处理方法归纳
- Python 函数的可变参数、切片、迭代和列表生成式
- SAP Commerce Accelerator从2005升级到2011的步骤
- vb net excel 剪贴板 粘贴_利用剪贴板强化 Excel 计算
- centos7之关于时间和日期以及时间同步的应用
- 有序多分类Logistic回归(图文+数据集)【SPSS 079期】
- python内置数据类型列表_python数据类型内置方法 字符串和列表
- 软件测试之黑盒测试白盒测试
- JS数组ES3-ES6常用方法
- 在Windows中查看文件的MD5值
- jquery 仿天猫加入购物车,小图标慢慢上升消失
- Linux下更新Chrome和vscode
- STM32’s I2C 硬件BUG引发的血案(qzm)
- ARM内核全解析,从ARM7 ARM9到Cortex-A7 A8 Cortex-A53 A57 A72
- 如何编写功能测试报告?详细测试方案模板参考
- bim的二次开发需要什么语言_BIM软件的二次开发是什么?都需要做哪些准备?
热门文章
- 使用netty编写IM通信界面
- C++:MSVCRTD.lib(crtexe.obj) : error LNK2019: 无法解析的外部符号 _main,该符号在函数 ___tmainCRTStart...
- iOS 可能用到的三方框架
- Balanced Binary Tree
- FMS3系列学习网上教程
- 阿里P7工作总结:Spring MVC的工作原理,看完受益匪浅
- Connection reset by peer原理解析
- sql server 用户'sa'登录失败(错误18456)
- Java 递归解决 quot;仅仅能两数相乘的计算器计算x^yquot; 问题
- R语言成功加载rJava方法