【php】根据书名搜索对应封面的API服务

因为今年的webapp中有个功能需要根据书名搜索封面,但是市面上没有可用的开放API,于是只能自己撸一个了。

因为自己之前没有这方面的经历,同时也没有把这个服务做成怎么怎么高大上的打算。初衷就是一个开发快、查询快的单页面接口。

思路一:通过国家数字图书馆的接口

中国国家数字图书馆中国国家数字图书馆

中国国家数字图书馆 传送门

中国国家数字图书馆中包含了所有印刷出品书籍的副本(之前在“知网事件”中了解到),所以能不能通过调用抓包搜索接口来获取图片的封面呢?

经过测试是可行的,但是有2个缺点:

  1. 图片不能自定义尺寸,涉及到后期裁切API
  2. 国家的,风险很大

开发难度:★★★☆☆
开发速度:★★★☆☆
牢饭概率:★★☆☆☆

思路二:通过第三方的开放API平台

第三方的开放API平台第三方的开放API平台

试用了几家API提供商,大多是数据不全的。有些近年来很火的玄幻、言情、都市小说根本查不到。

思路三:通过聚合抓取知名小说站点的搜索结果

抓取流程图抓取流程图

遍历抓取知名小说网站的结果来获取封面。

这个方法存在的缺点是:

  1. 抓取频率大,浪费时间多
  2. 后期维护成本高,对应每一个网站都要单独写抓取规则
  3. 部分站点存在反爬虫机制,抓取难度大

开发难度:★★★★★
开发速度:★☆☆☆☆
牢饭概率:★★★☆☆

思路四:通过搜索引擎的结果来获取

搜索引擎的结果搜索引擎的结果

如某搜索引擎的第一条搜索结果会变成该小说的封面,且该图片url地址支持图片处理。即可通过url中的w和h参数来生成对应宽高的封面图,无需在代码中进行图片裁切操作。

使用该方法的好处是:

  1. 搜索引擎的线路好,查询速度快
  2. 支持url图片处理,无需再写图片裁切代码

开发难度:★☆☆☆☆
开发速度:★★★★★
牢饭概率:★☆☆☆☆

正式开工

出于某些安全原因考虑,代码就不开源了。这里只说一下几个开发要点

  1. 首先设置屏蔽错误和允许跨域
1
2
3
4
<?php
error_reporting(0);
header('Access-Control-Allow-Origin:*'); // *代表允许任何网址请求
header('Access-Control-Allow-Methods:POST,GET,OPTIONS,DELETE'); // 允许请求的类型
  1. 使用curl来做数据请求
1
2
3
4
5
6
7
8
9
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "要请求的URL");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
$data = curl_exec($curl); // data就是返回的页面结果
curl_close($curl);
  1. 使用DOMXPATH类,通过XPATH表达式读取数据
1
2
3
4
5
6
7
8
// 阻止因为页面元素不规范引起的报错
$libxml_previous_state = libxml_use_internal_errors(true);
$domInstance = new \DOMDocument();
$domInstance->loadHTML('<?xml encoding="UTF-8">' . '网页源代码');
// 阻止因为页面元素不规范引起的报错
libxml_clear_errors();
libxml_use_internal_errors($libxml_previous_state);
$XPath = new \DOMXPath($domInstance);

DOMXPath的用法可以看这里 传送门,主要用到的还是$XPath->query(‘XPath表达式’)。

然后遍历解析DOM元素的属性值,拿到图片url输出即可。

  1. 网络异常、IP被ban、获取数据失败时的错误处理

关键位置try{}catch($e){},最好设置一个默认返回值用于在异常时返回。

小结

代码量不多,50行左右就完成了一个查询封面服务。同时在代理IP池足够大的情况下完全可以保证高可用。


评论区