PHP は Tencent QQ Weibo API インターフェイスを使用して Weibo コンテンツのコードを取得します

WBOY
リリース: 2016-07-25 08:57:47
オリジナル
1220 人が閲覧しました
  1. /**

  2. * Tencent QQ Weibo API インターフェースを使用して Weibo コンテンツを取得します
  3. * by bbs.it-home.org
  4. */
  5. define('HDOM_TYPE_ELEMENT', 1);
  6. define('HDOM_TYPE_COMMENT', 2);
  7. define('HDOM_TYPE_TEXT', 3);
  8. define('HDOM_TYPE_ENDTAG', 4);
  9. define('HDOM_TYPE_ROOT', 5);
  10. define('HDOM_TYPE_UNKNOWN', 6);
  11. define('HDOM_QUOTE_DOUBLE', 0);
  12. define('HDOM_QUOTE_SINGLE', 1);
  13. define('HDOM_QUOTE_NO', 3);
  14. define('HDOM_INFO_BEGIN', 0);
  15. define('HDOM_INFO_END', 1);
  16. define('HDOM_INFO_QUOTE', 2);
  17. define('HDOM_INFO_SPACE', 3);
  18. define('HDOM_INFO_TEXT', 4);
  19. define('HDOM_INFO_INNER', 5);
  20. define('HDOM_INFO_OUTER', 6);
  21. define('HDOM_INFO_ENDSPACE',7);
  22. // ヘルパー関数
  23. / / ---------------
  24. // HTML dom フォーム ファイルを取得します
  25. function file_get_html() {
  26. $dom = new simple_html_dom;
  27. $args = func_get_args();
  28. $dom-> ;load(call_user_func_array('file_get_contents', $args), true);
  29. return $dom;
  30. }
  31. // HTML dom フォーム文字列を取得
  32. function str_get_html($str, $ lowercase=true) {
  33. $dom = new simple_html_dom ;
  34. $dom->load($str, $ lowercase);
  35. return $dom;
  36. }
  37. // HTML dom ツリーをダンプ
  38. function dump_html_tree($node, $show_attr=true, $deep=0) {
  39. $ lead = str_repeat(' ', $deep);
  40. echo $lead.$node->tag;
  41. if ($show_attr && count($node->attr)>0) {
  42. echo '(';
  43. foreach($node->attr as $k=>$v)
  44. echo "[$k]=>"".$node->$k.'", ';
  45. echo ')';
  46. }
  47. echo "n";
  48. foreach($node->nodes as $c)
  49. dump_html_tree($c, $show_attr, $deep+1);
  50. }
  51. // dom フォーム ファイルを取得 (非推奨)
  52. function file_get_dom () {
  53. $dom = new simple_html_dom;
  54. $args = func_get_args();
  55. $dom->load(call_user_func_array('file_get_contents', $args), true);
  56. return $dom;
  57. }
  58. // get dom 形式の文字列 (非推奨)
  59. function str_get_dom($str, $ lowercase=true) {
  60. $dom = new simple_html_dom;
  61. $dom->load($str, $ lowercase);
  62. return $dom;
  63. }
  64. / / simple html dom ノード
  65. // ---------------
  66. class simple_html_dom_node {
  67. public $nodetype = HDOM_TYPE_TEXT;
  68. public $tag = 'text';
  69. public $attr = array( );
  70. public $children = array();
  71. public $nodes = array();
  72. public $parent = null;
  73. public $_ = array();
  74. private $dom = null;
  75. function __construct($dom) {
  76. $this->dom = $dom;
  77. $dom->nodes[] = $this;
  78. }
  79. 関数 __destruct() {
  80. $this->clear();
  81. }
  82. 関数 __toString() {
  83. return $this->outertext();
  84. }
  85. // php5 の循環参照によるメモリ リークによるメモリのクリーンアップ...
  86. function clear() {
  87. $this->dom = null;
  88. $this- >nodes = null;
  89. $this->parent = null;
  90. $this->children = null;
  91. }

  92. // ノードのツリーをダンプします

  93. function dump($show_attr=true) {
  94. dump_html_tree($this, $show_attr);
  95. }
  96. // ノードの親を返します
  97. functionparent() {
  98. return $this->parent;
  99. }
  100. // ノード
  101. 関数の子を返しますchildren($idx=-1) {
  102. if ($idx===-1) return $this->children;
  103. if (isset($this->children [$idx])) return $this->children[$idx];
  104. return null;
  105. }
  106. // ノード
  107. の最初の子を返します function first_child() {
  108. if (count($this->children )>0) return $this->children[0];
  109. return null;
  110. }
  111. // ノード
  112. 関数の最後の子を返します last_child() {
  113. if (($count=count($this-> ;children))>0) return $this->children[$count-1];
  114. return null;
  115. }
  116. // ノードの次の兄弟を返します
  117. function next_sibling() {
  118. if ($this-> ;parent===null) null を返します;
  119. $idx = 0;
  120. $count = count($this->parent->children);
  121. while ($idx<$count && $this!==$this ->parent->children[$idx])
  122. ++$idx;
  123. if (++$idx>=$count) return null;
  124. return $this->parent->children[$idx] ;
  125. }
  126. // ノードの前の兄弟を返します
  127. function prev_sibling() {
  128. if ($this->parent===null) return null;
  129. $idx = 0;
  130. $count = count($this->parent ->children);
  131. while ($idx<$count && $this!==$this->parent->children[$idx])
  132. ++$idx;
  133. if (--$idx<0 ) return null;
  134. return $this->parent->children[$idx];
  135. }
  136. // dom ノードの内部 html
  137. 関数を取得します innertext() {
  138. if (isset($this->_[HDOM_INFO_INNER) ])) return $this->_[HDOM_INFO_INNER];
  139. if (isset($this->_[HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT] ]);
  140. $ret = '';
  141. foreach($this->nodes as $n)
  142. $ret .= $n->outertext();
  143. return $ret;
  144. }
  145. // domノードの取得外側のテキスト (タグ付き)
  146. function innertext() {
  147. if ($this->tag==='root') return $this->gt;innertext();
  148. // コールバックをトリガー
  149. if ($this-> ;dom->callback!==null)
  150. call_user_func_array($this->dom->callback, array($this));
  151. if (isset($this->>_[HDOM_INFO_OUTER])) return $ this->_[HDOM_INFO_OUTER];
  152. if (isset($this->>_[HDOM_INFO_TEXT])) return $this->>dom->restore_noise($this->>_[HDOM_INFO_TEXT]);
  153. / / 開始タグをレンダリングします
  154. $ret = $this->dom->nodes[$this->>_[HDOM_INFO_BEGIN]]->makeup();
  155. // 内部テキストをレンダリングします
  156. if (isset($this- >_[HDOM_INFO_INNER]))
  157. $ret .= $this->_[HDOM_INFO_INNER];
  158. else {
  159. foreach($this->nodes as $n)
  160. $ret .= $n->outertext ();
  161. }
  162. // 終了タグをレンダリングします
  163. if(isset($this->_[HDOM_INFO_END]) && $this->_[HDOM_INFO_END]!=0)
  164. $ret .= 'tag.'>';
  165. return $ret;
  166. }
  167. // domノードのプレーンテキストを取得
  168. function text() {
  169. if (isset($this->gt;_[HDOM_INFO_INNER])) return $this->_[HDOM_INFO_INNER];
  170. switch ($this->nodetype) {
  171. case HDOM_TYPE_TEXT: return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
  172. case HDOM_TYPE_COMMENT: return '';
  173. case HDOM_TYPE_UNKNOWN: return '';
  174. }
  175. if (strcasecmp($this->tag, 'script')===0) return '';
  176. if (strcasecmp($this- >tag, 'style')===0) return '';
  177. $ret = '';
  178. foreach($this->nodes as $n)
  179. $ret .= $n->text() ;
  180. return $ret;
  181. }

  182. function xmltext() {

  183. $ret = $this->innertext();
  184. $ret = str_ireplace(' $ret = str_replace(']]> ;', '', $ret);
  185. return $ret;
  186. }
  187. // タグを使用してノードのテキストを構築
  188. function makeup() {
  189. // テキスト、コメント、不明
  190. if (isset($this->_ [HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
  191. $ret = '<'.$this->tag;
  192. $i = -1 ;
  193. foreach($this->attr as $key=>$val) {
  194. ++$i;
  195. // 削除された属性をスキップ
  196. if ($val===null || $val===false)
  197. continue;
  198. $ret .= $this->_[HDOM_INFO_SPACE][$i][0];
  199. //値なし attr: nowrap、チェック済み、選択済み...
  200. if ($val===true)
  201. $ret .= $key;
  202. else {
  203. switch($this->_[HDOM_INFO_QUOTE][$i]) {
  204. case HDOM_QUOTE_DOUBLE: $quote = '"'; Break;
  205. case HDOM_QUOTE_SINGLE: $quote = '' '; Break;
  206. デフォルト: $quote = '';
  207. }
  208. $ret .= $key.$this->_[HDOM_INFO_SPACE][$i][1].'='.$this->_[HDOM_INFO_SPACE] ][$i][2].$quote.$val.$quote;
  209. }
  210. }
  211. $ret = $this->dom->restore_noise($ret);
  212. return $ret 。 $this->_[HDOM_INFO_ENDSPACE] 。 '>';
  213. }
  214. // CSS selector で要素を検索
  215. function find($selector, $idx=null) {
  216. $selector = $this->parse_selector($selector);
  217. if (($count=count($selector))= ==0) return array();
  218. $found_keys = array();
  219. // 各セレクター
  220. を検索します for ($c=0; $c if (($level= count($selectors[0]))===0) return array();
  221. if (!isset($this->_[HDOM_INFO_BEGIN])) return array();
  222. $head = array($this- >_[HDOM_INFO_BEGIN]=>1);
  223. // 子孫セレクターを処理します。再帰的ではありません!
  224. for ($l=0; $l $ret = array();
  225. foreach($head as $k=>$v) {
  226. $n = ($k===-1) ? $this->dom->root : $this->dom->nodes[$k];
  227. $n->seek($selectors[$c][$l], $ret);
  228. }
  229. $head = $ret;
  230. }
  231. foreach($head as $k=>$v) {
  232. if (!isset($found_keys[$k]))
  233. $found_keys[$k] = 1;
  234. }
  235. }
  236. // キーをソートします
  237. ksort($found_keys);
  238. $found = array();
  239. foreach($found_keys as $k=>$v)
  240. $found[] = $this->dom- >nodes[$k];
  241. // n 番目の要素または配列を返します
  242. if (is_null($idx)) return $found;
  243. else if ($idx return (isset($found[$idx])) ? $found[$idx] : null;
  244. }
  245. // 与えられた条件でシーク
  246. protected function look($selector, &$ret) {
  247. list($tag, $key, $val, $exp, $no_key) = $selector;
  248. // xpath インデックス
  249. if ($tag && $key && is_numeric($key)) {
  250. $count = 0;
  251. foreach ($this->children as $c) {
  252. if ($tag= =='*' || $tag===$c->tag) {
  253. if (++$count==$key) {
  254. $ret[$c->_[HDOM_INFO_BEGIN]] = 1;
  255. return;
  256. }
  257. }
  258. }
  259. return;
  260. }
  261. $end = (!empty($this->_[HDOM_INFO_END])) ? $this->_[HDOM_INFO_END] : 0;
  262. if ($end==0) {
  263. $parent = $this->parent;
  264. while (!isset($parent->_[HDOM_INFO_END]) && $parent!==null) {
  265. $end -= 1;
  266. $parent = $parent->parent;
  267. }
  268. $end += $parent->_[HDOM_INFO_END];
  269. }
  270. for($i =$this->_[HDOM_INFO_BEGIN]+1; $i $node = $this->dom->nodes[$i];
  271. $pass = true;
  272. if ($tag==='*' && !$key) {
  273. if (in_array($node, $this->children, true))
  274. $ret[$i] = 1;
  275. continue;
  276. }
  277. // タグ
  278. を比較 if ($tag && $tag!=$node->tag && $tag!=='*') {$pass=false;}
  279. // キー
  280. if ($pass && $ key) {
  281. if ($no_key) {
  282. if (isset($node->attr[$key])) $pass=false;
  283. }
  284. else if (!isset($node->attr[$key]) ])) $pass=false;
  285. }
  286. // 値を比較します
  287. if ($pass && $key && $val && $val!=='*') {
  288. $check = $this->match($exp , $val, $node->attr[$key]);
  289. // 複数のクラスを処理します
  290. if (!$check && strcasecmp($key, 'class')===0) {
  291. foreach(explode(' ',$node->attr[$key]) as $k) {
  292. $check = $this->match($exp, $val, $k);
  293. if ($check) Break;
  294. }
  295. }
  296. if (!$check) $pass = false;
  297. }
  298. if ($pass) $ret[$i] = 1;
  299. unset($node);
  300. }
  301. }
  302. protected function match($exp, $ pattern, $value) {
  303. switch ($exp) {
  304. case '=':
  305. return ($value===$pattern);
  306. case '!=':
  307. return ($value!==$pattern);
  308. case '^=':
  309. return preg_match("/^".preg_quote($pattern,'/')."/", $value);
  310. case '$=':
  311. return preg_match("/".preg_quote ($pattern,'/')."$/", $value);
  312. case '*=':
  313. if ($pattern[0]=='/')
  314. return preg_match($pattern, $value);
  315. return preg_match("/".$pattern."/i", $value);
  316. }
  317. return false;
  318. }
  319. protected function parse_selector($selector_string) {
  320. // mootools から変更された CSS セレクターのパターン
  321. $pattern = "/([w-:*]*)(?:#([w-]+)|.([ w-]+))?(?:[@?(!?[w-]+)(?:([!*^$]?=)["']?(.*?)["']? )?])?([/, ]+)/is";
  322. preg_match_all($pattern, トリム($selector_string).' ', $matches, PREG_SET_ORDER);
  323. $selector = array();
  324. $result = array ();
  325. //print_r($matches);
  326. foreach ($matches as $m) {
  327. $m[0] = トリム($m[0]);
  328. if ($m[0]===' ' || $m[0]==='/' || $m[0]==='//') continue;
  329. // ブラウザーが取得した xpath 用 if ($m[1]===' tbody') 続行;
  330. list($tag, $key, $val, $exp, $no_key) = array($m[1], null, null, '=', false);
  331. if(!empty($ m[2])) {$key='id'; $val=$m[2];}
  332. if(!empty($m[3])) {$key='クラス'; $val=$m[3];}
  333. if(!empty($m[4])) {$key=$m[4];}
  334. if(!empty($m[5])) {$exp =$m[5];}
  335. if(!empty($m[6])) {$val=$m[6];}
  336. // 小文字に変換
  337. if ($this->dom->小文字) {$tag=strto lower($tag); $key=strto lower($key);}
  338. //指定された属性を持たない要素
  339. if (isset($key[0]) && $key[0]==='!') {$key=substr ($key, 1); $no_key=true;}
  340. $result[] = array($tag, $key, $val, $exp, $no_key);
  341. if (trim($m[7])===',') {
  342. $selectors[] = $result;
  343. $result = array();
  344. }
  345. }
  346. if (count($result)>0)
  347. $selectors[] = $result;
  348. return $selectors;
  349. }
  350. 関数__get($name) {
  351. if (isset($this->attr[$name])) return $this->attr[$name];
  352. switch($name) {
  353. case 'outertext': return $ this->outertext();
  354. case 'innertext': return $this->innertext();
  355. case 'plaintext': return $this->text();
  356. case 'xmltext': return $this- >xmltext();
  357. デフォルト: return array_key_exists($name, $this->attr);
  358. }
  359. }
  360. function __set($name, $value) {
  361. switch($name) {
  362. case 'outertext' : return $this->_[HDOM_INFO_OUTER] = $value;
  363. case 'innertext':
  364. if (isset($this->>_[HDOM_INFO_TEXT])) return $this->_[HDOM_INFO_TEXT] = $value ;
  365. return $this->_[HDOM_INFO_INNER] = $value;
  366. }
  367. if (!isset($this->attr[$name])) {
  368. $this->_[HDOM_INFO_SPACE][] =配列(' '、 ''、 '');
  369. $this->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE;
  370. }
  371. $this->attr[$name] = $value;
  372. }
  373. function __isset($name) {
  374. switch($name) {
  375. case 'outertext': return true;
  376. case 'innertext': return true;
  377. case 'plaintext': return true;
  378. }
  379. //値なし attr: nowrap, selected selected...
  380. return (array_key_exists($name, $this->attr)) ? true : isset($this->attr[$name]);
  381. }
  382. function __unset($name) {
  383. if (isset($this->attr[$name]))
  384. unset($this-> ;attr[$name]);
  385. }
  386. // ラクダの命名規則
  387. function getAllAttributes() {return $this->attr;}
  388. function getAttribute($name) {return $this->gt;__get($name) ;}
  389. function setAttribute($name, $value) {$this->__set($name, $value);}
  390. function hasAttribute($name) {return $this->__isset($name);}
  391. function RemoveAttribute($name) {$this->__set($name, null);}
  392. function getElementById($id) {return $this->find("#$id", 0);}
  393. function getElementsById ($id, $idx=null) {return $this->find("#$id", $idx);}
  394. function getElementByTagName($name) {return $this->find($name, 0) ;}
  395. 関数 getElementsByTagName($name, $idx=null) {return $this->find($name, $idx);}
  396. 関数parentNode() {return $this->parent();}
  397. 関数childNodes($idx=-1) {return $this->children($idx);}
  398. function firstChild() {return $this->first_child();}
  399. function lastChild() {return $this-> ;last_child();}
  400. 関数 nextSibling() {return $this->next_sibling();}
  401. functionPreviousSibling() {return $this->prev_sibling();}
  402. }
  403. // 単純な HTML dom パーサー
  404. // -------------------------------------- -------------------------------------
  405. class simple_html_dom {
  406. public $root = null;
  407. public $nodes = array();
  408. public $callback = null;
  409. public $ lowercase = false;
  410. protected $pos;
  411. protected $doc;
  412. protected $char;
  413. protected $size;
  414. protected $cursor;
  415. protected $parent ;
  416. protected $noise = array();
  417. protected $token_blank = " trn";
  418. protected $token_equal = ' =/>';
  419. protected $token_slash = " />rnt";
  420. protected $token_attr = ' > ;';
  421. // in_array の代わりに isset を使用すると、パフォーマンスが約 30% 向上します...
  422. protected $self_closed_tags = array('img'=>1, 'br'=>1, 'input'=>1 、'meta'=>1、'link'=>1、'hr'=>1、'base'=>1、'embed'=>1、'spacer'=>1);
  423. protected $block_tags = array('root'=>1, 'body'=>1, 'form'=>1, 'div'=>1, 'span'=>1, 'table' =>1);
  424. protected $optional_closed_tags = array(
  425. 'tr'=>array('tr'=>1, 'td'=>1, 'th'=>1),
  426. 'th '=>array('th'=>1),
  427. 'td'=>array('td'=>1),
  428. 'li'=>array('li'=>1) ,
  429. 'dt'=>array('dt'=>1, 'dd'=>1),
  430. 'dd'=>array('dd'=>1, 'dt'=> 1)、
  431. 'dl'=>array('dd'=>1, 'dt'=>1)、
  432. 'p'=>array('p'=>1)、
  433. 'nobr '=>array('nobr'=>1),
  434. );
  435. function __construct($str=null) {
  436. if ($str) {
  437. if (preg_match("/^http:///i" ,$str) || is_file($str))
  438. $this->load_file($str);
  439. else
  440. $this->load($str);
  441. }
  442. }
  443. http://www.devdao.com/
  444. function __destruct() {
  445. $this->clear();
  446. }
  447. //文字列から HTML をロード
  448. function load($str, $ lowercase=true) {
  449. // prepare
  450. $this->prepare($str, $ lowercase);
  451. // コメントを削除します
  452. $this->remove_noise( "''is");
  453. // cdata を削除します
  454. $this->remove_noise("''is", true);
  455. //