前几天老姐突然告诉我, 她在 JD 上买了本电子图书, 如何买完发现, 只能在线或者使用它自己的阅读器看, 很不方便, 让我给想想办法.
如何我就开始琢磨, 最开始, 我直接使用 Acrobat Reader 打开, 发现只有目录, 没有其他, 而且页面上面的都存在, 我想可能在正确的内容上增加了一块蒙版, 只能用 "钥匙" 的人可以过滤它, 要破解别人的编辑器, 短时间肯定是不行的的, 网上也有很多人想到的是使用自动化脚本去自动对官方阅读器截图, 但是我发现, 截图不是一页一页的, 这就很懵逼了. 最后只能通过在线阅读这条线来想办法.
这个办法和网友的类似, 都是保存为图片, 如何通过 pdf 工具制作成 pdf.
在线阅读惊奇发现, 文档真好, 一页一张图片, 它已经给你做好, 只是每次只更新出当前页的前后几张, 其他的会被清除. 到这里, 思路就有了:
跳转到第 n 页
拉取刷新出来的额图片路径
保存图片路径到缓存 (我使用的是 redis)
通过网络工具类, 将缓存中的图片地址全部下载到本地本次为图片
将图片通过 pdf 工作转为 pdf
第 1 步到第 3 步需要重复, 可以使用自动工具和脚本来实现.
第 4 步写个控制器就可以了, 最简单的 java 接口就行.
第 5 步直接网上在线服务就可以实现.
为什么需要先缓存在下载咧, 这里涉及到一个效率与图片去重和过滤的问题, 因为每次调整后获取的图片可能有重复的, 存在 redis 的 map 中, 自动就去重了; 也是为了避免一边获取图片路径, 一边下载中途异常退出等任务不能正常执行完毕等问题. 然后脚本获取路径, 后保存到自己的服务器, 唯一的问题可能就是跨域的问题. 结果发现还是少了几张图, 这样就体会出使用缓存的好处了, 可以直接通过代码验证少了那几张图, 不用去检查 jpg 文件, 少的文件个位数, 最后通过手动补全了.
通过这种方式得到的图片, 唯一缺陷就是带有 "JD 读书" 字样和图片分辨率不是很高, 字体好像带点毛脚. 有强迫症或者追求高品质的, 就使用官方阅读器吧, 个人看了蛮清晰的, 是文档, 不是图片!!!
下面附上 java 通过 URL 获取网络数据保存到本地的代码.
- public class HttpURLConnectionUtil {
- // 通过 get 请求得到读取器响应数据的数据流
- public static InputStream getInputStreamByGet(String url) {
- try {
- HttpURLConnection conn = (HttpURLConnection) new URL(url)
- .openConnection();
- conn.setReadTimeout(5000);
- conn.setConnectTimeout(5000);
- conn.setRequestMethod("GET");
- if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
- InputStream inputStream = conn.getInputStream();
- return inputStream;
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
- // 将服务器响应的数据流存到本地文件
- public static void saveData(InputStream is, File file) {
- try (BufferedInputStream bis = new BufferedInputStream(is);
- BufferedOutputStream bos = new BufferedOutputStream(
- new FileOutputStream(file));) {
- byte[] buffer = new byte[1024];
- int len = -1;
- while ((len = bis.read(buffer)) != -1) {
- bos.write(buffer, 0, len);
- bos.flush();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
调用:
- Set<String> imgNumber = (Set<String>) redisTemplate.opsForHash().keys(MAP_KEY);
- imgNumber.stream().forEach(e->{
- String url = (String) redisTemplate.opsForHash().get(MAP_KEY,e);
- String fileName = e+".jpg";
- File file = new File("E:\\pdf 图片 \\", fileName);
- InputStream inputStream = HttpURLConnectionUtil
- .getInputStreamByGet(url);
- HttpURLConnectionUtil.saveData(inputStream, file);
- });
此方法只适应已经购买了的电子书, 未购买的不适用. 建议还是到正规网站或书店购买, 支持正版, 尊重知识.
来源: http://blog.51cto.com/yuqian2203/2135284