如何强制Laravel应用使用Goutte而非Symfony处理Guzzle实例传参报错
错误根因
你当前使用的Goutte ≥ v4.0版本,该版本底层重构后直接继承Symfony\Component\BrowserKit\HttpBrowser,构造方法不再直接接收Guzzle原生GuzzleHttp\Client实例作为参数,仅支持传入实现了Symfony\Contracts\HttpClient\HttpClientInterface接口的实例。
解决方法(适配高版本Goutte,推荐)
步骤1:安装Symfony Http客户端依赖
执行composer命令安装适配包:
composer require symfony/http-client
步骤2:修改代码逻辑,将Guzzle实例包装为Symfony兼容的客户端实例
修改后的完整代码如下:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Goutte\Client; use GuzzleHttp\Cookie\CookieJar; use GuzzleHttp\Cookie\SetCookie; use GuzzleHttp\Client as GuzzleClient; use Symfony\Component\HttpClient\HttplugClient; // 新增适配器引用 class ScrapeController extends Controller { public function index() { return view('index'); } public function scrape() { $url = 'http://www.domain.com'; // 注意补全请求协议头,否则会触发请求错误 $domain = 'www.domain.com'; $cookieJar = new CookieJar(true); // 从www.domain.com获取cookie $cookieJar->setCookie(new SetCookie([ 'Domain' => "www.domain.com", 'Name' => '_name_session', 'Value' => 'value', 'Discard' => true ])); $guzzleClient = new GuzzleClient([ 'timeout' => 900, 'verify' => false, 'cookies' => $cookieJar ]); // 包装Guzzle实例为Symfony兼容的客户端 $symfonyClient = new HttplugClient($guzzleClient); $goutteClient = new Client($symfonyClient); $crawler = $goutteClient->request('GET', $url); $crawler->filter('table')->filter('tr')->each(function ($node) { dump($node->text()); }); } }
备选方案(降级Goutte版本,不推荐)
如果你不想修改适配逻辑,可以将Goutte降级到v3.x版本,该版本原生支持直接传入Guzzle实例:
composer require fabpot/goutte:^3.0
降级后无需修改原有代码即可正常运行。
内容的提问来源于stack exchange,提问作者kryz
相关产品推荐
相关产品推荐

