国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

cockroach 爬蟲:又一個 java 爬蟲實現(xiàn)

liangzai_cool / 2377人閱讀

摘要:爬蟲又一個爬蟲實現(xiàn)原文簡介小強當(dāng)時不知道為啥選了這么個名字,又長又難記,導(dǎo)致編碼的過程中因為單詞的拼寫問題耽誤了好長時間。我是一個小強爬蟲線程數(shù)健壯說到健壯,這里主要體現(xiàn)在以下幾個方面應(yīng)對封鎖這里我們使用動態(tài)代理來解決這個問題。

cockroach 爬蟲:又一個 java 爬蟲實現(xiàn)

原文

簡介

cockroach[小強] 當(dāng)時不知道為啥選了這么個名字,又長又難記,導(dǎo)致編碼的過程中因為單詞的拼寫問題耽誤了好長時間。

這個項目算是我的又一個坑吧,算起來挖的坑多了去了,多一個不多少一個不少。

一個小巧、靈活、健壯的爬蟲框架,暫且叫做框架吧。

簡單到什么程度呢,幾句話就可以創(chuàng)建一個爬蟲。

環(huán)境

java8 程序中用到了一些 java8 的新特性

maven


  com.github.zhangyingwei
  cockroach
  1.0.5-Beta

如果哪天我忘了更新文檔了,一定要記住使用最新的版本,最新的版本,新的版本,版本,本。

下面就逐點介紹一下:

小巧

小巧主要體現(xiàn)在兩個方面

體積小 (打包之后整個 jar 包只有 70k 多一點,所以完全擔(dān)得起小巧兩個字)

開發(fā)代碼量?。ɑ诒究蚣荛_發(fā)一個爬蟲需要的工作量可以說是非常小。這個在下邊的文檔中會有體現(xiàn))

實例

在項目中新建一個測試類 App.java 并新建 main 方法。

