Symfony DomCrawler遇OpenSSL连接重置错误(errno10054)求助
Symfony Crawler提交表单时SSL连接重置问题的解决思路
问题场景
我正在学习Symfony Crawler,想要实现以下流程:
- 访问指定页面
- 填写表单数据
- 提交表单
- 提交后若跳转到
example.org/error则更换数据重新提交,否则下载目标页面内容
我的实现代码(Symfony Command):
$io = new SymfonyStyle($input, $output); $url = "https://example.org"; $browser = new HttpBrowser(HttpClient::create()); $crawler = $browser->request('GET', $url); $form = $crawler->selectButton('submitForm')->form(); $form['field1'] = 'foo'; //temporary data $form['field2'] = 'bar'; $form['field3'] = 'baz'; $form['field4'] = '12345'; $crawler = $browser->submit($form); if(!$crawler->getBaseHref() === "https://example.org/error") { $nodeValues = $crawler->filter('.section')->each(function (Crawler $node, $i) { return $node->text(); }); $io->info("Important message: ".$nodeValues[0]); }
出现的错误
运行后95%概率触发以下错误:
In ErrorChunk.php line 62: OpenSSL SSL_read: Connection was reset, errno 10054 for "https://example.org".
In CurlResponse.php line 337: OpenSSL SSL_read: Connection was reset, errno 10054 for "https://example.org".
仅5%的情况能正常获取数据。
问题分析与解决
这个错误大概率是网站反爬机制触发,也可能是HttpClient配置缺失导致请求被识别为非浏览器请求,可从以下方向调整:
1. 模拟浏览器请求头
默认HttpClient的请求头特征明显,容易被拦截,创建客户端时添加标准浏览器请求头:
$browser = new HttpBrowser(HttpClient::create([ 'headers' => [ 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language' => 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3', 'Accept-Encoding' => 'gzip, deflate, br', 'Connection' => 'keep-alive', 'Upgrade-Insecure-Requests' => '1', ], ]));
2. 添加请求延迟
频繁提交请求会触发反爬阈值,提交前添加随机延迟:
// 随机延迟1-3秒,模拟人工操作间隔 sleep(rand(1, 3)); $crawler = $browser->submit($form);
3. 完善Cookie会话管理
确保请求携带网站设置的Cookie,显式启用CookieJar管理会话:
$cookieJar = new CookieJar(); $browser = new HttpBrowser(HttpClient::create(), null, $cookieJar);
4. 修正跳转判断逻辑
原代码的判断语法有误,!$crawler->getBaseHref() === "xxx"的优先级错误,应改为:
if ($crawler->getBaseHref() !== "https://example.org/error") { // 处理成功页面逻辑 } else { // 更换数据重新提交的逻辑 }
5. 添加错误重试机制
针对连接重置这类偶发网络错误,添加重试逻辑避免直接终止:
$maxRetries = 3; $retryCount = 0; $success = false; do { try { $crawler = $browser->submit($form); $success = true; } catch (\Exception $e) { $retryCount++; if ($retryCount >= $maxRetries) { throw $e; } sleep(2); // 重试前等待2秒 } } while (!$success);
内容的提问来源于stack exchange,提问作者TeslaX93
相关产品推荐
相关产品推荐

