利用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+MySQL的聊天室设计
Oct 09 PHP
php数组函数序列之in_array() 查找数组值是否存在
Oct 29 PHP
PHP高自定义性安全验证码代码
Nov 27 PHP
web目录下不应该存在多余的程序(安全考虑)
May 09 PHP
ThinkPHP 连接Oracle数据库的详细教程[全]
Jul 16 PHP
PHP连接MongoDB示例代码
Sep 06 PHP
php动态函数调用方法
May 21 PHP
PHP的Socket网络编程入门指引
Aug 11 PHP
详解ThinkPHP3.2.3验证码显示、刷新、校验
Dec 29 PHP
详解php用curl调用接口方法,get和post两种方式
Jan 13 PHP
ThinkPHP5框架缓存查询操作分析
May 30 PHP
PHP 观察者模式深入理解与应用分析
Sep 25 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
ThinkPHP3.1查询语言详解
2014/06/19 PHP
php常用字符串String函数实例总结【转换,替换,计算,截取,加密】
2016/12/07 PHP
关于PHP求解三数之和问题详析
2020/11/09 PHP
javascript显示选择目录对话框的代码
2008/11/10 Javascript
javascript之学会吝啬 精简代码
2010/04/25 Javascript
关于Ext中form移除textfield方法:hide(),setVisible(false),remove()
2010/12/02 Javascript
[原创]推荐10款最热门jQuery UI框架
2014/08/19 Javascript
JS通过Cookie判断页面是否为首次打开
2016/02/05 Javascript
jQuery操作属性和样式详解
2016/04/13 Javascript
BootStrap使用popover插件实现鼠标经过显示并保持显示框
2016/06/23 Javascript
基于js实现的限制文本框只可以输入数字
2016/12/05 Javascript
仿淘宝JSsearch搜索下拉深度用法
2018/01/15 Javascript
[45:46]2014 DOTA2国际邀请赛中国区预选赛5.21 HGT VS DT
2014/05/23 DOTA
[02:04]完美世界城市挑战赛秋季赛报名开始 谁是solo路人王?
2019/10/10 DOTA
基于python实现的抓取腾讯视频所有电影的爬虫
2016/04/22 Python
深入理解Django的中间件middleware
2018/03/14 Python
python奇偶行分开存储实现代码
2018/03/19 Python
python pycurl验证basic和digest认证的方法
2018/05/02 Python
WxPython建立批量录入框窗口
2019/02/27 Python
python操作文件的参数整理
2019/06/11 Python
python爬虫 基于requests模块的get请求实现详解
2019/08/20 Python
django配置app中的静态文件步骤
2020/03/27 Python
python 使用raw socket进行TCP SYN扫描实例
2020/05/05 Python
python3获取控制台输入的数据的具体实例
2020/08/16 Python
HTML5 常用语法一览(列举不支持的属性)
2010/01/26 HTML / CSS
卫校毕业生自我鉴定
2013/10/31 职场文书
工商企业管理应届生求职信
2013/11/03 职场文书
运动会表扬稿大全
2014/01/16 职场文书
文秘应届生求职信
2014/07/05 职场文书
旅游活动总结
2014/08/27 职场文书
党员个人总结范文
2015/02/14 职场文书
党员承诺书范文2015
2015/04/27 职场文书
费用申请报告范文
2015/05/15 职场文书
初中班长竞选稿
2015/11/20 职场文书
2016年“世界气象日”广播稿
2015/12/17 职场文书
Django cookie和session的应用场景及如何使用
2021/04/29 Python