unique / proxy-switcher
提供使用 Guzzle 的代理切换传输
Requires
- php: ^7.4
- guzzlehttp/guzzle: ^7.0
Requires (Dev)
- lstrojny/phpunit-function-mocker: *
- phpunit/phpunit: ^9.4
- unique/events: ^1.0.0
README
一个用于使用代理进行 HTTP 请求的组件。允许轻松地在不同的代理服务器之间切换。
安装
此组件需要 php >= 7.4。要安装它,您可以使用 composer
composer require unique/proxyswitcher
用法
无代理
您可以使用此组件而不使用代理。
<?php $transport = new \unique\proxyswitcher\Transport( [ // any public attributes for the component... ] );
单个代理
或者,您可以指定一个用于所有请求的单个代理。
<?php $transport = new \unique\proxyswitcher\Transport(); $transport->setProxyList( new \unique\proxyswitcher\SingleProxyList( [ 'username' => 'user', 'password' => 'pass', 'address' => 'my.proxy.com' ] ) );
多个代理和切换
每当您需要有一个可用代理列表并在请求一定次数后或代理被阻止/不工作时切换它们,您可以使用 ArrayProxyList
。
<?php $transport = new \unique\proxyswitcher\Transport(); $transport->setProxyList( new \unique\proxyswitcher\ArrayProxyList( [ 'username' => 'user', 'password' => 'pass', 'transports' => [ 'my1.proxy.com:80', 'my2.proxy.com:80', 'my3.proxy.com:80', ] ] ) );
当您使用 ArrayProxyList
时,您可以使用 Transport::$switch_transport_min
和 Transport::$switch_transport_max
来指定在强制更改代理之前需要执行的请求数量。代理将按照提供的顺序选择。如果代理失败,它将被标记为失败,并将切换到下一个。如果代理失败 ArrayProxyList::$max_transport_fails
次(默认 3)它将被标记为无效,将不会重试。
您还可以指定 Transport::$next_timeout_min
和 Transport::$next_timeout_max
来随机化请求次数,之后将执行超时。超时的长度可以通过使用 Transport::$sleep_time_min
和 Transport::$sleep_time_max
来指定,它设置超时的最小和最大秒数。
传递参数到 GuzzleHttp 或选择另一个客户端
尽管此组件已被设计为使用 GuzzleHttp\Client 类进行请求,但在理论上,您可以选择使用任何实现了 request() 方法的对象。您可以通过将 client_options
属性传递给 Transport 构造函数来实现这一点。
new \unique\proxyswitcher\Transport( [ 'client_options' => [ 'class' => \My\Client\Class::class, ], ] );
您还可以将其他属性传递给客户端的构造函数
new \unique\proxyswitcher\Transport( [ 'client_options' => [ 'class' => \GuzzleHttp\Client::class, 'verify' => false ], ] );
如果没有指定 class
属性,则默认使用 \GuzzleHttp\Client
。
您甚至可以传递一个客户端对象而不是它的配置
$client = new \GuzzleHttp\Client( [ 'verify' => false ] ); new \unique\proxyswitcher\Transport( [ 'client_options' => $client, ] );
发送请求
底层组件使用 GuzzleHttp 进行请求,因此您可以将您通常作为第三个参数传递的任何选项传递。
然而,一些选项:connect_timeout
和 proxy
是根据 Transport 对象的属性自动设置的。
Cookie
头是从 Transport::$cookie
中获取的
// Make a GET request: $response = $transport->request( \unique\proxyswitcher\Transport::REQUEST_GET, 'https://www.google.com?query=hello+world' ); // ...or a POST request: $response = $transport->request( \unique\proxyswitcher\Transport::REQUEST_POST, 'https://www.google.com', [ 'form_params' => [ 'query' => 'hello world!' ] ] );
有关使用 GuzzleHttp 发送请求的更多信息,请参阅:docs.guzzlephp.org
创建自己的代理列表组件
如果您需要执行比基本切换更多的逻辑,您可以通过扩展 AbstractProxyList
来编写自己的 ProxyList 类。如果您有一个在数据库中的列表并希望跟踪服务器,这可能很有用。
文档
Transport 属性
int $next_timeout_min = 2000
和 int $next_timeout_max = 5000
在随机数量的请求(最小/最大范围内)之后将执行超时。为了关闭此功能,将 $sleep_time_min
和 $sleep_time_max
设置为零。
int $sleep_time_min = 2 * 60
和 int $sleep_time_max = 5 * 60
达到超时后睡眠的秒数。实际睡眠的秒数将在此范围内随机化。如果不需要超时,可以设置为零。
int $switch_transport_min = 400
和 int $switch_transport_max = 800
代理切换之间的最小和最大请求数。如果两者都设置为 null,则代理只有在失败时才会切换。
int|null $max_proxies_in_a_row = null
指定在放弃并抛出异常之前,可以尝试多少个代理。这可以用作安全措施,以便在指定数量的请求失败后,假设存在问题(例如,网络连接失败、地址错误等)。
int $connect_timeout = 1
每个请求的默认连接超时时间。可以通过传递选项到 Transport::request()
方法来覆盖。
int $timeout_after_request = 1
指定在每次成功请求后等待的秒数,以防止洪泛。
string $cookie = ''
用于请求的cookie字符串。
SingleProxyList|ArrayProxyList|array|null $proxy_list
如果指定,将使用对象来控制代理切换。在 Transport
对象的构造期间只能传递 array
,以便自动构建 proxy_list
对象。在这种情况下,array
需要包含一个 ['class']
键。
Transport 方法
setProxyList( AbstractProxyList $proxy_list )
设置提供的代理列表。
getProxyList(): AbstractProxyList
返回分配的代理列表对象。
request( string $method, $url, array $options = [] ): ResponseInterface
向url发送请求,使用提供的请求方法GET/POST。如果在对象构建期间提供了 proxy_list
对象或使用 setProxyList()
方法,将应用相应的代理切换逻辑。
string $method
- "GET" 或 "POST"。string $url
- 请求的url。array $options = []
-GuzzleHttp\Client::request()
的选项。有关使用 GuzzleHttp 发送请求的更多信息,请参阅:docs.guzzlephp.org
static getInstance( $config = [] ): Transport
返回 Transport 类的静态实例。
array $config = []
- Transport 类的任何公共属性值。仅在第一次调用时初始化。(可能需要重构...)
setLogger( \Closure $logger )
设置用于传输和 proxy_list 的日志记录函数。日志记录函数将接收一个字符串参数,其中包含需要记录的文本。
\Closure $logger
- 将接收两个参数:( string $text, bool $is_error )
on( string $event, $callback )
为指定的事件类型设置新的处理程序。
string $event
- 事件名称,Transport 常量之一:EVENT_AFTER_RESPONSE
或EVENT_TOO_MANY_REQUESTS
。\Closure|array $callback
- 事件处理程序。将接收一个参数:( EventObjectInterface $event )
trigger( string $event_name, EventObjectInterface $event )
触发指定的事件。首先分配的处理程序将被调用。如果它没有设置 EventObjectInterface::setHandled()
,则调用第二个处理程序,依此类推,直到所有处理程序都被调用或设置了 setHandled( true )
。
string $event_name
- 事件名称,Transport 常量之一:EVENT_AFTER_RESPONSE
或EVENT_TOO_MANY_REQUESTS
。EventObjectInterface $event
- 事件对象
off( string $event, $callback = null )
从对象中删除事件处理程序。如果没有提供处理程序,则删除所有处理程序。
string $event
- 事件名称,Transport 常量之一:EVENT_AFTER_RESPONSE
或EVENT_TOO_MANY_REQUESTS
。\Closure|array|null $callback
- 使用on()
分配的事件处理程序。
使用事件
此组件具有一个非常简单的具有两个定义事件的系统。
AfterResponseEvent
- 在成功请求后触发。TooManyRequestsEvent
- 在收到 HTTP 429 响应后触发。
您可以通过调用 Transport::on()
方法来订阅事件。例如,将 TooManyRequestsEvent
事件设置为已处理,可以通过在传递的事件对象上调用 setHandled( true )
实现,这样当前代理就不会失败,组件会尝试继续使用它。
许可协议
本项目遵循MIT许可协议。
软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定目的和非侵权性保证。在任何情况下,作者或版权所有者不应对任何索赔、损害或其他责任负责,无论这些责任是由于合同、侵权或其他方式引起的,以及与软件的使用或其他交易有关。