利用PHP抓取百度阅读的方法示例

前言

这篇文章主要介绍的是,如何利用PHP抓取百度阅读的方法,下面话不多说,来一起看看吧。

抓取方法如下

首先在浏览器里打开阅读页面,查看源代码后发现小说的内容并不是直接写在页面里的,也就是说小说的内容是通过异步加载而来的。

于是将chrome的开发者工具切到network一栏,刷新阅读页面,主要关注的是XHR和script两个分类下。

经过排查,发现在script分类下有个jsonp请求比较像是小说内容,请求的地址是

http://wenku.baidu.com/content/49422a3769eae009581becba?m=8ed1dedb240b11bf0731336eff95093f&type=json&cn=1&_=1&t=1423309200&callback=wenku7

返回的是一个jsonp字符串,然后我发现,如果把地址里面的callback=wenku7去掉,返回的就是一个json字符串,这样解析起来就方便不少,可以直接在php里面转换成数组。

再来分析一下返回数据的结构,返回的json字符串之后是一个树状的结构,每个节点都有一个t属性和c属性,t属性用来指明这个节点的标签,比如h2 div等等,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 = '';
  if(is_string($node['c'])){
   $str .= $node['c'];
  }else if(is_array($node['c'])){
   foreach($node['c'] as $d){
    $str .= self::parseNode($d);
   }
  }
  switch($node['t']){
   case 'h2':
    $str .= "\n\n";
    break;
   case 'br':
   case 'div':
   case 'p':
    $str .= "\n";
    break;
   case 'img':
   case 'span':
    break;
   case 'obj':
    $tmp = '(' . self::parseNode($node['data'][0]) . ')';
    $str .= str_replace("\n", '', $tmp);
    break;
   default:
    trigger_error('Unkown type:'.$node['t'], E_USER_WARNING);
    break;
  }
  return $str;
 }
 public function get($page = 1){
  echo "getting page {$page}...\n";
  $ch = curl_init();
  $url = sprintf('http://wenku.baidu.com/content/%s/?m=%s&type=json&cn=%d', $this->bookId, $this->token, $page);
  curl_setopt_array($ch, array(
   CURLOPT_URL   => $url,
   CURLOPT_RETURNTRANSFER => 1,
   CURLOPT_HEADER   => 0,
   CURLOPT_HTTPHEADER  => array('Cookie: '. $this->cookie)
  ));
  $ret = json_decode(curl_exec($ch), true);
  curl_close($ch);
  $str = '';
  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('Result is empty', E_USER_ERROR);
   return;
  }
  file_put_contents($path, $this->result);
  echo "save to {$path}\n";
 }
}
//使用示例
$yuedu = new BaiduYuedu('49422a3769eae009581becba', '8ed1dedb240b11bf0731336eff95093f', '你的百度域cookie');
$yuedu->start();
$yuedu->saveTo('result.txt');

这个类前两个参数可以从小说的介绍页面获得,第一个参数bookId就是urlebook后面跟着的字符串,第二个参数bookToken在页面源代码搜索bdjsonUrlm参数后面的那个字符串就是。

注:如果不传入百度cookie或者百度cookie无效,则只能抓取免费阅读部分,要抓完整的内容必须保证cookie可以正常使用。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用PHP能有一定的帮助,如果有疑问大家可以留言交流。

(0)

相关推荐

  • PHP采集类Snoopy抓取图片实例

    用了两天php的Snoopy这个类,发现很好用.获取请求网页里面的所有链接,直接使用fetchlinks就可以,获取所有文本信息使用fetchtext(其内部还是使用正则表达式在进行处理),还有其它较多的功能,如模拟提交表单等. 使用方法: 先下载Snoopy类,下载地址:http://sourceforge.net/projects/snoopy/ 先实例化一个对象,然后调用相应的方法即可获取抓取的网页信息 复制代码 代码如下: include 'snoopy/Snoopy.class.php

  • PHP 超链接 抓取实现代码

    通用HTML标准超链接参数取得正则表达式测试 因为最近要做一个类似专业搜索引擎的东西,需要抓取网页的所有超链接. 大家帮忙测试一下子,下面的代码是否可以针对所有的标准超链接. 测试代码如下: 复制代码 代码如下: <?php // -------------------------------------------------------------------------- // File name : Noname1.php // Description : 通用链接参数获取正则表达式测试

  • php使用curl抓取qq空间的访客信息示例

    config.php 复制代码 代码如下: <?phpdefine('APP_DIR', dirname(__FILE__));define('COOKIE_FILE', APP_DIR . '/app.cookie.txt'); //会话记录文件define('VISITOR_CAPTURE_INTERVAL', 3); //QQ采集间隔define('VISITOR_DATA_UPLOAD_INTERVAL', '');define('THIS_TIME', time()); define(

  • PHP 抓取新浪读书频道的小说并生成txt电子书的代码

    复制代码 代码如下: /* Author: Yang Yu <yangyu@sina.cn> */ //想看什么电子书,先去新浪读书搜索,然后填入对应的参数即可 //http://vip.book.sina.com.cn/ //电子书参数 $array_book[0] = 38884; //小说id $array_book[1] = 22172; //章节起始id $array_book[2] = 32533; //章节结束id $array_book[3] = '中国特种部队生存实录:狼牙'

  • php抓取https的内容的代码

    直接用file_get_contents,会报错: 复制代码 代码如下: $url = (https://xxx.com"); file_get_contents($url); 错误: Warning: file_get_contents(https://xxx.com) [function.file-get-contents]: failed to open stream: No such file or directory in D:wampwwwgrabber_clientindex.ph

  • PHP多线程抓取网页实现代码

    受限于php语言本身不支持多线程,所以开发爬虫程序效率并不高,这时候往往需 要借助Curl Multi Functions 它可以实现并发多线程的访问多个url地址.既然 Curl Multi Function如此强大,能否用 Curl Multi Functions 来写并发多线程下载文件呢,当然可以,下面给出我的代码: 代码1:将获得的代码直接写入某个文件 复制代码 代码如下: <?php $urls = array( 'http://www.sina.com.cn/', 'http://w

  • PHP 抓取网页图片并且另存为的实现代码

    下面是源代码,及其相关解释 复制代码 代码如下: <?php //URL是远程的完整图片地址,不能为空, $filename 是另存为的图片名字 //默认把图片放在以此脚本相同的目录里 function GrabImage($url, $filename=""){ //$url 为空则返回 false; if($url == ""){return false;} $ext = strrchr($url, ".");//得到图片的扩展名 if

  • php抓取页面与代码解析 推荐

    得到数据我们不能直接输出,往往需要对内容进行提取,然后再进行格式化,以更加友好的方式显现出来.下面先简单说一下本文的主要内容: 一. PHP抓取页面的主要方法: 1. file()函数 2. file_get_contents()函数 3. fopen()->fread()->fclose()模式 4.curl方式 5. fsockopen()函数 socket模式 6. 使用插件(如:http://sourceforge.net/projects/snoopy/) 二.PHP解析html或x

  • php抓取页面的几种方法详解

    在 做一些天气预报或者RSS订阅的程序时,往往需要抓取非本地文件,一般情况下都是利用php模拟浏览器的访问,通过http请求访问url地址, 然后得到html源代码或者xml数据,得到数据我们不能直接输出,往往需要对内容进行提取,然后再进行格式化,以更加友好的方式显现出来.下面简单说一下php抓取页面的几种方法及原理:一. PHP抓取页面的主要方法:1. file()函数    2. file_get_contents()函数  3. fopen()->fread()->fclose()模式 

  • PHP中4种常用的抓取网络数据方法

    本小节的名称为 fsockopen,curl与file_get_contents,具体是探讨这三种方式进行网络数据输入输出的一些汇总.关于 fsockopen 前面已经谈了不少,下面开始转入其它.这里先简单罗列一下一些常见的抓取网络数据的一些方法. 1. 用 file_get_contents 以 get 方式获取内容: $url = 'http://localhost/test2.php'; $html = file_get_contents($url); echo $html; 2. 用fo

随机推荐