├── .php_cs.dist.php ├── .shiftrc ├── LICENSE.md ├── README.md ├── composer.json ├── config └── scrapingbee.php ├── rector.php └── src ├── LaravelScrapingBee.php ├── LaravelScrapingBeeFacade.php ├── LaravelScrapingBeeGoogleSearch.php └── LaravelScrapingBeeServiceProvider.php /.php_cs.dist.php: -------------------------------------------------------------------------------- 1 | in([ 5 | __DIR__ . '/src', 6 | __DIR__ . '/tests', 7 | ]) 8 | ->name('*.php') 9 | ->notName('*.blade.php') 10 | ->ignoreDotFiles(true) 11 | ->ignoreVCS(true); 12 | 13 | return (new PhpCsFixer\Config()) 14 | ->setRules([ 15 | '@PSR12' => true, 16 | 'array_syntax' => ['syntax' => 'short'], 17 | 'ordered_imports' => ['sort_algorithm' => 'alpha'], 18 | 'no_unused_imports' => true, 19 | 'not_operator_with_successor_space' => true, 20 | 'trailing_comma_in_multiline' => true, 21 | 'phpdoc_scalar' => true, 22 | 'unary_operator_spaces' => true, 23 | 'binary_operator_spaces' => true, 24 | 'blank_line_before_statement' => [ 25 | 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'], 26 | ], 27 | 'phpdoc_single_line_var_spacing' => true, 28 | 'phpdoc_var_without_name' => true, 29 | 'class_attributes_separation' => [ 30 | 'elements' => [ 31 | 'method' => 'one', 32 | ], 33 | ], 34 | 'method_argument_space' => [ 35 | 'on_multiline' => 'ensure_fully_multiline', 36 | 'keep_multiple_spaces_after_comma' => true, 37 | ], 38 | 'single_trait_insert_per_statement' => true, 39 | ]) 40 | ->setFinder($finder); 41 | -------------------------------------------------------------------------------- /.shiftrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ziming/laravel-scrapingbee/4077b30ac86d2d9039dc30d56ba61d59c4bcaa4a/.shiftrc -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) ziming 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A PHP Laravel Library for [ScrapingBee](https://www.scrapingbee.com?fpr=php-laravel) 2 | 3 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/ziming/laravel-scrapingbee.svg?style=flat-square)](https://packagist.org/packages/ziming/laravel-scrapingbee) 4 | [![Total Downloads](https://img.shields.io/packagist/dt/ziming/laravel-scrapingbee.svg?style=flat-square)](https://packagist.org/packages/ziming/laravel-scrapingbee) 5 | 6 | A PHP Laravel Package for [ScrapingBee](https://www.scrapingbee.com?fpr=php-laravel) 7 | 8 | If you wanted to support my work you can use my [referral link to create an account & be a paid customer of ScrapingBee](https://www.scrapingbee.com?fpr=php-laravel). 9 | 10 | ## Installation 11 | 12 | You can install the package via composer: 13 | 14 | ```bash 15 | composer require ziming/laravel-scrapingbee 16 | ``` 17 | 18 | You can publish the config file with: 19 | ```bash 20 | php artisan vendor:publish --provider="Ziming\LaravelScrapingBee\LaravelScrapingBeeServiceProvider" --tag="laravel-scrapingbee-config" 21 | ``` 22 | 23 | This is the contents of the published config file: 24 | 25 | ```php 26 | return [ 27 | 'api_key' => env('SCRAPINGBEE_API_KEY'), 28 | 'base_url' => env('SCRAPINGBEE_BASE_URL', 'https://app.scrapingbee.com/api/v1/'), 29 | 'timeout' => env('SCRAPINGBEE_TIMEOUT', 120), 30 | ]; 31 | ``` 32 | 33 | ## Usage 34 | 35 | ### The Generic ScrapingBee Client 36 | 37 | ```php 38 | $scrapingBeeClient = Ziming\LaravelScrapingBee\LaravelScrapingBee::make(); 39 | 40 | $response = $scrapingBeeClient->blockAds() 41 | ->when(now()->weekOfMonth === 4, function (LaravelScrapingBee $scrapingBeeClient): LaravelScrapingBee { 42 | // if it is last week of the month, spam premium proxy to use up credits! 43 | return $scrapingBeeClient->premiumProxy(); 44 | }) 45 | ->jsonResponse() 46 | //->aiQuery('top 5 blog posts') // AI Query Feature! 47 | //->aiExtractRules(['title' => 'title of post', 'summary' => 'summary of post']) // AI Extract Feature! 48 | ->jsScenario([ 49 | ['click' => '#button_id'], 50 | ['wait' => 1000], 51 | ['wait_for' => '#slow_div'], 52 | ['scroll_x' => 1000], 53 | ['scroll_y' => 1000], 54 | ['fill' => ['#input_1','value_1']], 55 | ['evaluate' => 'console.log(window);'], 56 | ])->get('https://www.scrapingbee.com') 57 | ``` 58 | 59 | Look at the source code of `src/LaravelScrapingBee.php` for the other methods (link below). Methods that return `$this` are chainable. An example is the `blockAds()` method you saw above. Meanwhile methods such as `get()`, `post()`, `usageStatistics()` returns you an `Illuminate\Http\Client\Response` object if no exceptions are thrown. 60 | 61 | [LaravelScrapingBee.php](https://github.com/ziming/laravel-scrapingbee/blob/main/src/LaravelScrapingBee.php) 62 | 63 | If for some reason you prefer to set all parameters at once you may wish to use the `setParams() or addParams()` method. Take note that these methods simply takes in an array and sets the parameters as is. So for the methods that does something extra before setting the parameter you would have to do them yourselves now if you chose this path. 64 | 65 | An example is shown below: 66 | 67 | ```php 68 | $scrapingBeeClient = Ziming\LaravelScrapingBee\LaravelScrapingBee::make(); 69 | 70 | $response = $scrapingBeeClient->setParams([ 71 | 'js_scenario' => json_encode([ 72 | 'instructions' => [ 73 | ['click' => '#button_id'], 74 | ['wait' => 1000], 75 | ['wait_for' => '#slow_div'], 76 | ['scroll_x' => 1000], 77 | ['scroll_y' => 1000], 78 | ['fill' => ['#input_1','value_1']], 79 | ['evaluate' => 'console.log(window);'] 80 | ] 81 | ]), 82 | 'block_ads' => true, 83 | 'json_response' => true, 84 | ])->get('https://www.scrapingbee.com') 85 | ``` 86 | 87 | ### The Google Search ScrapingBee Client 88 | 89 | ```php 90 | $googleSearchScrapingBeeClient = Ziming\LaravelScrapingBee\LaravelScrapingBeeGoogleSearch::make(); 91 | 92 | $response = $googleSearchScrapingBeeClient 93 | ->nbResults(8) 94 | ->page(1) 95 | ->search('scrapingbee') 96 | ->get(); 97 | ``` 98 | Look at the source code of `src/LaravelScrapingBeeGoogleSearch.php` for the other methods (link below). 99 | 100 | [LaravelScrapingBeeGoogleSearch.php](https://github.com/ziming/laravel-scrapingbee/blob/main/src/LaravelScrapingBeeGoogleSearch.php) 101 | 102 | ## Testing 103 | 104 | Currently, there are no tests. But if there are tests in the future, you can run the command below to execute the testcases. 105 | 106 | ```bash 107 | composer test 108 | ``` 109 | 110 | ## Contributing 111 | 112 | You may see [CONTRIBUTING](.github/CONTRIBUTING.md) for details. 113 | 114 | ## Security Vulnerabilities 115 | 116 | Please review [our security policy](../../security/policy) on how to report security vulnerabilities. 117 | 118 | ## Credits 119 | 120 | - [Ziming](https://github.com/ziming) 121 | - [All Contributors](../../contributors) 122 | 123 | ## License 124 | 125 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 126 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ziming/laravel-scrapingbee", 3 | "description": "A PHP Laravel Library for ScrapingBee", 4 | "keywords": [ 5 | "laravel", 6 | "laravel-scrapingbee" 7 | ], 8 | "homepage": "https://github.com/ziming/laravel-scrapingbee", 9 | "license": "MIT", 10 | "authors": [ 11 | { 12 | "name": "Ziming", 13 | "email": "ziming.opensource@gmail.com", 14 | "role": "Package Uploader" 15 | } 16 | ], 17 | "require": { 18 | "php": "^8.1", 19 | "spatie/laravel-package-tools": "^1.13.5", 20 | "illuminate/contracts": "^9.0||^10.0||^11.0||^12.0" 21 | }, 22 | "require-dev": { 23 | "nunomaduro/collision": "^6.3||^7.0||^8.1.1", 24 | "orchestra/testbench": "^7.7||^8.0||^9.0||^10.0", 25 | "phpunit/phpunit": "^9.5.24||^10.0||^11.0||^12.0", 26 | "rector/rector": "^2.0", 27 | "spatie/laravel-ray": "^1.30", 28 | "symfony/thanks": "^1.3" 29 | }, 30 | "autoload": { 31 | "psr-4": { 32 | "Ziming\\LaravelScrapingBee\\": "src" 33 | } 34 | }, 35 | "autoload-dev": { 36 | "psr-4": { 37 | "Ziming\\LaravelScrapingBee\\Tests\\": "tests" 38 | } 39 | }, 40 | "scripts": { 41 | "test": "./vendor/bin/testbench package:test --no-coverage", 42 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage" 43 | }, 44 | "config": { 45 | "sort-packages": true, 46 | "allow-plugins": { 47 | "symfony/thanks": true 48 | } 49 | }, 50 | "extra": { 51 | "laravel": { 52 | "providers": [ 53 | "Ziming\\LaravelScrapingBee\\LaravelScrapingBeeServiceProvider" 54 | ], 55 | "aliases": { 56 | "LaravelScrapingBee": "Ziming\\LaravelScrapingBee\\LaravelScrapingBeeFacade" 57 | } 58 | } 59 | }, 60 | "minimum-stability": "dev", 61 | "prefer-stable": true 62 | } 63 | -------------------------------------------------------------------------------- /config/scrapingbee.php: -------------------------------------------------------------------------------- 1 | env('SCRAPINGBEE_API_KEY'), 7 | 'base_url' => env('SCRAPINGBEE_BASE_URL', 'https://app.scrapingbee.com/api/v1/'), 8 | 'timeout' => env('SCRAPINGBEE_TIMEOUT', 140), 9 | 'google_search_base_url' => env('SCRAPINGBEE_GOOGLE_SEARCH_BASE_URL', 'https://app.scrapingbee.com/api/v1/store/google'), 10 | ]; 11 | -------------------------------------------------------------------------------- /rector.php: -------------------------------------------------------------------------------- 1 | paths([ 9 | __DIR__ . '/src', 10 | __DIR__ . '/tests', 11 | ]); 12 | 13 | // Define what rule sets will be applied 14 | $rectorConfig->sets([ 15 | LevelSetList::UP_TO_PHP_81, 16 | ]); 17 | // $containerConfigurator->import(LaravelSetList::LARAVEL_80); 18 | 19 | // get services (needed for register a single rule) 20 | // $services = $containerConfigurator->services(); 21 | 22 | // register a single rule 23 | // $services->set(TypedPropertyRector::class); 24 | }; 25 | -------------------------------------------------------------------------------- /src/LaravelScrapingBee.php: -------------------------------------------------------------------------------- 1 | apiKey = $apiKey ?? config('scrapingbee.api_key'); 33 | $this->timeout = $timeout ?? config('scrapingbee.timeout'); 34 | 35 | $this->baseUrl = config( 36 | 'scrapingbee.base_url', 37 | 'https://app.scrapingbee.com/api/v1/' 38 | ); 39 | } 40 | 41 | /** 42 | * @throws ConnectionException 43 | */ 44 | private function request(string $method, string $url, array $data = [], string $postContentType = 'application/x-www-form-urlencoded; charset=utf-8'): Response 45 | { 46 | // https://www.scrapingbee.com/documentation/#encoding-url 47 | // urlencode($url) make things fail somehow. 48 | // My guess is urlencode is run at the Http::get() / Http::post() level already 49 | $this->params['url'] = $url; 50 | 51 | $this->params['api_key'] = $this->apiKey; 52 | 53 | $http = Http::withHeaders($this->headers)->timeout($this->timeout); 54 | 55 | if ($method === 'POST') { 56 | // If user never specify content type we use the 1 provided in the official docs. 57 | $http->withHeaders([ 58 | 'Content-Type' => $postContentType, 59 | ]); 60 | 61 | $response = $http->post($this->baseUrl . '?' . http_build_query($this->params), $data); 62 | } else { 63 | // else assume is a GET request 64 | $response = $http->get($this->baseUrl, $this->params); 65 | } 66 | 67 | // Reset the params and headers 68 | $this->reset(); 69 | 70 | return $response; 71 | } 72 | 73 | /** 74 | * @throws ConnectionException 75 | */ 76 | public function get(string $url): Response 77 | { 78 | return $this->request('GET', $url); 79 | } 80 | 81 | /** 82 | * @throws ConnectionException 83 | */ 84 | public function post(string $url, array $data = [], string $postContentType = 'application/x-www-form-urlencoded; charset=utf-8'): Response 85 | { 86 | return $this->request('POST', $url, $data, $postContentType); 87 | } 88 | 89 | /** 90 | * https://www.scrapingbee.com/documentation/#block-ads 91 | */ 92 | public function blockAds(): self 93 | { 94 | $this->params['block_ads'] = true; 95 | 96 | return $this; 97 | } 98 | 99 | /** 100 | * https://www.scrapingbee.com/documentation/#block-resources 101 | */ 102 | public function allowResources(): self 103 | { 104 | $this->params['block_resources'] = false; 105 | 106 | return $this; 107 | } 108 | 109 | /** 110 | * https://www.scrapingbee.com/documentation/#custom-cookies 111 | */ 112 | public function setCustomCookies(array $cookies): self 113 | { 114 | $this->params['cookies'] = http_build_query($cookies, '', ';'); 115 | 116 | return $this; 117 | } 118 | 119 | /** 120 | * https://www.scrapingbee.com/documentation/#geolocation 121 | */ 122 | public function countryCode(string $countryCode): self 123 | { 124 | $this->params['country_code'] = $countryCode; 125 | 126 | return $this; 127 | } 128 | 129 | /** 130 | * https://www.scrapingbee.com/documentation/#custom-google 131 | */ 132 | public function customGoogle(): self 133 | { 134 | $this->params['custom_google'] = true; 135 | 136 | return $this; 137 | } 138 | 139 | /** 140 | * https://www.scrapingbee.com/documentation/#device 141 | */ 142 | public function device(string $device): self 143 | { 144 | $this->params['device'] = $device; 145 | 146 | return $this; 147 | } 148 | 149 | /** 150 | * https://www.scrapingbee.com/documentation/#json_css 151 | * https://www.scrapingbee.com/documentation/data-extraction/ 152 | * @throws JsonException 153 | */ 154 | public function extractDataFromCssRules(array $cssRules): self 155 | { 156 | $this->params['extract_rules'] = json_encode($cssRules, JSON_THROW_ON_ERROR); 157 | 158 | return $this; 159 | } 160 | 161 | /* 162 | * https://www.scrapingbee.com/documentation/#ai_query 163 | * https://www.scrapingbee.com/documentation/#ai_selector 164 | * 165 | * There is no aiSelector() method since it need to be used with aiQuery 166 | */ 167 | public function aiQuery(string $query, ?string $selector = null): self 168 | { 169 | $this->params['ai_query'] = $query; 170 | 171 | if ($selector !== null) { 172 | $this->params['ai_selector'] = $selector; 173 | } 174 | 175 | return $this; 176 | } 177 | 178 | /** 179 | * https://www.scrapingbee.com/documentation/#ai_extract_rules 180 | * https://www.scrapingbee.com/documentation/#ai_selector 181 | * @throws JsonException 182 | */ 183 | public function aiExtractRules(array $rules, ?string $selector = null): self 184 | { 185 | $this->params['ai_extract_rules'] = json_encode($rules, JSON_THROW_ON_ERROR); 186 | 187 | if ($selector !== null) { 188 | $this->params['ai_selector'] = $selector; 189 | } 190 | 191 | return $this; 192 | } 193 | 194 | /** 195 | * https://www.scrapingbee.com/documentation/#json_response 196 | */ 197 | public function jsonResponse(): self 198 | { 199 | $this->params['json_response'] = true; 200 | 201 | return $this; 202 | } 203 | 204 | /** 205 | * https://www.scrapingbee.com/documentation/#javascript-execution 206 | */ 207 | public function jsSnippet(string $jsCodeSnippet): self 208 | { 209 | $this->params['js_snippet'] = base64_encode($jsCodeSnippet); 210 | 211 | return $this; 212 | } 213 | 214 | /** 215 | * https://www.scrapingbee.com/documentation/#javascript-scroll 216 | */ 217 | public function jsScroll(): self 218 | { 219 | $this->params['js_scroll'] = true; 220 | 221 | return $this; 222 | } 223 | 224 | /** 225 | * https://www.scrapingbee.com/documentation/#javascript-scroll 226 | */ 227 | public function jsScrollWait(int $milliseconds): self 228 | { 229 | $this->params['js_scroll_wait'] = $milliseconds; 230 | 231 | return $this; 232 | } 233 | 234 | /** 235 | * https://www.scrapingbee.com/documentation/#javascript-scroll 236 | */ 237 | public function jsScrollCount(int $count): self 238 | { 239 | $this->params['js_scroll_count'] = $count; 240 | 241 | return $this; 242 | } 243 | 244 | /** 245 | * https://www.scrapingbee.com/documentation/#premium-proxy 246 | */ 247 | public function premiumProxy(): self 248 | { 249 | $this->params['premium_proxy'] = true; 250 | 251 | return $this; 252 | } 253 | 254 | /** 255 | * https://www.scrapingbee.com/documentation/#stealth_proxy 256 | */ 257 | public function stealthProxy(): self 258 | { 259 | $this->params['stealth_proxy'] = true; 260 | 261 | return $this; 262 | } 263 | 264 | /** 265 | * https://www.scrapingbee.com/documentation/#own_proxy 266 | */ 267 | public function ownProxy(string $proxy): self 268 | { 269 | $this->params['own_proxy'] = $proxy; 270 | 271 | return $this; 272 | } 273 | 274 | /** 275 | * https://www.scrapingbee.com/documentation/#javascript-rendering 276 | */ 277 | public function disableJs(): self 278 | { 279 | $this->params['render_js'] = false; 280 | 281 | return $this; 282 | } 283 | 284 | /** 285 | * https://www.scrapingbee.com/documentation/#javascript-execution 286 | * https://www.scrapingbee.com/documentation/js-scenario/ 287 | * @throws JsonException 288 | */ 289 | public function jsScenario(array $instructions, bool $strict = true): self 290 | { 291 | $this->params['js_scenario'] = json_encode([ 292 | 'strict' => $strict, 293 | 'instructions' => $instructions, 294 | ], JSON_THROW_ON_ERROR); 295 | 296 | return $this; 297 | } 298 | 299 | /** 300 | * https://www.scrapingbee.com/documentation/#page-source 301 | */ 302 | public function pageSource(): self 303 | { 304 | $this->params['return_page_source'] = true; 305 | 306 | return $this; 307 | } 308 | 309 | /** 310 | * https://www.scrapingbee.com/documentation/#session_id 311 | */ 312 | public function session(int $id): self 313 | { 314 | $this->params['session_id'] = $id; 315 | 316 | return $this; 317 | } 318 | 319 | /** 320 | * https://www.scrapingbee.com/documentation/#timeout 321 | */ 322 | public function timeout(int $milliseconds): self 323 | { 324 | $this->params['timeout'] = $milliseconds; 325 | 326 | return $this; 327 | } 328 | 329 | /** 330 | * https://www.scrapingbee.com/documentation/#screenshot 331 | */ 332 | public function screenshot(): self 333 | { 334 | $this->params['screenshot'] = true; 335 | 336 | return $this; 337 | } 338 | 339 | /** 340 | * https://www.scrapingbee.com/documentation/#screenshot_selector 341 | */ 342 | public function screenshotSelector(string $selector): self 343 | { 344 | $this->params['screenshot_selector'] = true; 345 | 346 | return $this; 347 | } 348 | 349 | /** 350 | * https://www.scrapingbee.com/documentation/#screenshot_full_page 351 | */ 352 | public function screenshotFullPage(): self 353 | { 354 | $this->params['screenshot_full_page'] = true; 355 | 356 | return $this; 357 | } 358 | 359 | /** 360 | * https://www.scrapingbee.com/documentation/#transparent_status_code 361 | */ 362 | public function transparentHttpStatusCode(): self 363 | { 364 | $this->params['transparent_status_code'] = true; 365 | 366 | return $this; 367 | } 368 | 369 | /** 370 | * https://www.scrapingbee.com/documentation/#wait 371 | */ 372 | public function wait(int $milliseconds): self 373 | { 374 | $this->params['wait'] = $milliseconds; 375 | 376 | return $this; 377 | } 378 | 379 | /** 380 | * https://www.scrapingbee.com/documentation/#wait-for 381 | */ 382 | public function waitForCssSelector(string $cssSelector): self 383 | { 384 | $this->params['wait_for'] = $cssSelector; 385 | 386 | return $this; 387 | } 388 | 389 | /** 390 | * https://www.scrapingbee.com/documentation/#wait_browser 391 | */ 392 | public function waitForBrowser(string $networkCondition = 'domcontentloaded'): self 393 | { 394 | $this->params['wait_browser'] = $networkCondition; 395 | 396 | return $this; 397 | } 398 | 399 | /** 400 | * https://www.scrapingbee.com/documentation/#width_or_height 401 | */ 402 | public function windowWidth(int $windowWidth): self 403 | { 404 | $this->params['window_width'] = $windowWidth; 405 | 406 | return $this; 407 | } 408 | 409 | /** 410 | * https://www.scrapingbee.com/documentation/#width_or_height 411 | */ 412 | public function windowHeight(int $windowHeight): self 413 | { 414 | $this->params['window_height'] = $windowHeight; 415 | 416 | return $this; 417 | } 418 | 419 | /** 420 | * https://www.scrapingbee.com/documentation/data-extraction/#output 421 | */ 422 | public function output(string $output): self 423 | { 424 | $this->params['output'] = $output; 425 | 426 | return $this; 427 | } 428 | 429 | /* 430 | * This is for the situation if our API did not catch up and you want to add a new parameter 431 | * that Scrapingbee supports 432 | * like ->setParam('new_beta_feature', true) for example 433 | */ 434 | public function setParam(string $key, mixed $value): self 435 | { 436 | $this->params[$key] = $value; 437 | 438 | return $this; 439 | } 440 | 441 | public function setParams(array $params): self 442 | { 443 | $this->params = $params; 444 | 445 | return $this; 446 | } 447 | 448 | /* 449 | * Just in case there are new params that are not covered by the convenience params methods 450 | */ 451 | public function addParams(array $params): self 452 | { 453 | $this->params = array_merge_recursive($this->params, $params); 454 | 455 | return $this; 456 | } 457 | 458 | public function setHeaders(array $headers): self 459 | { 460 | $this->headers = array_combine( 461 | array_map(fn ($key) => 'Spb-'. $key, array_keys($headers)), 462 | $headers 463 | ); 464 | 465 | $this->params['forward_headers'] = true; 466 | 467 | return $this; 468 | } 469 | 470 | public function pureHeadersForwarding(): self 471 | { 472 | $this->params['forward_headers_pure'] = true; 473 | unset($this->params['forward_headers']); 474 | 475 | return $this; 476 | } 477 | 478 | private function reset(): self 479 | { 480 | $this->params = []; 481 | $this->headers = []; 482 | 483 | return $this; 484 | } 485 | 486 | /** 487 | * https://www.scrapingbee.com/documentation/#UsageEndpoint 488 | */ 489 | public function usageStatistics(): Response 490 | { 491 | return Http::get($this->baseUrl . 'usage', [ 492 | 'api_key' => $this->apiKey, 493 | ]); 494 | } 495 | } 496 | -------------------------------------------------------------------------------- /src/LaravelScrapingBeeFacade.php: -------------------------------------------------------------------------------- 1 | apiKey = $apiKey ?? config('scrapingbee.api_key'); 29 | 30 | $this->baseUrl = config( 31 | 'scrapingbee.google_search_base_url', 32 | 'https://app.scrapingbee.com/api/v1/store/google' 33 | ); 34 | } 35 | 36 | public function get(): Response 37 | { 38 | $this->params['api_key'] = $this->apiKey; 39 | $response = Http::get($this->baseUrl, $this->params); 40 | $this->reset(); 41 | 42 | return $response; 43 | } 44 | 45 | /** 46 | * https://www.scrapingbee.com/documentation/google/#search 47 | */ 48 | public function search(string $query): self 49 | { 50 | $this->params['search'] = $query; 51 | 52 | return $this; 53 | } 54 | 55 | /** 56 | * https://www.scrapingbee.com/documentation/google/#search_type 57 | */ 58 | public function searchType(string $type): self 59 | { 60 | $this->params['search_type'] = $type; 61 | 62 | return $this; 63 | } 64 | 65 | /** 66 | * https://www.scrapingbee.com/documentation/google/#country_code 67 | */ 68 | public function countryCode(string $countryCode): self 69 | { 70 | $this->params['country_code'] = $countryCode; 71 | 72 | return $this; 73 | } 74 | 75 | /** 76 | * https://www.scrapingbee.com/documentation/google/#nb_results 77 | */ 78 | public function nbResults(int $count): self 79 | { 80 | $this->params['nb_results'] = $count; 81 | 82 | return $this; 83 | } 84 | 85 | /** 86 | * https://www.scrapingbee.com/documentation/google/#page 87 | */ 88 | public function page(int $pageNumber): self 89 | { 90 | $this->params['page'] = $pageNumber; 91 | 92 | return $this; 93 | } 94 | 95 | /** 96 | * https://www.scrapingbee.com/documentation/google/#language 97 | */ 98 | public function language(string $language): self 99 | { 100 | $this->params['language'] = $language; 101 | 102 | return $this; 103 | } 104 | 105 | /** 106 | * https://www.scrapingbee.com/documentation/google/#extra_params 107 | */ 108 | public function extraParams(array $extraParams): self 109 | { 110 | $this->params['extra_params'] = http_build_query($extraParams); 111 | 112 | return $this; 113 | } 114 | 115 | /** 116 | * https://www.scrapingbee.com/documentation/google/#add_html 117 | */ 118 | public function addHtml(): self 119 | { 120 | $this->params['add_html'] = true; 121 | 122 | return $this; 123 | } 124 | 125 | /* 126 | * If the API hasn't caught up and you need to support a new ScrapingBee parameter, 127 | * you can set it using this method. 128 | */ 129 | public function setParam(string $key, mixed $value): self 130 | { 131 | $this->params[$key] = $value; 132 | 133 | return $this; 134 | } 135 | 136 | private function reset(): self 137 | { 138 | $this->params = []; 139 | 140 | return $this; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/LaravelScrapingBeeServiceProvider.php: -------------------------------------------------------------------------------- 1 | name('laravel-scrapingbee') 21 | ->hasConfigFile(); 22 | } 23 | 24 | public function packageRegistered(): void 25 | { 26 | $this->app->bind('laravel-scrapingbee', LaravelScrapingBee::class); 27 | } 28 | } 29 | --------------------------------------------------------------------------------