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


Posted in PHP onDecember 18, 2016

前言

这篇文章主要介绍的是,如何利用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能有一定的帮助,如果有疑问大家可以留言交流。

PHP 相关文章推荐
DedeCMS dede_channeltype表字段注释
Apr 07 PHP
探讨如何在php168_cms中提取验证码
Jun 08 PHP
php addslashes 利用递归实现使用反斜线引用字符串
Aug 05 PHP
php实现图片添加水印功能
Feb 13 PHP
thinkphp学习笔记之多表查询
Jul 28 PHP
php使用ereg验证文件上传的方法
Dec 16 PHP
PHP实现算式验证码和汉字验证码实例
Mar 09 PHP
php英文单词统计器
Jun 23 PHP
用PHP的socket实现客户端到服务端的通信实例详解
Feb 04 PHP
解决安装WampServer时提示缺少msvcr110.dll文件的问题
Jul 09 PHP
PHP使用PDO调用mssql存储过程的方法示例
Oct 07 PHP
PHP实现转盘抽奖算法分享
Apr 15 PHP
详解PHP数据压缩、加解密(pack, unpack)
Dec 17 #PHP
Yii2中datetime类的使用
Dec 17 #PHP
php生成二维码图片方法汇总
Dec 17 #PHP
PHP二维数组去重算法
Dec 17 #PHP
php格式化时间戳
Dec 17 #PHP
PHP生成唯一ID之SnowFlake算法
Dec 17 #PHP
简单解决微信文章图片防盗链问题
Dec 17 #PHP
You might like
PHP生成自适应大小的缩略图类及使用方法分享
2014/05/06 PHP
Linux平台PHP5.4设置FPM线程数量的方法
2016/11/09 PHP
yii2中LinkPager增加总页数和总记录数的实例
2017/08/28 PHP
区分JS中的undefined,null,&quot;&quot;,0和false
2007/03/08 Javascript
jQuery 对Select的操作备忘记录
2011/07/04 Javascript
深入理解JavaScript系列(8) S.O.L.I.D五大原则之里氏替换原则LSP
2012/01/15 Javascript
JavaScript中使用sencha gridpanel 编辑单元格、改变单元格颜色
2015/11/26 Javascript
JavaScript从数组的indexOf()深入之Object的Property机制
2016/05/11 Javascript
bootstrap flask登录页面编写实例
2016/11/01 Javascript
详解vue-Resource(与后端数据交互)
2017/01/16 Javascript
jquery实现放大镜简洁代码(推荐)
2017/06/08 jQuery
基于vue.js路由参数的实例讲解——简单易懂
2017/09/07 Javascript
js 客户端打印html 并且去掉页眉、页脚的实例
2017/11/03 Javascript
javascript显示动态时间的方法汇总
2018/07/06 Javascript
vue-cli3 配置开发与测试环境详解
2019/05/17 Javascript
JS sort排序详细使用方法示例解析
2020/09/27 Javascript
JS highcharts动态柱状图原理及实现
2020/10/16 Javascript
Express 配置HTML页面访问的实现
2020/11/01 Javascript
vant组件中 dialog的确认按钮的回调事件操作
2020/11/04 Javascript
深入理解javascript中的this
2021/02/08 Javascript
python快速排序代码实例
2013/11/21 Python
详解在Python中处理异常的教程
2015/05/24 Python
Python实现计算两个时间之间相差天数的方法
2017/05/10 Python
Python爬豆瓣电影实例
2018/02/23 Python
Python实现的合并两个有序数组算法示例
2019/03/04 Python
Python 异常处理Ⅳ过程图解
2019/10/18 Python
Python 爬虫实现增加播客访问量的方法实现
2019/10/31 Python
keras实现多GPU或指定GPU的使用介绍
2020/06/17 Python
CSS3支持IE6, 7, and 8的边框border属性
2012/12/28 HTML / CSS
HTML5 Canvas 实现K线图的示例代码
2019/12/23 HTML / CSS
小学生竞选班干部演讲稿(5篇)
2014/09/12 职场文书
无犯罪记录证明范本
2014/09/15 职场文书
违规违纪检讨书范文
2015/05/06 职场文书
2019年怎样才能撰写出优秀的自荐信
2019/03/25 职场文书
解决MySQL Varchar 类型尾部空格的问题
2022/04/06 MySQL
Redis中key的过期删除策略和内存淘汰机制
2022/04/12 Redis