【Pyppeteer】如何进行超时时时间设置

【问题描述】

在爬取网页的过程中,不可避免会有一部分链接失效,或者各种原因导致服务器响应慢,甚至不响应。

这里有一个“超时时间” 的参数设置,就是如果服务器在指定时间内没有响应的话,程序直接停止等待响应,抛出异常。

Pyppeteer 默认的超时时间是 30 秒。

很多时候,30秒其实有点太长,或者太短了,我们希望可以根据项目实际情况,自己设置超时时间。

 

【解决方法】 

 我在网上找了一些方法,也做了一些测试。

不知道是不是我的方法有问题,目前只有 方法三 和 方法四 测试成功。这里将我找到的 各种方法,参考文章,以及我测试的代码放出来。希望给大家带来一些启发。

如果前两种方法测试失败是由于我代码哪儿没有写对的话,也希望有大佬能够指点指点,不胜感激!

方法一:

await page.setDefaultNavigationTimeout(timeout)

方法二:

await page.goto(url, {'timeout': 10000*20})

方法三:

await page.waitForNavigation({'timeout': 1000*30})

方法四: 

await asyncio.wait_for(page.goto(url), timeout=1.0)

参考文章:

  1.  数据获取_Pyppeteer_代理设置及超时设置
  2. pyppeteer 弹出页面造成阻塞

 

【测试过程】

方法一 测试代码如下:

import asyncio
from pyppeteer import launch
 
url = 'http://www.google.com'
 
async def fetchUrl(url):
    browser = await launch({'headless': False,'dumpio':True, 'autoClose':True})
    page = await browser.newPage()
 
    try:
        await page.setDefaultNavigationTimeout(10)
        await page.goto(url)
    except Exception as e:
        print(e)
 
asyncio.get_event_loop().run_until_complete(fetchUrl(url))

运行结果:失败,程序报错

>> object NoneType can't be used in 'await' expression

方法二 测试代码如下:

import asyncio
from pyppeteer import launch
import time
 
url = 'http://www.google.com'
 
async def fetchUrl(url):
    browser = await launch({'headless': False,'dumpio':True, 'autoClose':True})
    page = await browser.newPage()
 
    startTime = time.time()

    try:
        await page.goto(url, {'timeout': 1000*3})
    except Exception as e:
        print(e)

    endTime = time.time()
    print("运行时长:%d 秒"%(endTime-startTime))
 
asyncio.get_event_loop().run_until_complete(fetchUrl(url))

运行结果:失败,运行 21 秒后抛出超时异常,与设置 3 秒不符

>>   net::ERR_CONNECTION_TIMED_OUT at http://www.google.com
       运行时长:21 秒

 方法三 测试代码如下:

import asyncio
from pyppeteer import launch
import time
 
url = 'http://www.google.com'
 
async def fetchUrl(url):
    browser = await launch({'headless': False,'dumpio':True, 'autoClose':True})
    page = await browser.newPage()
 
    startTime = time.time()
    try:
        await page.waitForNavigation({'timeout': 1000*3})
        await page.goto(url)
    except Exception as e:
        print(e)

    endTime = time.time()
    print("运行时长:%d 秒"%(endTime-startTime))

 
asyncio.get_event_loop().run_until_complete(fetchUrl(url))

运行结果:成功,运行 3 秒后抛出超时异常

>>    Navigation Timeout Exceeded: 3000 ms exceeded.
        运行时长:3 秒

 方法四 测试代码如下:

import asyncio
from pyppeteer import launch
import time
 
url = 'http://www.google.com'
 
async def fetchUrl(url):
    browser = await launch({'headless': False,'dumpio':True, 'autoClose':True})
    page = await browser.newPage()
 
    startTime = time.time()
    try:
        await asyncio.wait_for(page.goto(url), timeout=3)
    except:
        print("timeout")

    endTime = time.time()
    print("运行时长:%d 秒"%(endTime-startTime))
 
asyncio.get_event_loop().run_until_complete(fetchUrl(url))

运行结果:成功,运行 3 秒后抛出超时异常

>>    timeout
        运行时长:3 秒

 

上述是我的整个测试过程,后两种方法测试可以使用。

至于前两种方法失败的原因,很有可能是我学艺不精,代码书写有问题导致,希望各位大佬看到后可以不吝赐教,指点指点正确的代码写法,机灵鹤在此不胜感激!


上一篇:【Pyppeteer】爬取多个网页时,如何只创建一个浏览器窗口,打开多个页签


下一篇:连阿里P8架构师都赞叹不已的Pyppeteer实用技能 (有源码)