如何解决错误:Puppeteer 中的 net::ERR_CONNECTION

Posted

技术标签:

【中文标题】如何解决错误:Puppeteer 中的 net::ERR_CONNECTION【英文标题】:How to get around Error: net::ERR_CONNECTION in Puppeteer 【发布时间】:2021-08-18 02:41:49 【问题描述】:

我尝试从该站点获取代理:https://hidemy.name/en/proxy-list/?type=4#list

这是我的 Puppeteer 抓取代码(部署到 Heroku),它在 .goto() 行的标题中返回错误:

const preparePageForTests = async (page) => 

const userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/78.0.3904.108 Safari/537.36';

  await page.setUserAgent(userAgent);

  await page.evaluateOnNewDocument(() => 
    Object.defineProperty(navigator, 'webdriver', 
      get: () => false,
    );
  );

  // Pass the Chrome Test.
  await page.evaluateOnNewDocument(() => 
    // We can mock this in as much depth as we need for the test.
    window.navigator.chrome = 
      app: 
        isInstalled: false,
      ,
      webstore: 
        onInstallStageChanged: ,
        onDownloadProgress: ,
      ,
      runtime: 
        PlatformOs: 
          MAC: 'mac',
          WIN: 'win',
          android: 'android',
          CROS: 'cros',
          LINUX: 'linux',
          OPENBSD: 'openbsd',
        ,
        PlatformArch: 
          ARM: 'arm',
          X86_32: 'x86-32',
          X86_64: 'x86-64',
        ,
        PlatformNaclArch: 
          ARM: 'arm',
          X86_32: 'x86-32',
          X86_64: 'x86-64',
        ,
        RequestUpdateCheckStatus: 
          THROTTLED: 'throttled',
          NO_UPDATE: 'no_update',
          UPDATE_AVAILABLE: 'update_available',
        ,
        OnInstalledReason: 
          INSTALL: 'install',
          UPDATE: 'update',
          CHROME_UPDATE: 'chrome_update',
          SHARED_MODULE_UPDATE: 'shared_module_update',
        ,
        OnRestartRequiredReason: 
          APP_UPDATE: 'app_update',
          OS_UPDATE: 'os_update',
          PERIODIC: 'periodic',
        ,
      
    ;
  );

  await page.evaluateOnNewDocument(() => 
    const originalQuery = window.navigator.permissions.query;
    return window.navigator.permissions.query = (parameters) => (
      parameters.name === 'notifications' ?
        Promise.resolve( state: Notification.permission ) :
        originalQuery(parameters)
    );
  );

  await page.evaluateOnNewDocument(() => 
    // Overwrite the `plugins` property to use a custom getter.
    Object.defineProperty(navigator, 'plugins', 
      // This just needs to have `length > 0` for the current test,
      // but we could mock the plugins too if necessary.
      get: () => [1, 2, 3, 4, 5],
    );
  );

  await page.evaluateOnNewDocument(() => 
    // Overwrite the `plugins` property to use a custom getter.
    Object.defineProperty(navigator, 'languages', 
      get: () => ['en-US', 'en'],
    );
  );


const browser = await puppeteerExtra.launch( headless: true, args: [                
'--no-sandbox', '--disable-setuid-sandbox', '--proxy-server=socks4://109.94.182.128:4145']);

const page = await browser.newPage();

await preparePageForTests(page);

await page.goto('https://www.google.com/search?q=concerts+near+new+york&client=safari&rls=en&uact=5&ibp=htl;events&rciv=evn&sa=X&fpstate=tldetail#htivrt=events&htidocid=L2F1dGhvcml0eS9ob3Jpem9uL2NsdXN0ZXJlZF9ldmVudC8yMDIxLTA2LTA0fDIxMjMzMzg4NTU2Nzc1NDk%3D&fpstate=tldetail') 

我有时也会收到“ERR_CONNECTION_CLOSED”或“ERR_CONNECTION_FAILED”而不是 ERR_CONNECTION_RESET。

任何帮助摆脱这个错误(大概是通过在 preparePageForTests 函数中添加更多通过谷歌测试的方法)将是惊人的,谢谢!

【问题讨论】:

在我的情况下,这是使用带有 puppeteer 的本地 nodejs 服务器随机发生的。 @NeilGuyLindberg 不知道为什么,我仍然不确定如何修复我的不是本地服务器... 【参考方案1】:

您使用的是低质量的公共代理,它们很自然会产生网络错误和/或被 Google 阻止。这里最简单的解决方案是付费。

但如果page.open失败,也可以拦截错误并重复请求:

const collectData = async (page) => 
  try 
    await page.goto('https://www.google.com/search?q=concerts+near+new+york');
    return page.evaluate(() => document.title);
   catch (err) 
    console.error(err.message);
    return false;
  


let data = false;
let attempts = 0;

// Retry request until it gets data or tries 5 times
while(data === false && attempts < 5)

  data = await collectData(page);
  attempts += 1;  
  if (data === false) 
    // Wait a few seconds, also a good idea to swap proxy here*
    await new Promise((resolve) => setTimeout(resolve, 3000));
  



* 以编程方式更改代理的模块:

https://www.npmjs.com/package/puppeteer-page-proxy https://www.npmjs.com/package/proxy-chain

【讨论】:

我真的很喜欢这个概念,但还没有实现它——首先,我已经安装了代理链,然后使用了高质量的付费代理,我在这里尝试使用 Zilvia Smith 的解决方案:***.com/questions/49376910/…,但奇怪的是当调用 'await page.waitForSelector("ul", timeout: 30000 )' 时出现超时错误。不知道为什么,因为如果我不使用代理 waitForSelector 按预期工作。我已经尝试了多个代理。你有什么建议吗? 您可能会因为页面未在 30 秒内加载或没有该列表而超时。您是否检查页面内容实际上是您认为的内容?使用headless: false 模式还是使用屏幕截图?根据代理,您可能会看到一个插页式、模态、重定向或只是一个块页面。 我建议首先使用您自己的代理进行训练,该代理应该可以 100% 工作 - 安装类似 3proxy 的东西 - 并访问类似 example.com 的简单内容; 然后去抓取目标。 我正在截取屏幕截图,但收到一条错误消息:'403.那是一个错误。您的客户端无权从该服务器获取 URL/........我们知道的就这些。'所以我假设谷歌正在检测我的抓取——你还有其他建议吗? 嗯,这是另一个值得自己提问的问题,但我认为我们已经解决了这个关于代理网络错误的问题,你不是说吗?【参考方案2】:

你需要awaitpage.goto("...")

await page.goto("https://google.com", waitUntil: "networkidle2");

【讨论】:

这不起作用——await 在我的代码中,但我不小心将它从问题中删除了——另外,waitUntil 会导致 timeoutError 发生,因为我已经部署到 Heroku,它遇到了30 秒后超时。我还用谷歌搜索的实际 URL 更新了我的代码(如果有帮助的话)。

以上是关于如何解决错误:Puppeteer 中的 net::ERR_CONNECTION的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 Puppeteer 抛出的“节点不可见或不是 HTMLElement”错误?

Puppeteer - 协议错误(Page.navigate):目标已关闭

如何从 puppeteer 获取返回值? [复制]

如何登录 Puppeteer?

Node.js puppeteer - 如何设置导航超时?

如何解决在electron里无法使用puppeteer的evaluate函数