1+ <?php
2+
3+ namespace shintio \yii2 \proxy \components ;
4+
5+ use shintio \yii2 \proxy \models \ProxyServer ;
6+ use shintio \yii2 \proxy \models \ProxyServerInterface ;
7+ use yii \helpers \ArrayHelper ;
8+ use yii \httpclient \Response ;
9+
10+ /**
11+ * Class ProxyParser
12+ * @package shintio\yii2\proxy\components
13+ *
14+ * @property ProxyServerInterface $proxyServerModel
15+ */
16+ class ProxyManager
17+ {
18+ public $ proxyServerModel = ProxyServer::class;
19+
20+ public $ client ;
21+
22+ public $ checkerUrl = 'https://ipleak.net/json/ ' ;
23+ public $ proxyLists = [
24+ [
25+ 'url ' => 'https://free-proxy-list.net/ ' ,
26+ 'container ' => 'table#proxylisttable ' ,
27+ 'ip ' => 0 ,
28+ 'port ' => 1 ,
29+ 'country ' => 3 ,
30+ ]
31+ ];
32+
33+ /**
34+ * @return integer
35+ */
36+ public function parseNewProxy ()
37+ {
38+ $ count = 0 ;
39+
40+ foreach ($ this ->proxyLists as $ proxyList ) {
41+ $ url = ArrayHelper::remove ($ proxyList , 'url ' );
42+ $ container = ArrayHelper::remove ($ proxyList , 'container ' );
43+
44+ $ client = $ this ->getClient ();
45+
46+ $ request = $ client ->createRequest ()->setMethod ('get ' )->setUrl ($ url );
47+
48+ $ response = $ request ->send ();
49+
50+ if ($ response ->isOk ) {
51+ $ document = \phpQuery::newDocumentHTML ($ response ->content );
52+
53+ $ proxies = [];
54+
55+ foreach ($ proxyList as $ key => $ attribute ) {
56+ foreach ($ document ->find ("$ container tr " ) as $ item ) {
57+ /** @var \DOMElement $item */
58+ if ($ item ->childNodes [$ proxyList ['ip ' ]]->tagName == 'td ' ) {
59+ ($ this ->proxyServerModel )::saveNew ($ item ->childNodes [$ proxyList ['ip ' ]]->nodeValue ,
60+ $ item ->childNodes [$ proxyList ['port ' ]]->nodeValue ,
61+ $ item ->childNodes [$ proxyList ['password ' ]]->nodeValue ?? null ,
62+ $ item ->childNodes [$ proxyList ['country ' ]]->nodeValue ?? null );
63+
64+ $ count ++;
65+ }
66+ }
67+ }
68+ }
69+ }
70+
71+ return $ count ;
72+ }
73+
74+ /**
75+ * @param ProxyServerInterface|null $proxy
76+ * @param integer $timeout
77+ *
78+ * @return ProxyServerInterface|boolean
79+ */
80+ public function checkProxy ($ proxy = null , $ timeout = 5 )
81+ {
82+ if (isset ($ proxy )) {
83+ return $ this ->sendCheckRequest ($ proxy , $ timeout );
84+ } else {
85+ do {
86+ $ proxy = ($ this ->proxyServerModel )::findNew ();
87+
88+ if (isset ($ proxy )) {
89+ $ proxy = $ this ->sendCheckRequest ($ proxy , $ timeout );
90+ } else {
91+ return false ;
92+ }
93+ } while (empty ($ proxy ));
94+
95+ return $ proxy ;
96+ }
97+ }
98+
99+ public function getClient ()
100+ {
101+ return $ this ->client ?? new \yii \httpclient \Client ();
102+ }
103+
104+ /**
105+ * @param bool $check
106+ * @param integer $timeout
107+ *
108+ * @return ProxyServerInterface
109+ */
110+ public function getProxy ($ check = true , $ timeout = 5 )
111+ {
112+ $ proxy = ($ this ->proxyServerModel )::findActive ();
113+
114+ return $ check ? $ this ->checkProxy ($ proxy , $ timeout ) : $ proxy ;
115+ }
116+
117+ /**
118+ * @param bool $check
119+ * @param integer $timeout
120+ *
121+ * @return string|boolean
122+ */
123+ public function getProxyString ($ check = true , $ timeout = 5 )
124+ {
125+ $ proxy = $ this ->getProxy ($ check , $ timeout );
126+
127+ return $ proxy ? $ this ->formatProxyString ($ proxy ) : false ;
128+ }
129+
130+ /**
131+ * @param ProxyServerInterface $proxy
132+ *
133+ * @return string
134+ */
135+ public function formatProxyString ($ proxy )
136+ {
137+ return 'tcp:// ' . $ proxy ->getIp () . ': ' . $ proxy ->getPort ();
138+ }
139+
140+ /**
141+ * @param ProxyServerInterface $proxy
142+ * @param integer $timeout
143+ *
144+ * @return ProxyServerInterface|boolean
145+ */
146+ protected function sendCheckRequest ($ proxy , $ timeout = 5 )
147+ {
148+ $ client = $ this ->getClient ();
149+
150+ $ request = $ client ->createRequest ()->setMethod ('get ' )->setOptions ([
151+ 'proxy ' => $ this ->formatProxyString ($ proxy ),
152+ 'timeout ' => $ timeout
153+ ])->setUrl ($ this ->checkerUrl );
154+
155+ try {
156+ $ response = $ request ->send ();
157+
158+ if ($ response ->isOk ) {
159+ $ ip = $ this ->getCheckedIp ($ response );
160+
161+ if ($ ip == $ proxy ->getIp ()) {
162+ $ proxy ->setActive ();
163+
164+ return $ proxy ;
165+ }
166+ }
167+ } catch (\Exception $ exception ) {
168+
169+ }
170+
171+ $ proxy ->setUnActive ();
172+
173+ return false ;
174+ }
175+
176+ /**
177+ * @param Response $response
178+ *
179+ * @return string
180+ */
181+ protected function getCheckedIp ($ response )
182+ {
183+ $ json = $ response ->data ;
184+
185+ return $ json ['ip ' ];
186+ }
187+ }
0 commit comments