上午刚入手的小说,下午心血来潮想从网站上拉取下来做成电子书,呵呵,瞎折腾~说做就做~

【抓包】

这一步比什么都重要,如果找不到获取真正资源的那个请求,就什么都不用做了~

先是打算用迅雷把所有页面都下载下来然后本地处理,结果发现保存下来的页面都只有界面没有内容~看了看Javascript的代码,原来是ready的时候再ajax发送post到另一个网址取内容。

于是再抓包核实一下。抓包工具真难搞,试了两三个都没成功,最后还是用firefox搞定了~打开页面共发送了50个请求,不过post只有两个,很快就看到http包的内容了。

【写程序拉取】

网址,请求的header,表单 都具备了,还等什么,赶紧码字爬取啦~本来还担心要伪装浏览器,要填入cookies内容,调试起来发现是想太多了,直奔网址带上表单就够了~

HttpClient的用法是现炒现卖,官方example的QuickStart.java就够很清晰了。再有就是debug进去看请求和响应。

用法见HttpPostcrawlOnePage(HttpRequestBase)。MyFileWriter就不贴出来献丑了,反正就是个I/O。

遇到并解决的问题:

1.响应回来的资源是gzip压缩过的,要用对应的类去解码;

2.网址序列号中个别缺页,通过判断响应里的状态码跳过即可。

(全文完,以下是代码。)

  1 package mycrawl;
  2
  3 import java.io.IOException;
  4 import java.util.ArrayList;
  5 import java.util.List;
  6
  7 import org.apache.http.HttpEntity;
  8 import org.apache.http.NameValuePair;
  9 import org.apache.http.client.ClientProtocolException;
 10 import org.apache.http.client.entity.GzipDecompressingEntity;
 11 import org.apache.http.client.entity.UrlEncodedFormEntity;
 12 import org.apache.http.client.methods.CloseableHttpResponse;
 13 import org.apache.http.client.methods.HttpPost;
 14 import org.apache.http.client.methods.HttpRequestBase;
 15 import org.apache.http.impl.client.CloseableHttpClient;
 16 import org.apache.http.impl.client.HttpClients;
 17 import org.apache.http.message.BasicNameValuePair;
 18 import org.apache.http.util.EntityUtils;
 19
 20 import crawl.common.MyFileWriter;
 21
 22 public class MyCrawl {
 23
 24     private static CloseableHttpClient httpclient = HttpClients.createDefault();
 25
 26     /**
 27      * (1)建立post对象,包括网址和表单 (2)循环抓取每页并处理输出
 28      *
 29      * @param args
 30      * @throws IOException
 31      */
 32     public static void main(String[] args) throws IOException {
 33         final int startChapter = 页面序列号;
 34         final int endChapter = 页面序列号; 35         final Integer bookId = bookid;
 36         String outPattern = "c:\\book*.txt";
 37         MyFileWriter fw = new MyFileWriter(outPattern);
 38
 39         // 创建post操作
 40         HttpPost httpPost = new HttpPost("网址");
 41         List<NameValuePair> nvps = new ArrayList<NameValuePair>(2);
 42
 43         try {
 44             // post的表单内容
 45             nvps.add(new BasicNameValuePair("b", bookId.toString()));
 46             nvps.add(new BasicNameValuePair("c", "placeholder"));
 47
 48             for (Integer i = startChapter, j = 0; i <= endChapter; i++, j++) {
 49                 // 循环抓取连续章节
 50                 nvps.set(1, new BasicNameValuePair("c", i.toString()));
 51                 httpPost.setEntity(new UrlEncodedFormEntity(nvps));
 52
 53                 String outStr = MyCrawl.crawlOnePage(httpPost);
 54                 if (outStr == null || outStr.isEmpty()) {
 55                     j--;
 56                     continue;
 57                 }
 58                 // 处理章节标题,懒得去抓取标题页了。
 59                 outStr = "====== " + MyCrawl.chapterArr[j] + "\r\n"
 60                         + MyCrawl.prettyTxt(outStr);
 61                 // System.out.println(outStr);
 62                 fw.rollingAppend(outStr);
 63             }
 64             fw.getFileWriter().flush();
 65             fw.getFileWriter().close();
 66             System.out.println("已完成");
 67
 68         } finally {
 69             httpclient.close();
 70         }
 71     }
 72
 73     /**
 74      * 抓取单页
 75      *
 76      * @param req
 77      * @return result
 78      * @throws ClientProtocolException
 79      * @throws IOException
 80      */
 81     public static String crawlOnePage(HttpRequestBase req)
 82             throws ClientProtocolException, IOException {
 83
 84         String result;
 85         CloseableHttpResponse resp = httpclient.execute(req);
 86
 87         // 处理返回码
 88         int status = resp.getStatusLine().getStatusCode();
 89         if (status < 200 || status >= 300) {
 90             System.out.println("[Error] " + resp.getStatusLine().toString());
 91             return "";
 92         } else if (status != 200) {
 93             System.out.println("[Warn] " + resp.getStatusLine().toString());
 94             return "";
 95         }
 96
 97         HttpEntity entity = resp.getEntity();
 98         if (entity instanceof GzipDecompressingEntity) {
 99             // 解压缩内容
100             GzipDecompressingEntity gEntity = (GzipDecompressingEntity) entity;
101             result = EntityUtils.toString(gEntity);
102         } else {
103             result = EntityUtils.toString(entity);
104         }
105
106         EntityUtils.consume(entity);
107         resp.close();
108         return result;
109     }
110
111     /**
112      * 处理换行等特殊字符
113      *
114      * @param txt
115      * @return string
116      */
117     public static String prettyTxt(String txt) {
118         if (txt == null || txt.isEmpty()) {
119             return "";
120         }
121         int contentStart = txt.indexOf("content") + 10;
122         int contentEnd = txt.indexOf("  <br/><br/>  \",\"next");
123         txt = txt.substring(contentStart, contentEnd);
124         return txt.replace("<br/><br/>", "\r\n");
125     }
126
127     // 章节标题
128     private static final String[] chapterArr = new String[] { "第一章",
129             "第二章" };
130
131 }

