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

如果对你有帮助,欢迎关注我,我会持续输出更多好文章!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值