天天看點

Java|“ Java”來爬取小說章節

1 前提簡介

在上一篇Java|使用WebMagic進行電話爬取“的文章裡就已經介紹了如何主要使用Pageprocessor去爬取電話号碼,接下來将要學習到的是去爬取起點中文網的小說,并且按照小說名和章節分别儲存。

2 簡單檢視

下面就是需要去爬取的小說頁面以及内容,但儲存下來的檔案隻需要章節内容,像第一章的開頭就不需要,于是需要注意去判斷。

Java|“ Java”來爬取小說章節
圖2.1 起點中文網
Java|“ Java”來爬取小說章節
圖2.2 玄幻新書
Java|“ Java”來爬取小說章節
圖2.3 反派強無敵
Java|“ Java”來爬取小說章節

圖2.4 章節内容

3 代碼及注釋

話不多說,需要的解釋都以注釋的形式寫在代碼裡,下面就來看看詳細的代碼,值得注意的是内容的是xpath不要寫錯,否則可能會導緻失敗:

package com.yellow.java_pachong.book;

import us.codecraft.webmagic.Page;

import us.codecraft.webmagic.Site;

import us.codecraft.webmagic.Spider;

import us.codecraft.webmagic.processor.PageProcessor;

import  us.codecraft.webmagic.selector.Html;

import  us.codecraft.webmagic.selector.Selectable;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.PrintWriter;

import java.util.ArrayList;

import java.util.List;

/**

 *  爬取起點小說

 */

public class GetQidianBook implements  PageProcessor {

     //設定帶爬取檔案的相關配置

     private Site site = Site.me()

            .setCharset("utf-8")//設定字元集

            .setTimeOut(1000)//設定逾時時間

            .setSleepTime(1000);//設定休眠時間

     //書的名字

String bookName1 = "";

     @Override

     public Site getSite() {return site;}

     //爬取資料邏輯

     //第一級URL     https://www.qidian.com/xuanhuan     擷取書欄目錄

     //第二級    https://book.qidian.com/info/1019251979#Catalog    章節目錄

     //第三級    https://read.qidian.com/chapter/SaT8jsiJD54smgY_yC2imA2/oQbX6YtwB_NOBDFlr9quQA2    章節内容

     public void process(Page page) {

         //擷取URL

         Selectable table = page.getUrl();

         //System.out.println(table);

         //URL比對     用.{23}去代替字元比對,每個章節的字尾不一樣

         if  (table.regex("https://read.qidian.com/chapter/.{23}/.{23}").match())  {//文章章節頁面

            //擷取html頁面資訊

            Html html = page.getHtml();

             //列印html

            //System.out.println(html);

            //章節标題

            String title = "";

            //内容集合

            List<String> content = new  ArrayList<String>();

            //抓取有用資訊

            //判斷是否是第一章

            if  (html.xpath("/html/body/div[2]/div[3]/div[2]/div[1]/div[1]/div[1]/div[1]/h1/text()").toString()  != null) {//是第一章

                //擷取書名

                bookName1 =  html.xpath("/html/body/div[2]/div[3]/div[2]/div[1]/div[1]/div[1]/div[1]/h1/text()").toString();

                 //System.out.println(bookName);

                //擷取章節名

                title =  html.xpath("[@class='main-text-wrap']/div[1]/h3/span/text()").toString();

                //System.out.println(title);

                //擷取文章内容

                content =  html.xpath("[@class='main-text-wrap']/div[2]/p/text()").all();

            } else {//不是第一章

                title =  html.xpath("[@id='j_chapterBox']/div[1]/div[1]/div[1]/h3/span/text()").toString();

                 //擷取文章内容

                content =  html.xpath("[@id='j_chapterBox']/div[1]/div[1]/div[2]/p/text()").all();

            }

            //存到本地

            downBook(bookName1, title,  content);

         }else if(table.regex("https://book.qidian.com/info/\\d{10}#Catalog").match()){//書的章節目錄

            //擷取每一章節的位址,在章節目錄裡每一章的xpath

            List<String> url =  page.getHtml().xpath("[@class='volume-wrap']/div[1]/ul/li/a/@href").all();

            //加入待爬取序列

             page.addTargetRequests(url);

         }else{//一級url

            //擷取Html頁面

            //解析出每本書的url

            List<String> url =  html.xpath("[@id='new-book-list']/div/ul/li/div[2]/h4/a/@href").all();

            //拼接成完整的路徑

            List<String> url2 = new  ArrayList<String>();

            for (String string : url) {

                url2.add(string +  "#Catalog");

            page.addTargetRequests(url2);

         }

    }

     //将書存入本地

     private void downBook(String bookName2, String title,  List<String> content) {

         //判斷目錄存不存在

         File file = new File("D:/book.xuanhuan/" + bookName2);

         if(!file.exists()){

            //如果不存在目錄,則建立目錄

            file.mkdirs();

         PrintWriter pw = null; //使用IO流

         try {

            //存為txt檔案及其路徑

            FileOutputStream fos = new  FileOutputStream("D:/book.xuanhuan/" + bookName2 + "/" +  title + ".txt");

            pw = new PrintWriter(fos,true);

            for (String string : content) {

                pw.println(string);

            //爬完一章列印

            System.out.println(title + "  " + "爬取完畢");

         } catch (FileNotFoundException e) {

            e.printStackTrace();

         } finally {//關流

            pw.close();

     }

     //建立線程

     public static void main(String[] args) {//爬取了玄幻類的書

         Spider.create(new  GetQidianBook()).thread(1).addUrl("https://www.qidian.com/xuanhuan").run();

}

4結果展示

首先是控制台的的列印:

Java|“ Java”來爬取小說章節

圖4.1 控制台列印

然後是儲存檔案路徑:

Java|“ Java”來爬取小說章節

圖4.2 檔案路徑

最後是章節内容:

Java|“ Java”來爬取小說章節

圖4.3 章節内容

這樣就自動規整地爬取到了書籍。