初步定的方案用 python,因為IO讀寫方便,結合xpath,后來搭了環境,發現好多都忘記了,需要復習,所有最后決定用java,結合jsoup,htmlUtil等。
關于 jsoup ,可以看我的博客:Jsoup學習文檔
搗鼓了一晚上,折騰到凌晨3、4點多,終于爬了下來。原本想一個頁面下載小說的多個類型,后來發現做不到,一段代碼并行跑的。
爬取小說的網站
設計到技術點:
需要模擬下載按鈕的點擊,還有之后彈出的確認框的按鈕點擊。這里的思路是調用兩次按鈕點擊事件對應方法,第一次click返回page,獲取按鈕Element在調用一次返回的page直接輸出為IO,
按鈕的多次點擊之間,頁面會通過js動態生成Element。如果兩次點擊事件串行觸發,可能需要的Element數據沒有加載出來,獲取不到第二次的按鈕元素。報NullPointException。這個處理是讓線程sleep了一秒。確保js加載的Element可以加載出來。
當前代碼同一個頁面不支持多次按鈕點擊下載,如果因為在一次下載完無法獲取到當前頁面了,所以不能并行操作,解決辦法現在還沒想到,小伙伴可以留言idea。
剩下的需要注意一些版本依賴問題。
默認的處理異常邏輯為,當前小說下載出現異常會直接跳過。
代碼沒有處理,需要優化的可以自行處理下
依賴
4.0.0 com.liruilon spider 1.0-SNAPSHOT org.apache.httpcomponents httpclient 4.5.7 org.jsoup jsoup 1.11.3 com.fasterxml.jackson.core jackson-databind 2.9.8 org.mozilla rhino 1.7.10 net.sourceforge.htmlunit htmlunit 2.33 junit junit 4.12 test org.slf4j slf4j-api 1.7.25 org.slf4j slf4j-log4j12 1.7.25 commons-beanutils commons-beanutils 1.9.4 commons-io commons-io 2.5 com.google.guava guava 18.0
import com.gargoylesoftware.htmlunit.Page; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.html.DomElement; import com.gargoylesoftware.htmlunit.html.HtmlPage; import com.google.common.collect.ImmutableMap; import com.google.common.io.Files; import org.apache.commons.io.FileUtils; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.*; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import java.util.stream.Collectors; import static org.apache.commons.io.IOUtils.copyLarge; /** * @Description : * @Author: Liruilong * @Date: 2020/10/13 21:15 */ public class Test { static Logger logger = Logger.getLogger(Test.class.getCanonicalName()); static ExecutorService executorService = Executors.newFixedThreadPool(20); static final Map mapTextStyle = ImmutableMap.of( // "下載 updb 檔", "updb" // "下載 prc 檔", "prc" "下載直式 mobi 檔", "mobi" //"下載 epub 檔", "epub" ); /** * @param args * @return * @description * @author Liruilong * @date 2020年10月15日 03:10:12 **/ public static void main(String[] args) { String[] strings = new String[]{"http://www.haodoo.net/?M=hd&P=100", "http://www.haodoo.net/?M=hd&P=wisdom", "http://www.haodoo.net/?M=hd&P=history", "http://www.haodoo.net/?M=hd&P=martial", "http://www.haodoo.net/?M=hd&P=mystery", "http://www.haodoo.net/?M=hd&P=scifi", "http://www.haodoo.net/?M=hd&P=romance", "http://www.haodoo.net/?M=hd&P=fiction"}; for (int j = 0; j < strings.length; j++) { try { Document doc = null; doc = Jsoup.connect(strings[j]).get(); Elements s = doc.select("a[href]"); logger.info("爬取:" + strings[j] + "__________---------——————————————" + Thread.currentThread().getName()); List elements = s.stream().filter(a -> a.attr("abs:href").indexOf("book") != -1 && a.text().length() > 1) .collect(Collectors.toList()); executorService.execute(() -> { for (int i = 0; i < elements.size(); i++) { try { WebClient webclient = new WebClient(); logger.info("爬取:" + elements.get(i).text() + "__________---------——————————————" + Thread.currentThread().getName()); HtmlPage htmlpage = null; htmlpage = webclient.getPage(elements.get(i).attr("abs:href")); List domElements = htmlpage.getElementsByTagName("input").stream().filter(o -> mapTextStyle.containsKey(o.getAttribute("value"))).collect(Collectors.toList()); for (int i1 = 0; i1 < domElements.size(); i1++) { try { String textNameStyle = mapTextStyle.get(domElements.get(i1).getAttribute("value")); logger.info("爬取:" + elements.get(i).text() + "___" + textNameStyle + "_______---------——————————————" + Thread.currentThread().getName()); HtmlPage page = domElements.get(i1).click(); TimeUnit.SECONDS.sleep(1); DomElement button = page.getElementById("okButton"); if (Objects.isNull(button)) { TimeUnit.SECONDS.sleep(1); } final InputStream inputStream = button.click().getWebResponse().getContentAsStream(); saveFile(inputStream, elements.get(i).text(), textNameStyle); } catch (Exception e) { continue; } } webclient.close();//關掉 } catch (IOException e) { continue; } } }); } catch (IOException e) { e.printStackTrace(); } } } /** * @param io * @param s * @return 文件保存 * @description * @author Liruilong * @date 2020年10月15日 00:10:06 **/ public static void saveFile(InputStream io, String... s) { executorService.execute(() -> { logger.info("-----------------------------------------------------------------------導入開始:" + s[0] + "__________---------——————————————" + Thread.currentThread().getName()); try (OutputStream outputStream = new FileOutputStream(new File("G:\codedemo\src\main\" + s[0] .replaceAll("【", "").replaceAll("】", "") .replaceAll("《", "").replaceAll("》", "") + "." + s[1]));) { copyLarge(io, outputStream); outputStream.flush(); logger.info("-------------------------------------------------------------------------導入結束:" + s[0] + "__________---------——————————————" + Thread.currentThread().getName()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }); } }

Java 爬蟲
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。