利用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 相关文章推荐
PHP操作XML作为数据库的类
Dec 19 PHP
让PHP以ROOT权限执行系统命令的方法
Feb 10 PHP
PHP性能优化准备篇图解PEAR安装
Dec 05 PHP
ThinkPHP3.1新特性之对Ajax的支持更加完善
Jun 19 PHP
PHP实现检测客户端是否使用代理服务器及其匿名级别
Jan 07 PHP
thinkphp3.2.3 分页代码分享
Jul 28 PHP
PHP7新特性foreach 修改示例介绍
Aug 26 PHP
PHP抽象类基本用法示例
Dec 28 PHP
Laravel路由研究之domain解决多域名问题的方法示例
Apr 04 PHP
php7下的filesize函数
Sep 30 PHP
Laravel 读取 config 下的数据方法
Oct 13 PHP
PHP接口类(interface)的定义、特点和应用示例
May 18 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五种设计模式小结
2011/03/23 PHP
深入探讨:Nginx 502 Bad Gateway错误的解决方法
2013/06/03 PHP
javascript 数组学习资料收集
2010/04/11 Javascript
jQuery Ajax 实例全解析
2011/04/20 Javascript
常用的JQuery函数及功能小结
2016/03/24 Javascript
省市选择的简单实现(基于zepto.js)
2016/06/21 Javascript
浅谈JS验证表单文本域输入空格的问题
2017/02/14 Javascript
解决OneThink中无法异步提交kindeditor文本框中修改后的内容方法
2017/05/05 Javascript
Node.js安装配置图文教程
2017/05/10 Javascript
基于Vue的文字跑马灯组件(npm 组件包)
2017/05/24 Javascript
JS实现简易换图时钟功能分析
2018/01/04 Javascript
vue-star评星组件开发实例
2018/03/01 Javascript
vue 1.0 结合animate.css定义动画效果
2018/07/11 Javascript
vue项目中,main.js,App.vue,index.html的调用方法
2018/09/20 Javascript
JS二级菜单不同实现方法分析【4种方法】
2018/12/21 Javascript
Vue2.0实现组件之间数据交互和通信操作示例
2019/05/16 Javascript
JavaScript中callee和caller的区别与用法实例分析
2019/06/28 Javascript
小程序自定义导航栏兼容适配所有机型(附完整案例)
2020/04/26 Javascript
JS常见内存泄漏及解决方案解析
2020/05/30 Javascript
Postman无法正常返回结果问题解决
2020/08/28 Javascript
JavaScript代码实现简单计算器
2020/12/27 Javascript
使用python编写android截屏脚本双击运行即可
2014/07/21 Python
python 中的list和array的不同之处及转换问题
2018/03/13 Python
python实现随机漫步算法
2018/08/27 Python
Python 绘制酷炫的三维图步骤详解
2019/07/12 Python
django的ORM操作 删除和编辑实现详解
2019/07/24 Python
对Pytorch中nn.ModuleList 和 nn.Sequential详解
2019/08/18 Python
分享一个页面平滑滚动小技巧(推荐)
2019/10/23 HTML / CSS
HTML5拖拽API经典实例详解
2018/04/20 HTML / CSS
捷克多品牌在线时尚商店:ANSWEAR.cz
2020/10/03 全球购物
初中班主任寄语
2014/04/04 职场文书
募捐倡议书
2014/04/14 职场文书
中学生社区服务活动报告
2015/02/05 职场文书
python中sys模块的介绍与实例
2021/04/17 Python
MYSQL 运算符总结
2021/11/11 MySQL
一次项目中Thinkphp绕过禁用函数的实战记录
2021/11/17 PHP