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

因CSDN版权问题,小说网站的URL、图片不可在此公布,读者根据自己想要爬取的网站,自行选择网站即可。

1.爬取小说章节内容,需要注意的大部分原创小说内容页是禁用右键的,无法直接选取页面内容进行元素检查,需要按F12,从上往下逐步选取元素。
2.利用IO流,将爬取的内容保存到本地文本文件。
本练习循序渐进,Demo1、首先爬取某一章节小说内容,Demo2、爬取完整一本小说内容,Demo3、爬取首页推荐榜中所有作品内容。
在项目中添加HttpClient、Jsoup依赖,参见本系列上两章。

Demo1:爬取某一章节小说内容

public static void main(String[] args) throws IOException {
    
    
    //小说第一章URL,因版权问题,url屏蔽,读者可自行选择
    String url = "https://xxx.xxxx.xxxx/xxxxx";
    Connection connect = Jsoup.connect(url);
    Document document = connect.get();
    //经F12分析,章节的标题、内容组合选择器如下所示
    Elements title = document.select("#j_chapterBox .text-wrap  .main-text-wrap .text-head h3 .content-wrap");
    Elements content = document.select("#j_chapterBox .text-wrap  .main-text-wrap .read-content p");
      //利用IO流将小说章节内容保存到本地
    FileWriter fw = new FileWriter("d:/test/abc.txt");
    fw.write(title.text() + "\r\n");
    for (Element e : content) {
    
    
        fw.write(e.text() + "\r\n");
    }
    fw.close();
}

Demo2、爬取完整一本小说内容

本Demo的思路是根据读取每章节的标题、内容,并读取“下一章”超链接中的href,以便发起网络请求爬取下一章内容。利用循环,即可实现自动爬取一本小说的内容。并爬取出本页面所显示的书名作为文件名。

这里注意,本Demo使用HttpClient做网络连接,Jsoup做内容解析,这是因为Jsoup虽然也可以进行网络连接,但是它存在的目的更是为了做HTML解析,它的网络连接方面的处理功能比之HTTPClient不可同日而语。在本Demo中,因为要不断的根据“下一章的”按钮,去发起新的网络请求,所以让适合的技术干适合的事情就势在必行了。

public static void main(String[] args) throws IOException {
    
    
  //小说第一章URL,因版权问题,url屏蔽,读者可自行选择
    String url = "https://xxx.xxxx.xxxx/xxxxx";;
    Document document = Jsoup.connect(url).get();
    Elements bookName = document.select("#j_textWrap .read-container .book-cover-wrap h1");
    //建立文件输出流,保存文本文件,以小说名作为文件名
    FileWriter fw = new FileWriter("d:/test/"+bookName.text()+".txt");
    //通过HttpClients工具类创建一个httpClient对象,该用来发起HTTP请求
    CloseableHttpClient httpClient = HttpClients.createDefault();
  while(true) {
    
    
      //创建一个“HTTP请求方法为Get”的一个对象
      HttpGet httpGet = new HttpGet(url);
      //通过httpClient发其Http请求,得到Http响应
      CloseableHttpResponse response = httpClient.execute(httpGet);
      //处理响应
      //如果响应状态码是200,表示访问的网页是正常的
      if (response.getStatusLine().getStatusCode() == 200) {
    
    
          //拿到响应内容
          HttpEntity entity = response.getEntity();
          //将内容转换成String
          String html = EntityUtils.toString(entity, "UTF-8");
          //由Jsoup解析由HttpClient获取的HTML文档
           document = Jsoup.parse(html);
          //Jsoup通过id、class、标签,解析HTML文档,拿到我们业务上想要的数据
          Elements title = document.select("#j_chapterBox .text-wrap .main-text-wrap .text-head h3 .content-wrap");
          Elements content = document.select("#j_chapterBox .text-wrap .main-text-wrap .read-content p");
          //解析“下一章”按钮,得到下一章的URL
          Elements next = document.select("#j_chapterNext");
          String href = next.attr("href");
          String prefix = "https:";
          url = prefix + href;        
          //如果爬取不到内容,说明本书已爬完最后一章,结束
          if(url.equals("https:")){
    
    
              break;
          }
          fw.write(title.text()+"\r\n");
          for (Element e : content) {
    
    
              fw.write(e.text()+"\r\n");
          }
      }
  }
    fw.close();
}

Demo3、爬取首页推荐榜中所有作品内容
本次爬取首页强推榜所有书籍。

点击强推榜单中的书籍超链接,会进入如下图所示的书籍首页。点击书籍的免费试读,可以进入到如Demo1、Demo2中的小说第一章的URL。

分析首页强推榜HTML代码、免费试读按钮代码,得出思路如下:
1.访问首页,解析强推榜中所有书籍
2.利用循环进入强推榜列表中所有书籍的主页
3.在书籍主页中,通过解析“免费试读”按钮,进入到第一章URL
4.根据Demo2中的读取完整一本小说内容,整合实现本Demo

代码如下:

    public static void main(String[] args) throws IOException {
    
    
        Document document = null;
        String prefix = "https:";
         //小说网站首页,url屏蔽,读者可自行选择
        String url = "https://xxx.xxxx.xxxx/";
        CloseableHttpClient httpClient = HttpClients.createDefault();
        //访问小说网首页
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpClient.execute(httpGet);
        if (response.getStatusLine().getStatusCode() == 200) {
    
    
            HttpEntity entity = response.getEntity();
            String html = EntityUtils.toString(entity, "UTF-8");
            document = Jsoup.parse(html);
            //解析推榜单,得到书籍标题和href
            Elements books = document.select(".wrap .index-two-wrap .book-list-wrap .book-list ul li strong a");
            for (Element book : books) {
    
    
                url = prefix + book.attr("href");
                //进入书籍主页
                httpGet = new HttpGet(url);
                response = httpClient.execute(httpGet);
                if (response.getStatusLine().getStatusCode() == 200) {
    
    
                    entity = response.getEntity();
                    html = EntityUtils.toString(entity, "UTF-8");
                    document = Jsoup.parse(html);
                    //解析书籍主页中的“免费阅读”按钮,得到书籍第一章的URL
                    url =prefix+ document.select("#readBtn").attr("href");
                    //根据强推榜中的书籍标题,通过IO流,为每一本小说创建文件名
                    FileWriter fw = new FileWriter("d:/test/" + book.text() + ".txt");
                    //循环读取每一章节的内容,并使用IO流存储到对应的文件中
                    while (true) {
    
    
                        httpGet = new HttpGet(url);
                        response = httpClient.execute(httpGet);
                        if (response.getStatusLine().getStatusCode() == 200) {
    
    
                            entity = response.getEntity();
                            //将内容转换成String
                            html = EntityUtils.toString(entity, "UTF-8");
                            document = Jsoup.parse(html);
                            Elements title = document.select("#j_chapterBox .text-wrap .main-text-wrap .text-head h3 .content-wrap");
                            Elements content = document.select("#j_chapterBox .text-wrap .main-text-wrap .read-content p");
                            Elements next = document.select("#j_chapterNext");
                            String href = next.attr("href");
                            url = prefix + href;
                            if (url.equals("https:")) {
    
    
                                break;
                            }
                            fw.write(title.text() + "\r\n");
                            for (Element e : content) {
    
    
                                fw.write(e.text() + "\r\n");
                            }
                        }
                    }
                    fw.close();
                }
            }
        }
    }```

おすすめ

転載: blog.csdn.net/GodBlessYouAndMe/article/details/120562037