>백엔드 개발 >PHP 튜토리얼 >PHP를 사용하여 Baidu Reading을 크롤링하는 방법의 예

PHP를 사용하여 Baidu Reading을 크롤링하는 방법의 예

黄舟
黄舟원래의
2017-02-23 09:27:211920검색

머리말

이번 글은 주로 PHP를 활용한 바이두리딩 캡처 방법을 소개합니다.

크롤링 방법은 다음과 같습니다

먼저 브라우저에서 독서 페이지를 열어서 소스코드를 확인하여 소설의 내용이 직접 쓰여져 있지 않은지 확인하세요. 즉, 소설의 내용이 비동기적으로 로드된다고 합니다.

그래서 Chrome의 개발자 도구를 네트워크 열로 전환하고 읽기 페이지를 새로 고치고 XHR과 스크립트의 두 가지 범주에 집중했습니다.

조사 결과 스크립트 카테고리에 소설 내용과 유사한 jsonp 요청이 있는 것으로 확인되었습니다. 요청한 주소는
http://www.php.cn/ 응답은

jsonp

문자열이었고, 주소에서

callback=wenku7

를 제거하면 반환되는 것은

json

문자열이라는 것을 알았습니다. 구문 분석하기가 훨씬 더 편리하며 PHP에서 배열로 직접 변환할 수 있습니다.


반환된 데이터의 구조를 분석해 보겠습니다. 반환된

json

문자열 뒤에는 트리와 같은 구조가 있습니다. 각 노드에는 t 속성이 있음을 나타냅니다. h2 p 등과 같은 이 노드의 레이블, c 속성은 내용이지만 두 가지 가능성이 있습니다. 하나는 문자열이고 다른 하나는 배열이며 배열의 각 요소는 노드입니다.


이런 종류의 구조는 파싱하기에 가장 좋으며, 한 번의 재귀로 수행할 수 있습니다


최종 코드는 다음과 같습니다.

<?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;);


이 클래스의 처음 두 매개변수는 소설의 소개 페이지에서 얻을 수 있습니다. 첫 번째 매개변수

bookId

url

ebook

에서 두 번째 매개변수

bookToken

는 페이지 소스 코드의

bdjsonUrl

를 검색하고

m

매개변수 뒤의 문자열은 다음과 같습니다. .


참고:
Baidu

cookie
가 전달되지 않거나 Baidu

cookie

가 유효하지 않은 경우 무료 읽기 부분만 캡처할 수 있으며, 완전한 것을 캡쳐해야 합니다. 콘텐츠는

cookie

가 정상적으로 사용될 수 있도록 보장되어야 합니다.


요약


위는 PHP를 사용하여 바이두리딩을 캡쳐하는 방법의 예시입니다. PHP 중국어 홈페이지(www.php.cn)!


PHP를 사용하여 Baidu Reading을 크롤링하는 방법의 예
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.