利用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 404错误页面实现代码
Jun 22 PHP
PHP 进程锁定问题分析研究
Nov 24 PHP
php设置编码格式的方法
Mar 05 PHP
PHP中array_merge和array相加的区别分析
Jun 17 PHP
php inc文件使用的风险和注意事项
Nov 12 PHP
腾讯CMEM的PHP扩展编译安装方法
Sep 25 PHP
thinkPHP导出csv文件及用表格输出excel的方法
Dec 30 PHP
PHP编写学校网站上新生注册登陆程序的实例分享
Mar 21 PHP
PHP获取访问页面HTTP状态码的实现代码
Nov 03 PHP
PHP判断是否是微信打开,浏览器打开的方法
Mar 14 PHP
PHP大文件切割上传并带进度条功能示例
Jul 01 PHP
PHP中16个高危函数整理
Sep 19 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制作静态网站的模板框架(二)
2006/10/09 PHP
Smarty最简单实现列表奇偶变色的方法
2015/07/01 PHP
PHP简单实现DES加密解密的方法
2016/07/12 PHP
浅谈php和js中json的编码和解码
2016/10/24 PHP
Laravel 微信小程序后端搭建步骤详解
2019/11/26 PHP
JQuery Study Notes 学习笔记(一)
2010/08/04 Javascript
javascript中alert()与console.log()的区别
2015/08/26 Javascript
利用JS判断字符串是否含有数字与特殊字符的方法小结
2016/11/25 Javascript
巧用Javascript的逻辑运算符
2016/12/02 Javascript
D3.js中强制异步文件读取同步的几种方法
2017/02/06 Javascript
JS数组去重常用方法实例小结【4种方法】
2018/05/28 Javascript
vue debug 二种方法
2018/09/16 Javascript
JavaScript实现获取两个排序数组的中位数算法示例
2019/02/26 Javascript
Element-ui el-tree新增和删除节点后如何刷新tree的实例
2020/08/31 Javascript
[01:42]TI4西雅图DOTA2前线报道 第一顿早饭哦
2014/07/08 DOTA
[47:45]Liquid vs OG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python网络编程学习笔记(九):数据库客户端 DB-API
2014/06/09 Python
Python算法之栈(stack)的实现
2014/08/18 Python
python中assert用法实例分析
2015/04/30 Python
shell命令行,一键创建 python 模板文件脚本方法
2018/03/20 Python
python 列表删除所有指定元素的方法
2018/04/19 Python
Python简单处理坐标排序问题示例
2019/07/11 Python
Python实现的爬取豆瓣电影信息功能案例
2019/09/15 Python
如何实现更换Jupyter Notebook内核Python版本
2020/05/18 Python
python等待10秒执行下一命令的方法
2020/07/19 Python
python实现学生通讯录管理系统
2021/02/25 Python
AT&T Wireless:手机、无限数据计划和配件
2018/06/03 全球购物
真正的英国宝藏:Mappin & Webb
2019/05/05 全球购物
Fanatics法国官网:美国体育电商
2019/08/27 全球购物
学期自我评价
2014/01/27 职场文书
文化活动实施方案
2014/03/28 职场文书
办公楼租房协议书范本
2014/11/25 职场文书
大学生就业意向书
2015/05/11 职场文书
中国式结婚:司仪主持词(范文)
2019/07/25 职场文书
JavaScript的function函数详细介绍
2021/11/20 Javascript
Win11右下角图标点了没反应怎么办?Win11点击右下角图标无反应解决方法汇总
2022/07/07 数码科技