網絡爬蟲

什麼是網絡爬蟲?

  網絡爬蟲(又被稱爲網頁蜘蛛,網絡機器人,在FOAF社區中間,更常常的稱爲網頁追逐者),是一種按照必定的規則,自動地抓取萬維網信息的程序或者腳本。另一些不常使用的名字還有螞蟻、自動索引、模擬程序或者蠕蟲css

網絡爬蟲會遇到的問題

  有人抓取,就會有人想要防護。網絡爬蟲在運行過程當中也會遇到反爬蟲策略。常見的有:html

  • 訪問頻率限制;
  • Header頭部信息校驗;
  • 採用動態頁面生成;
  • 訪問地址限制;
  • 登陸限制;
  • 驗證碼限制等。

這些只是傳統的反爬蟲手段,隨着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

  1. 輸入想要爬取的url地址;
  2. 發送網絡請求獲取頁面內容;
  3. 使用jsoup解析dom;
  4. 獲取須要的數據,輸出到控制檯。

網路爬蟲框架

設計框架的目的就是將這些流程統一化,將通用的功能進行抽象,減小重複工做。設計網絡爬蟲框架須要哪些組件呢?web

  1. url管理;
  2. 網頁下載器;
  3. 爬蟲調度器;
  4. 網頁解析器;
  5. 數據處理器。
  • URL管理器

  爬蟲框架要處理不少的 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 選擇器解析

架構圖

相關文章
相關標籤/搜索