ホームページ  >  記事  >  バックエンド開発  >  PHP を使用して Baidu Reading をクロールする方法の例

PHP を使用して Baidu Reading をクロールする方法の例

黄舟
黄舟オリジナル
2017-02-23 09:27:211878ブラウズ

はじめに

この記事では主に PHP を使用して Baidu Reading をキャプチャする方法を紹介します。以下ではあまり説明しません。

クローリング方法は以下の通りです

まずブラウザで閲覧ページを開き、ソースコードを確認すると、小説の内容がページに直接書かれていないことが分かります。非同期でロードされます。

そこで、Chrome の開発者ツールをネットワーク列に切り替え、閲覧ページを更新して、XHR とスクリプトの 2 つのカテゴリに焦点を当てました。

調査の結果、小説の内容に近い jsonp リクエストがあることが分かりました。リクエストされたアドレスは
http://www.php.cn/ です。
返されるのは

jsonp
です。アドレスの

callback=wenku7

を削除すると、返されるのは

json

文字列になります。これは解析が非常に便利で、PHP で配列に直接変換できます。


返されたデータの構造を分析してみましょう。返された

json

文字列の後には、t 属性と c 属性が続きます。t 属性は、このノードのラベルを示すために使用されます。 h2 p 待て、c 属性はコンテンツですが、2 つの可能性があります。1 つは文字列、もう 1 つは配列、そして配列の各要素はノードです。


この種の構造は分析するのに最適であり、1 回の再帰で実行できます


最終的なコードは次のとおりです:

<?php
class BaiduYuedu {
 protected $bookId;
 protected $bookToken;
 protected $cookie;
 protected $result;
 public function __construct($bookId, $bookToken, $cookie){
  $this->bookId = $bookId;
  $this->bookToken = $bookToken;
  $this->cookie = $cookie;
 }
 public static function parseNode($node){
  $str = &#39;&#39;;
  if(is_string($node[&#39;c&#39;])){
   $str .= $node[&#39;c&#39;];
  }else if(is_array($node[&#39;c&#39;])){
   foreach($node[&#39;c&#39;] as $d){
    $str .= self::parseNode($d);
   }
  }
  switch($node[&#39;t&#39;]){
   case &#39;h2&#39;:
    $str .= "\n\n";
    break;
   case &#39;br&#39;:
   case &#39;p&#39;:
   case &#39;p&#39;:
    $str .= "\n";
    break;
   case &#39;img&#39;:
   case &#39;span&#39;:
    break;
   case &#39;obj&#39;:
    $tmp = &#39;(&#39; . self::parseNode($node[&#39;data&#39;][0]) . &#39;)&#39;;
    $str .= str_replace("\n", &#39;&#39;, $tmp);
    break;
   default:
    trigger_error(&#39;Unkown type:&#39;.$node[&#39;t&#39;], E_USER_WARNING);
    break;
  }
  return $str;
 }
 public function get($page = 1){
  echo "getting page {$page}...\n";
  $ch = curl_init();
  $url = sprintf(&#39;http://wenku.baidu.com/content/%s/?m=%s&type=json&cn=%d&#39;, $this->bookId, $this->token, $page);
  curl_setopt_array($ch, array(
   CURLOPT_URL   => $url,
   CURLOPT_RETURNTRANSFER => 1,
   CURLOPT_HEADER   => 0,
   CURLOPT_HTTPHEADER  => array(&#39;Cookie: &#39;. $this->cookie)
  ));
  $ret = json_decode(curl_exec($ch), true);
  curl_close($ch);
  $str = &#39;&#39;;
  if(!empty($ret)){
   $str .= self::parseNode($ret);
   $str .= $this->get($page + 1);
  }
  return $str;
 }
 public function start(){
  $this->result = $this->get();
 }
 public function getResult(){
  return $this->result;
 }
 public function saveTo($path){
  if(empty($this->result)){
   trigger_error(&#39;Result is empty&#39;, E_USER_ERROR);
   return;
  }
  file_put_contents($path, $this->result);
  echo "save to {$path}\n";
 }
}
//使用示例
$yuedu = new BaiduYuedu(&#39;49422a3769eae009581becba&#39;, &#39;8ed1dedb240b11bf0731336eff95093f&#39;, &#39;你的百度域cookie&#39;);
$yuedu->start();
$yuedu->saveTo(&#39;result.txt&#39;);


このクラスの最初の 2 つのパラメーターは、導入部分から取得できます。小説のページでは、最初のパラメータ

bookId

は、

url

ebook

に続く文字列です。2番目のパラメータ

bookToken

は、ページのソースコード内で

bdjsonUrl

を検索します。 。

注:
Baidu

m
が渡されていないか、Baidu
cookie

が無効な場合、完全なコンテンツをキャプチャするには、

cookie

が正常に使用できることを確認する必要があります。

概要


上記は、PHP を使用して Baidu Reading をキャプチャする方法の例です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。


-->
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。