利用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.ini中文版(1)
Oct 09 PHP
PHP+.htaccess实现全站静态HTML文件GZIP压缩传输(一)
Feb 15 PHP
Ha0k 0.3 PHP 网页木马修改版
Oct 11 PHP
php下连接ftp实现文件的上传、下载、删除文件实例代码
Jun 03 PHP
zend framework框架中url大小写问题解决方法
Aug 19 PHP
php专用数组排序类ArraySortUtil用法实例
Apr 03 PHP
再Docker中架设完整的WordPress站点全攻略
Jul 29 PHP
JavaScript与HTML结合的基本使用方法整理
Oct 12 PHP
PHP微信公众号自动发送红包API
Jun 01 PHP
Thinkphp3.2.3整合phpqrcode生成带logo的二维码
Jul 21 PHP
深入学习微信网址链接解封的防封原理visit_type
Aug 15 PHP
PHP实现一个限制实例化次数的类示例
Sep 16 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/01/09 PHP
PHP实现视频文件上传完整实例
2014/08/28 PHP
PHP支付系统设计与典型案例分享
2016/08/02 PHP
解决PHP使用CURL发送GET请求时传递参数的问题
2019/10/11 PHP
thinkphp5 框架结合plupload实现图片批量上传功能示例
2020/04/04 PHP
基于逻辑运算的简单权限系统(实现) JS 版
2007/03/24 Javascript
用js替换除数字与逗号以外的所有字符的代码
2014/06/07 Javascript
推荐一个封装好的getElementsByClassName方法
2014/12/02 Javascript
node.js中的querystring.parse方法使用说明
2014/12/10 Javascript
js实现选中页面文字将其分享到新浪微博
2015/11/05 Javascript
Javascript实现图片轮播效果(二)图片序列节点的控制实现
2016/02/17 Javascript
Angularjs中ng-repeat-start与ng-repeat-end的用法实例介绍
2016/12/31 Javascript
Jqprint实现页面打印
2017/01/06 Javascript
AngularJS实现使用路由切换视图的方法
2017/01/24 Javascript
BootStrap table删除指定行的注意事项(笔记整理)
2017/02/05 Javascript
AngularJS动态绑定ng-options的ng-model实例代码
2017/06/21 Javascript
jQuery之动画ajax事件(实例讲解)
2017/07/18 jQuery
bootstrap插件treeview实现全选父节点下所有子节点和反选功能
2017/07/21 Javascript
ES6中的Promise代码详解
2017/10/09 Javascript
vue项目实现表单登录页保存账号和密码到cookie功能
2018/08/31 Javascript
Nodejs调用Dll模块的方法
2018/09/17 NodeJs
vue微信分享插件使用方法详解
2020/02/18 Javascript
Python 闭包的使用方法
2017/09/07 Python
简单实现Python爬取网络图片
2018/04/01 Python
Python图像处理之直线和曲线的拟合与绘制【curve_fit()应用】
2018/12/26 Python
对python以16进制打印字节数组的方法详解
2019/01/24 Python
Python中typing模块与类型注解的使用方法
2019/08/05 Python
matplotlib教程——强大的python作图工具库
2020/10/15 Python
MANGO官方网站:西班牙芒果服装品牌
2017/01/15 全球购物
英国最大线上综合鞋类商城:Office
2017/12/08 全球购物
中科软测试工程师面试题
2012/06/16 面试题
学校安全检查制度
2014/01/27 职场文书
实习计划书范文
2015/01/16 职场文书
2015年老干部工作总结
2015/04/23 职场文书
2016预备党员培训心得体会
2016/01/08 职场文书
无线电通信名词解释
2022/02/18 无线电