public static void main(String[] args){
    CockroachConfig config = new CockroachConfig()
                    .setAppName("我是一個小強")
                    .setThread(2); //爬蟲線程數(shù)
    CockroachContext context = new CockroachContext(config);
    TaskQueue queue = TaskQueue.of();
    context.start(queue);
    
    // 以上就是一個完整的爬蟲,下邊的代碼相當(dāng)于一個生產(chǎn)者,往隊列里邊寫任務(wù),一旦寫入任務(wù),爬蟲就會對任務(wù)進行爬取
    new Thread(() -> {
        int i = 0;
        while(true){
            i++;
            try {
                Thread.sleep(1000);
                String url = "http://www.xicidaili.com/wt/"+i;
                System.out.println(url);
                queue.push(new Task(url));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (i > 1000) {
                break;
            }
        }
    }).start();
}
靈活

那靈活又體現(xiàn)在什么方面呢

可以自定義 http 客戶端(可選,默認使用 okhttp3)

可以自定義結(jié)果的處理 (可選,默認使用打印處理器)

自定義 http 客戶端

首先我們嘗試一下自定義客戶端

public class SelfHttpClient implements HttpClient {
       public HttpClient setProxy(HttpProxy proxy){
            //設(shè)置代理實現(xiàn)方法
       }
       public TaskResponse doGet(Task task) throws Exception{
            // get 請求實現(xiàn)方法
       }
   
       public HttpClient proxy(){
            // 應(yīng)用代理到 http 客戶端 方法
       }
   
       public TaskResponse doPost(Task task) throws Exception{
            // post 請求實現(xiàn)方法
       }
   
       public HttpClient setCookie(String cookie){
            // 設(shè)置 cookie 實現(xiàn)方法
       }
   
       public HttpClient setHttpHeader(Map httpHeader){
            // 設(shè)置 header 實現(xiàn)方法
       }
}

應(yīng)用自定義 http 客戶端到爬蟲

CockroachConfig config = new CockroachConfig()
    .setAppName("我是一個小強")
    .setThread(2) //爬蟲線程數(shù)
    .setHttpClient(SelfHttpClient.class)

PS:上邊這一塊目前處于待定狀態(tài)

自定義結(jié)果處理類

自定義結(jié)果處理類

public class SelfStore implements IStore {
    @Override
    public void store(TaskResponse response) {
        System.out.println(response.getContent());
    }
}

這里簡單的將結(jié)果打印了出來,在實際應(yīng)用中,我們可以保存到數(shù)據(jù)庫或者保存到文件中等等。值得一說的是,如果結(jié)果是 html 網(wǎng)頁文本的話,我們還提供了 select("css選擇器") 來對結(jié)果文本進行處理。

應(yīng)用自定義 store 客戶端到爬蟲

CockroachConfig config = new CockroachConfig()
    .setAppName("我是一個小強")
    .setThread(2) //爬蟲線程數(shù)
    .setHttpClient(SelfHttpClient.class)
    .setStore(SelfStore.class);
自定義錯誤處理類

當(dāng) http 請求網(wǎng)頁出現(xiàn)錯誤的時候會統(tǒng)一定位到錯誤處理類,如果沒有自定義錯誤處理類,系統(tǒng)會默認使用 DefaultTaskErrorHandler ,此處理類會吧錯誤信息打印出來。具體實現(xiàn)代碼如下。

public class DefaultTaskErrorHandler implements ITaskErrorHandler {
    private Logger logger = Logger.getLogger(DefaultTaskErrorHandler.class);
    @Override
    public void error(Task task,String message) {
        logger.info("task error: "+message);
    }
}

如果需要自定義錯誤處理類,可以仿照以上代碼,實現(xiàn) ITaskErrorHandler 接口,在 error 方法中實現(xiàn)自己的處理邏輯。

在自定義錯誤處理類之后,我們需要把自定義類應(yīng)用到爬蟲。

CockroachConfig config = new CockroachConfig()
    .setAppName("我是一個小強")
    .setThread(2) //爬蟲線程數(shù)
    .setHttpClient(SelfHttpClient.class)
    .setStore(SelfStore.class)
    .setTaskErrorHandler(SelfTaskErrorHandler.class);
健壯

說到健壯,這里主要體現(xiàn)在以下幾個方面:

應(yīng)對IP封鎖

這里我們使用動態(tài)代理來解決這個問題。

動態(tài)代理的使用
CockroachConfig config = new CockroachConfig()
    .setAppName("我是一個小強")
    .setThread(2) //爬蟲線程數(shù)
    .setHttpClient(SelfHttpClient.class)
    .setProxys("100.100.100.100:8888,101.101.101.101:8888")

如上所示,我們可以設(shè)置若干個代理 ip,最終將所有代理 ip 生成一個代理池,在爬蟲請求之前,我們會從代理池中隨機抽取一個 ip 做代理。

應(yīng)對 http 請求中的 user-agent 問題

程序中實現(xiàn)了一個 user-agent 池,每次請求都會隨機取出一個 user-agent 使用,目前在程序中集成了 17 種 user-agent,后續(xù)會考慮把這塊開放出來到配置中,自定義配置(有沒有意義呢?)。

程序中的異常處理問題

目前在異常處理這塊,本身也不是非常擅長,已經(jīng)盡力把異常控制在一個可控的范圍內(nèi),程序中定義了很多自定義異常,這里沒有什么發(fā)言權(quán),就不細說了,各位要是有意見建議,歡迎拍磚。

所謂深度爬取

程序中并沒有現(xiàn)成的深度爬取實現(xiàn),是因為一般情況下我并不覺得深度爬取有什么卵用,但是也不是沒有為深度爬取留出來一席之地。我們可以自己提取出頁面中的鏈接并加入到任務(wù)隊列中。以達到深度爬取的效果。

public class DemoStore implements IStore {

    private String id = NameUtils.name(DemoStore.class);

    public DemoStore() throws IOException {}

    @Override
    public void store(TaskResponse response) throws IOException {
        List urls = response.select("a").stream().map(element -> element.attr("href")).collect(Collectors.toList());
        try {
            response.getQueue().push(urls);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
注解支持

最近忙里偷閑增加了注解支持,那么在使用注解之后,一個爬蟲是什么樣的呢?

@EnableAutoConfiguration
@AppName("hello spider")
@Store(PrintStore.class)
@AutoClose(true)
@ThreadConfig(num = 1)
@CookieConfig("asdfasdfasdfasdfasfasdfa")
@HttpHeaderConfig({
        "key1=value1",
        "key2=value2"
})
@ProxyConfig("1.1.1.1,2.2.2.2")
public class CockroachApplicationTest {
    public static void main(String[] args) throws Exception {
        TaskQueue queue = TaskQueue.of();
        queue.push(new Task("http://blog.zhangyingwei.com"));
        CockroachApplication.run(CockroachApplicationTest.class,queue);
    }
}

如上就是基本上所有注解的演示,那么拋開演示的部分,如果真的只是做一個demo,需要怎么寫呢?

@EnableAutoConfiguration
public class CockroachApplicationTest {
    public static void main(String[] args) throws Exception {
        TaskQueue queue = TaskQueue.of();
        queue.push(new Task("http://blog.zhangyingwei.com"));
        CockroachApplication.run(CockroachApplicationTest.class,queue);
    }
}

沒錯,就是這么簡單。這個爬蟲就是爬取 http://blog.zhangyingwei.com 這個頁面的內(nèi)容并將結(jié)果打印出來。
在爬蟲結(jié)果處理這個問題上,程序中默認使用 PringStore 這個類將所有結(jié)果打印出來。

動態(tài) header 支持

最近做了一個工作職位的爬蟲,在爬拉鉤的時候遇到一個問題。需要登錄才能爬取,這個當(dāng)然配置 cookie 就能解決,但是拉鉤的 cookie 里邊做了防爬蟲驗證。cookie 里邊有一個時間需要動態(tài)變化。所以就產(chǎn)生了這個功能。

這個功能使用起來如下:

Cookie 生成器
@CookieConfig(cookieGenerator = CookieGeneratorTest.class)
/**
 * Created by zhangyw on 2017/12/19.
 */
public class CookieGeneratorTest implements StringGenerator {

    @Override
    public String get(Task task) {
        String cookie = "v="+ UUID.randomUUID().toString();
        System.out.println(cookie);
        return cookie;
    }
}

在每次發(fā)生 http 請求之前,程序都會調(diào)用 Generator 的 get 方法。獲取到本次的 cookie 值,并附加到 http 請求頭中。

Header 生成器

由于程序中需要的 header 是 map 類型的數(shù)據(jù),所以 header 生成器如下:

@HttpHeaderConfig(headerGenerator = HeaderGeneratorTest.class)
/**
 * Created by zhangyw on 2017/12/19.
 */
public class HeaderGeneratorTest implements MapGenerator {
    private Map headers = new HashMap();
    @Override
    public Map get(Task task) {
        return headers;
    }
}

以上就是目前所有的生成器,可以看到生成器中傳入了 task 對象,這里是為了在爬蟲應(yīng)對不同的地址的時候使用不同的 cookie/header 。

算了還是舉個栗子吧:

/**
 * Created by zhangyw on 2017/12/19.
 */
public class HeaderGeneratorTest implements MapGenerator {
    private Map headers = new HashMap();
    @Override
    public Map get(Task task) {
        if ("jobs.lagou".equals(task.getGroup())) {
            header.put("key","value");
            return headers;
        } else {
            return null;
        }
    }
}

OK,到此為止,就啰嗦這么多了。

最后,各位大大如果覺得不討厭的話,來個 start 唄。

https://github.com/zhangyingwei/cockroach

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/70865.html

相關(guān)文章

  • 【微信小程序爬蟲】表情包小程序圖文視頻教學(xué),從零寫起,保姆教程?。。?/b>

    摘要:文章目錄前言爬取分析視頻教學(xué)成果展示福利入門到就業(yè)學(xué)習(xí)路線規(guī)劃小白快速入門爬蟲路線前言皮皮蝦一個沙雕而又有趣的憨憨少年,和大多數(shù)小伙伴們一樣喜歡聽歌游戲,當(dāng)然除此之外還有寫作的興趣,,日子還很長,讓我們一起加油努力叭話 ...

    coordinate35 評論0 收藏0
  • 精通Python網(wǎng)絡(luò)爬蟲(0):網(wǎng)絡(luò)爬蟲學(xué)習(xí)路線

    摘要:以上是如果你想精通網(wǎng)絡(luò)爬蟲的學(xué)習(xí)研究路線,按照這些步驟學(xué)習(xí)下去,可以讓你的爬蟲技術(shù)得到非常大的提升。 作者:韋瑋 轉(zhuǎn)載請注明出處 隨著大數(shù)據(jù)時代的到來,人們對數(shù)據(jù)資源的需求越來越多,而爬蟲是一種很好的自動采集數(shù)據(jù)的手段。 那么,如何才能精通Python網(wǎng)絡(luò)爬蟲呢?學(xué)習(xí)Python網(wǎng)絡(luò)爬蟲的路線應(yīng)該如何進行呢?在此為大家具體進行介紹。 1、選擇一款合適的編程語言 事實上,Python、P...

    spacewander 評論0 收藏0
  • Python爬蟲學(xué)習(xí)路線

    摘要:以下這些項目,你拿來學(xué)習(xí)學(xué)習(xí)練練手。當(dāng)你每個步驟都能做到很優(yōu)秀的時候,你應(yīng)該考慮如何組合這四個步驟,使你的爬蟲達到效率最高,也就是所謂的爬蟲策略問題,爬蟲策略學(xué)習(xí)不是一朝一夕的事情,建議多看看一些比較優(yōu)秀的爬蟲的設(shè)計方案,比如說。 (一)如何學(xué)習(xí)Python 學(xué)習(xí)Python大致可以分為以下幾個階段: 1.剛上手的時候肯定是先過一遍Python最基本的知識,比如說:變量、數(shù)據(jù)結(jié)構(gòu)、語法...

    liaoyg8023 評論0 收藏0
  • 知乎書籍排行網(wǎng)站——建站始末

    摘要:一時心血來潮,于是當(dāng)時想,如果拿來分析知乎這個網(wǎng)站,會有什么效果呢。知乎并沒有公開,只能采取爬蟲手段。如此,大概率會觸發(fā)知乎反爬蟲系統(tǒng),所以采取以下方法來回避這個問題代理池。但是,很多情況下知乎還是能通過你的請求得到你的真實。。 網(wǎng)站地址books.bigfacewo.com最近工作去了,感覺人也變懶了,一直想寫一些關(guān)于這個網(wǎng)站東西分享出來。慢慢寫吧。前情提要:對于大神來說,這個網(wǎng)站使...

    Tony 評論0 收藏0
  • 知乎書籍排行網(wǎng)站——建站始末

    摘要:一時心血來潮,于是當(dāng)時想,如果拿來分析知乎這個網(wǎng)站,會有什么效果呢。知乎并沒有公開,只能采取爬蟲手段。如此,大概率會觸發(fā)知乎反爬蟲系統(tǒng),所以采取以下方法來回避這個問題代理池。但是,很多情況下知乎還是能通過你的請求得到你的真實。。 網(wǎng)站地址books.bigfacewo.com最近工作去了,感覺人也變懶了,一直想寫一些關(guān)于這個網(wǎng)站東西分享出來。慢慢寫吧。前情提要:對于大神來說,這個網(wǎng)站使...

    stormzhang 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<