網絡爬蟲


什么是網絡爬蟲?

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

網絡爬蟲會遇到的問題

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

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

這些只是傳統的反爬蟲手段,隨着AI時代的到來,也會有更先進的手段的到來。

一個簡單的爬蟲示例

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();
        }
    }
}

示例分析:

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

網路爬蟲框架

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

  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 選擇器解析

架構圖

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM