采用QueryList实现图书馆图书与豆瓣评分信息整合
笔者经常去本地的淄博图书馆借阅图书,该图书馆的藏书并不是很丰富,并不是大部分的书都能找到,一般都是有啥书就翻翻是不是合适再借阅,之前就想如果能在检索的时候显示豆瓣的评分,优先选择评价好的经典图书会比较好,图书馆官网并没有这样的功能,于是就有了下面的代码。
该代码基于thinkphp5+php7下运行,采用querylist采集组件,确实强大方便,并利用组件自带的从LARAVEL抽离的集合扩展tightenco/collect进行按评分的倒序显示.
<?php
namespace app\index\controller;
use app\common\controller\Common;
use QL\QueryList;
class Book extends Common{
public function index()
{
set_time_limit(0);
$apikey = "0df993c66c0c636e29ecbb5344252a4a";
$doubanurl = "https://api.douban.com/v2/book/isbn/";
if(input('?keyword'))
{
$keyword = input('keyword');
$url = "http://222.134.129.122:458/opac/search?searchWay=title&q=" . $keyword . "&view=&searchSource=reader&booktype=&scWay=dim&marcformat=&sortWay=score&sortOrder=desc&startPubdate=&endPubdate=&rows=100&hasholding=1&curlocal=";
//获取并按采集规则返回数据
$rules = [
'title' => ['.title-link','text','span'],
'isbn' => ['.bookcover_img','isbn'],
'num' => ['.bookmeta>div>span:eq(1)','text'],
'callno' => ['.callnosSpan','text'],
// 'holding' => ['.expressServiceTab>ul>li:eq(0)>a','text']
];
//切片选择器
$range = '.resultTable>tr';
//echo $url;die();
$ql = QueryList::get($url)->rules($rules)->range($range)->query();
//匿名回调处理豆瓣信息
$data = $ql->getData(function ($item) use ($apikey,$doubanurl) {
$douban = QueryList::get($doubanurl . $item['isbn'] . '?apikey=' . $apikey)->getHtml();
$doubanObj = json_decode($douban);
if($doubanObj){
$item['rating'] = $doubanObj->rating->average;
$item['author'] = $doubanObj->author;
$item['pubdate'] = $doubanObj->pubdate;
$item['image'] = $doubanObj->image;
$item['publisher'] = $doubanObj->publisher;
$item['doubanurl'] = $doubanObj->alt;
}
sleep(5);
return $item;
});
//dump($data->all());
$sorted = $data->sortByDesc('rating');
return json($sorted->all());
}
else
{
$this->error("请输入关键词");
}
}
}
细节调整、容错版
<?php
namespace app\index\controller;
use app\common\controller\Common;
use QL\QueryList;
use GuzzleHttp\Exception\RequestException;
class Book extends Common{
public function index()
{
set_time_limit(0);
$apikey = "0df993c66c0c636e29ecbb5344252a4a";
$doubanurl = "https://api.douban.com/v2/book/isbn/";
if(input('?keyword'))
{
$keyword = input('keyword');
$url = "http://222.134.129.122:458/opac/search?searchWay=title&q=" . $keyword . "&view=&searchSource=reader&booktype=&scWay=dim&marcformat=&sortWay=score&sortOrder=desc&startPubdate=&endPubdate=&rows=100&hasholding=1&curlocal=";
//获取并按采集规则返回数据
$rules = [
'title' => ['.title-link','text','span'],
'isbn' => ['.bookcover_img','isbn'],
'num' => ['.bookmeta>div>span:eq(1)','text'],
'callno' => ['.callnosSpan','text'],
// 'holding' => ['.expressServiceTab>ul>li:eq(0)>a','text']
];
//切片选择器
$range = '.resultTable>tr';
//echo $url;die();
//忽略错误
$ql1 = QueryList::getInstance();
//注册一个myGet方法到QueryList对象
$ql1->bind('myGet',function ($url,$args = null,$otherArgs = []){
try{
$this->get($url,$args,$otherArgs);
}catch(RequestException $e){
$this->setHtml('');
// print_r($e->getRequest());
echo "Http Error \r\n";
}
return $this;
});
$ql = QueryList::get($url)->rules($rules)->range($range)->query();
//匿名回调处理豆瓣信息
$data = $ql->getData(function ($item) use ($apikey,$doubanurl,$ql1) {
//初始数据
$item['image'] = "http://222.134.129.122:458/opac/media/images/book-default-small.gif";
$item['rating'] = '0';
$item['author'] = '';
$item['pubdate'] = '';
$item['image'] = '';
$item['publisher'] = '';
$item['doubanurl'] = '';
//有isbn
if($item['isbn']) {
try {
//忽略信息
$douban = $ql1->myGet($doubanurl . $item['isbn'] . '?apikey=' . $apikey)->getHtml();
$doubanObj = json_decode($douban);
if ($doubanObj && !isset($doubanObj->msg)) {
$item['rating'] = $doubanObj->rating->average;
$item['author'] = $doubanObj->author;
$item['pubdate'] = $doubanObj->pubdate;
$item['image'] = $doubanObj->image;
$item['publisher'] = $doubanObj->publisher;
$item['doubanurl'] = $doubanObj->alt;
}
}
catch (RequestException $e){
//echo 'Http Error';
}
}
sleep(5);
return $item;
});
//dump($data->all());
$sorted = $data->sortByDesc('rating');
//return json($sorted->all());
$this->assign('keyword',$keyword);
$this->assign('books',$sorted->all());
return $this->fetch(); // 渲染模板
}
else
{
$this->assign('books',[]);
$this->assign('keyword','');
return $this->fetch(); // 渲染模板
}
}
}