利用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 相关文章推荐
ajax 的post方法实例(带循环)
Jul 04 PHP
基于php-fpm 参数的深入理解
Jun 03 PHP
使用配置类定义Codeigniter全局变量
Jun 12 PHP
php浏览历史记录的方法
Mar 10 PHP
php实现根据IP地址获取其所在省市的方法
Apr 30 PHP
php实现微信公众号无限群发
Oct 11 PHP
php微信浏览器分享设置以及回调详解
Aug 01 PHP
php 使用redis锁限制并发访问类示例
Nov 02 PHP
php中实现字符串翻转的方法
Feb 22 PHP
Thinkphp结合AJAX长轮询实现PC与APP推送详解
Jul 31 PHP
PHP如何实现订单的延时处理详解
Dec 30 PHP
thinkPHP5使用Rabc实现权限管理
Aug 28 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 和 MySQL 开发的 8 个技巧
2006/10/09 PHP
php下使用SMTP发邮件的代码
2008/01/10 PHP
PHP通过iconv将字符串从GBK转换为UTF8字符集
2011/07/18 PHP
PHP array_multisort() 函数的深入解析
2013/06/20 PHP
php 字符串中的\n换行符无效、不能换行的解决方法
2014/04/02 PHP
Tab页界面 用jQuery及Ajax技术实现(php后台)
2011/10/12 Javascript
js返回前一页刷新本页重载页面
2014/07/29 Javascript
js实现不提交表单获取单选按钮值的方法
2015/08/21 Javascript
限制只能输入数字的实现代码
2016/05/16 Javascript
javascript 中设置window.location.href跳转无效问题解决办法
2017/02/09 Javascript
使用vue和datatables进行表格的服务器端分页实例代码
2017/06/07 Javascript
使用jQuery实现购物车结算功能
2017/08/15 jQuery
微信小程序获取循环元素id以及wx.login登录操作
2017/08/17 Javascript
简单谈谈js的数据类型
2017/09/25 Javascript
JS中双击和单击事件冲突的解决方法
2018/04/09 Javascript
关于node-bindings无法在Electron中使用的解决办法
2018/12/18 Javascript
JS数组求和的常用方法实例小结
2019/01/07 Javascript
ES6的异步操作之promise用法和async函数的具体使用
2019/12/06 Javascript
JavaScript命令模式原理与用法实例详解
2020/03/10 Javascript
解决Echarts2竖直datazoom滑动后显示数据不全的问题
2020/07/20 Javascript
Javascript执行上下文顺序的深入讲解
2020/11/04 Javascript
[00:12]DAC2018 Miracle-站上中单舞台,他能否再写奇迹?
2018/04/06 DOTA
在python中的socket模块使用代理实例
2014/05/29 Python
Linux(Redhat)安装python3.6虚拟环境(推荐)
2018/05/05 Python
在OpenCV里实现条码区域识别的方法示例
2019/12/04 Python
IDLE下Python文件编辑和运行操作
2020/04/25 Python
详解HTML5 录音的踩坑之旅
2017/12/26 HTML / CSS
印度低票价航空公司:GoAir
2017/10/11 全球购物
Nebula美国官网:便携式投影仪
2019/03/15 全球购物
英国网上电器商店:Electricshop
2020/03/15 全球购物
写得不错的求职信范文
2014/07/11 职场文书
年度安全生产目标责任书
2014/07/23 职场文书
招商引资工作汇报材料
2014/10/28 职场文书
优秀学生干部事迹材料
2014/12/24 职场文书
关于Numpy之repeat、tile的用法总结
2021/06/02 Python
java项目构建Gradle的使用教程
2022/03/24 Java/Android