【问题描述】
在爬取网页的过程中,不可避免会有一部分链接失效,或者各种原因导致服务器响应慢,甚至不响应。
这里有一个“超时时间” 的参数设置,就是如果服务器在指定时间内没有响应的话,程序直接停止等待响应,抛出异常。
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)
参考文章:
- 数据获取_Pyppeteer_代理设置及超时设置
- 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 秒
上述是我的整个测试过程,后两种方法测试可以使用。
至于前两种方法失败的原因,很有可能是我学艺不精,代码书写有问题导致,希望各位大佬看到后可以不吝赐教,指点指点正确的代码写法,机灵鹤在此不胜感激!