網絡爬蟲(又被稱爲網頁蜘蛛,網絡機器人,在FOAF社區中間,更常常的稱爲網頁追逐者),是一種按照必定的規則,自動地抓取萬維網信息的程序或者腳本。另一些不常使用的名字還有螞蟻、自動索引、模擬程序或者蠕蟲。css
有人抓取,就會有人想要防護。網絡爬蟲在運行過程當中也會遇到反爬蟲策略。常見的有:html
這些只是傳統的反爬蟲手段,隨着AI時代的到來,也會有更先進的手段的到來。java
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; public class Reptile { public static void main(String[] args) { // 傳入你所要爬取的頁面地址 String url1 = "http://www.xxxx.com.cn/"; // 建立輸入流用於讀取流 InputStream is = null; // 包裝流, 加快讀取速度 BufferedReader br = null; // 用來保存讀取頁面的數據. StringBuffer html = new StringBuffer(); // 建立臨時字符串用於保存每一次讀的一行數據,而後 html 調用 append 方法寫入 temp; String temp = ""; try { // 獲取 URL; URL url2 = new URL(url1); // 打開流,準備開始讀取數據; is = url2.openStream(); // 將流包裝成字符流,調用 br.readLine() 能夠提升讀取效率,每次讀取一行; br = new BufferedReader(new InputStreamReader(is)); // 讀取數據, 調用 br.readLine() 方法每次讀取一行數據, 並賦值給 temp, 若是沒數據則值 ==null, // 跳出循環; while ((temp = br.readLine()) != null) { // 將 temp 的值追加給 html, 這裏注意的時 String 跟 StringBuffer // 的區別前者不是可變的後者是可變的; html.append(temp); } // 接下來是關閉流, 防止資源的浪費; if (is != null) { is.close(); is = null; } // 經過 Jsoup 解析頁面, 生成一個 document 對象; Document doc = Jsoup.parse(html.toString()); // 經過 class 的名字獲得(即 XX), 一個數組對象 Elements 裏面有咱們想要的數據, 至於這個 div的值,打開瀏覽器按下 F12 就知道了; Elements elements = doc.getElementsByClass("xx"); for (Element element : elements) { // 打印出每個節點的信息; 選擇性的保留想要的數據, 通常都是獲取個固定的索引; System.out.println(element.text()); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
示例分析:node
設計框架的目的就是將這些流程統一化,將通用的功能進行抽象,減小重複工做。設計網絡爬蟲框架須要哪些組件呢?web
爬蟲框架要處理不少的 URL,咱們須要設計一個隊列存儲全部要處理的 URL,這種先進先出的數據結構很是符合這個需求。 將全部要下載的 URL 存儲在待處理隊列中,每次下載會取出一個,隊列中就會少一個。咱們知道有些 URL 的下載會有反爬蟲策略, 因此針對這些請求須要作一些特殊的設置,進而能夠對 URL 進行封裝抽出 Request。正則表達式
若是沒有網頁下載器,用戶就要編寫網絡請求的處理代碼,這無疑對每一個 URL 都是相同的動做。 因此在框架設計中咱們直接加入它就行了,至於使用什麼庫來進行下載都是能夠的,你能夠用 httpclient 也能夠用 okhttp, 在本文中咱們使用一個超輕量級的網絡請求庫 oh-my-request (沒錯,就是在下搞的)。 優秀的框架設計會將這個下載組件置爲可替換,提供默認的便可。數據庫
調度器和咱們在開發 web 應用中的控制器是一個相似的概念,它用於在下載器、解析器之間作流轉處理。 解析器能夠解析到更多的 URL 發送給調度器,調度器再次的傳輸給下載器,這樣就會讓各個組件有條不紊的進行工做。數組
咱們知道當一個頁面下載完成後就是一段 HTML 的 DOM 字符串表示,但還須要提取出真正須要的數據, 之前的作法是經過 String 的 API 或者正則表達式的方式在 DOM 中搜尋,這樣是很麻煩的,框架 應該提供一種合理、經常使用、方便的方式來幫助用戶完成提取數據這件事兒。經常使用的手段是經過 xpath 或者 css 選擇器從 DOM 中進行提取,並且學習這項技能在幾乎全部的爬蟲框架中都是適用的。瀏覽器
普通的爬蟲程序中是把 網頁解析器 和 數據處理器 合在一塊兒的,解析到數據後立刻處理。 在一個標準化的爬蟲程序中,他們應該是各司其職的,咱們先經過解析器將須要的數據解析出來,多是封裝成對象。 而後傳遞給數據處理器,處理器接收到數據後多是存儲到數據庫,也可能經過接口發送給老王。網絡
上面說了這麼多,咱們設計的爬蟲框架有如下幾個特性,沒有作到大而全,能夠稱得上輕量迷你挺好用。
易於定製:不少站點的下載頻率、瀏覽器要求是不一樣的,爬蟲框架須要提供此處擴展配置
多線程下載:當 CPU 核數多的時候多線程下載能夠更快完成任務
支持 XPath 和 CSS 選擇器解析