转载于:https://www.cnblogs.com/syjkfind/p/3578896.html

HttpClient拉取连载小说相关推荐

  1. 使用 requests+lxml 库的 Python 爬虫实例(以爬取网页连载小说《撒野》为例)

    需求目标 介绍使用 requests 库与 lxml 库进行简单的网页数据爬取普通框架与爬虫实例,本文以爬取网页连载小说<撒野>为例~ 当然有很多小说基本都能找到现成的 .txt 或者 . ...

  2. 《破碎的残阳,我们逆光》连载小说- HashMap剖析

    破碎的残阳,我们逆光[连载小说]- HashMap剖析 "行到水穷处,坐看云起时"        前言: 偶尔翻阅了自己当时高中时代写的日志,发现了几篇自己多年未打开的自写小说草本 ...

  3. 破碎的残阳,我们逆光【连载小说】- HashMap剖析

    破碎的残阳,我们逆光[连载小说]- HashMap剖析 "行到水穷处,坐看云起时"  前言: 偶尔翻阅了自己当时高中时代写的日志,发现了几篇自己多年未打开的自写小说草本,小说的名字 ...

  4. Python的scrapy之爬取顶点小说网的所有小说

    闲来无事用Python的scrapy框架练练手,爬取顶点小说网的所有小说的详细信息. 看一下网页的构造: tr标签里面的 td 使我们所要爬取的信息 下面是我们要爬取的二级页面 小说的简介信息: 下面 ...

  5. .NET Core 3.0中的WinForms创建集中式拉取请求中心

    Windows 窗体(或简称 WinForms),多年来被用于开发具有丰富和交互式界面的基于 Windows 的强大应用程序. 各类企业对这些桌面应用程序的投入量非常巨大,每月有大约 240 万开发人 ...

  6. Java网络爬虫(三)爬取网络小说

    因CSDN版权问题,小说网站的URL.图片不可在此公布,读者根据自己想要爬取的网站,自行选择网站即可. 1.爬取小说章节内容,需要注意的大部分原创小说内容页是禁用右键的,无法直接选取页面内容进行元素检 ...

  7. 基于Java的网络爬虫实现抓取网络小说(一)

    基于Java的网络爬虫实现抓取网络小说(一) 今天开始写点东西,一方面加深印象一方面再学习. 网络爬虫(Web crawler),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本,它们被广泛用 ...

  8. 用java从网上爬取大部头小说

     用java从网上爬取大部头小说 最近,我从网上看到零点看书(www.00ksw.com)网站分章连载了网络作家写的<大主宰>这部玄幻小说.截至目前,这部小说的最新章节已写到第一千三百 ...

  9. Java抓取起点小说输出到本地文件夹和数据库

    Java抓取起点小说输出到本地文件夹和数据库 目录 项目结构 所需插件 项目代码 输出结果 目录 项目结构 第一次写网络爬虫,参考了别人的,也自己理解了用法 所需插件 因为使用了mevan,直接上po ...

最新文章

  1. android 根目录缓存,Android系统中内部存储和外部存储(公有目录、私有目录、缓存目录)详解...
  2. 乒乓球比赛赛程_丁宁休战,刘诗雯做手术!李隼、秦志戬做介绍,国乒最新赛程曝光...
  3. vue+springboot图片上传,addResourceHandlers调用无效
  4. 农业走出去-国际农民丰收节贸易会·刘合光:走向全球思考
  5. tcga数据下载_TCGA数据下载(mRNA)
  6. 如何使用加密的Payload来识别并利用SQL注入漏洞
  7. linux amd64目录,创建基于amd64的qqforlinux的deb包
  8. 微信小程序使用 ocr 身份证识别
  9. 亚马逊成功的四个关键因素
  10. SQL server 还原数据库遇到正在使用的解决方法:
  11. 小米手机打开报告mimu查看程序调试错误locat
  12. 论如何用Python让你的同桌骂人...
  13. threejs特效:扫光shader
  14. 闲鱼,越分享才越有价值
  15. ODOO13 开发教程三 开始你的第一个模块
  16. 炫酷恶趣强大的制作神器小程序源码_支持多种流量主模式
  17. excel oss 上传_excel上传数据库失败
  18. 【电子】Baseband Signal and Passband Signal
  19. 输入一个有大写和小写的字符串,把其中的大写转化为小写,小写转化为大写。
  20. 【优雅编程之道】之注释的9点建议

热门文章

  1. 闷骚型的高级技术员写的SQL注入基础原理(超详细)
  2. SMIT快捷命令总结
  3. 万维网之父 65 岁创业,原因与你我都有关
  4. newbee-mall项目源码及部署
  5. 交易赋能,数字化助力渠道模式新升级 | 爱分析报告
  6. java7或java8新特性
  7. Java开发知识之Java的数字处理类Math类
  8. 压力变送器取压点如何选取
  9. python余弦定理求角_python实现的文本相似度算法(余弦定理)
  10. excel如何去除密码保护