利用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的宝库目录--PEAR
Oct 09 PHP
用PHP开发GUI
Oct 09 PHP
用PHP查询域名状态whois的类
Nov 25 PHP
php结合表单实现一些简单功能的例子
Jun 04 PHP
php 多关键字 高亮显示实现代码
Apr 23 PHP
使用php记录用户通过搜索引擎进网站的关键词
Feb 13 PHP
举例详解PHP脚本的测试方法
Aug 05 PHP
PHP 中 Orientation 属性判断上传图片是否需要旋转
Oct 16 PHP
PHP文件系统管理(实例讲解)
Sep 19 PHP
用Laravel Sms实现laravel短信验证码的发送的实现
Nov 29 PHP
PHP join()函数用法与实例讲解
Mar 11 PHP
Laravel 5.5 实现禁用用户注册示例
Oct 24 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
解决MySQL中文输出变成问号的问题
2008/06/05 PHP
PHP基础之运算符的使用方法
2013/04/28 PHP
IIS+fastcgi下PHP运行超时问题的解决办法详解
2013/06/20 PHP
php jq jquery getJSON跨域提交数据完整版
2013/09/13 PHP
用JavaScript实现仿Windows关机效果
2007/03/10 Javascript
json 实例详细说明教程
2009/10/31 Javascript
关于COOKIE个数与大小的问题
2011/01/17 Javascript
JS求平均值的小例子
2013/11/29 Javascript
javascript模拟map输出与去除重复项的方法
2015/02/09 Javascript
JavaScript阻止浏览器返回按钮的方法
2015/03/18 Javascript
微信小程序开发经验总结(推荐)
2017/01/11 Javascript
Angular移动端页面input无法输入的解决方法
2017/11/14 Javascript
vue 设置proxyTable参数进行代理跨域
2018/04/09 Javascript
vue eslint简要配置教程详解
2019/07/26 Javascript
JavaScript交换变量常用4种方法解析
2020/09/02 Javascript
[00:32]2018DOTA2亚洲邀请赛Secret出场
2018/04/03 DOTA
[01:10:49]Secret vs VGJ.S 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
跟老齐学Python之复习if语句
2014/10/02 Python
Python os模块介绍
2014/11/30 Python
详解Python设计模式编程中观察者模式与策略模式的运用
2016/03/02 Python
python 编写简单网页服务器的实例
2018/06/01 Python
对python 多线程中的守护线程与join的用法详解
2019/02/18 Python
Python三元运算与lambda表达式实例解析
2019/11/30 Python
python3实现在二叉树中找出和为某一值的所有路径(推荐)
2019/12/26 Python
Python读取分割压缩TXT文本文件实例
2020/02/14 Python
解决python虚拟环境切换无效的问题
2020/04/30 Python
Python新手学习函数默认参数设置
2020/06/03 Python
葡萄牙鞋子品牌:Fair
2016/12/10 全球购物
大学生物业管理求职信
2013/10/24 职场文书
考试违纪检讨书
2014/02/02 职场文书
党委书记个人对照检查材料
2014/09/15 职场文书
个人四风问题原因分析及整改措施
2014/09/28 职场文书
报到证办理个人委托书
2014/10/06 职场文书
2014年体育教师工作总结
2014/12/03 职场文书
先进个人申报材料
2014/12/30 职场文书
numpy数据类型dtype转换实现
2021/04/24 Python