多账号定向网站爬取关键技术

场景描述:

多个帐号模拟登录同一个网站,将不同帐号的cookie保存至本地,对于网站中的异步接口数据,各个帐号(通过携带cookie)都可同时并行请求。


问题描述:

假设有不同帐号,100个线程的爬取请求的cookie失效时,某个线程将会占有唯一浏览器,重新登录网站。其它线程如何处理?


1 爬取线程不应该直接刷新cookie,而是提交刷新cookie的需求

2 由cookie管理器控制哪个请求线程具体占有浏览器实现登录,获取cookie


cookie刷新观察者,监听cookie刷新的需求,并实际执行cookie刷新

public class CookiesAskWatcher implements Observer{

    private CookiesFlushSemaphore cookiesFlushSemaphore;

    CookiesAskWatcher(CookiesFlushSemaphore cookiesFlushSemaphore){
        this.cookiesFlushSemaphore = cookiesFlushSemaphore;
    }

    @Override
    public void update(Observable o, Object arg) {        
       CookiesStoreUtils.flush(帐号,密码);
       cookiesFlushSemaphore.confirmFlush();       
    }
}


cookie刷新的请求的被观察者,根据情况提交刷行请求,或者阻塞,唤醒后直接使用可用的cookie

public class CookiesAskWatched extends Observable{

    private boolean volatile isFlushing = false;

    private CookiesFlushSemaphore cookiesFlushSemaphore;

    public CookiesAskWatched(CookiesFlushSemaphore cookiesFlushSemaphore){
        this.cookiesFlushSemaphore = cookiesFlushSemaphore;
    }

    public void askFlush(Param param) throws Exception{
        if(isFlushing == false){
            synchronized (this) {
                if (isFlushing == false) {
                    isFlushing = true;
                    setChanged();
                    notifyObservers(param);
                    isFlushing = false;
                    return;
                }
            }
        }
        cookiesFlushSemaphore.waitFlush();
    }
}


cookie管理者,初始化需要定义cookie观察者和主题

public class CookiesManager {

    private static Map<Integer, CookiesAskWatched> watcheds = new HashMap<>();

    public CookiesManager(){
        int i = 1;
        while (i <= 4){
            CookiesFlushSemaphore cookiesFlushSemaphore = new CookiesFlushSemaphore();
            CookiesAskWatched cookiesAskWatched = new CookiesAskWatched(cookiesFlushSemaphore);
            cookiesAskWatched.addObserver(new CookiesAskWatcher(cookiesFlushSemaphore));
            watcheds.put(i, cookiesAskWatched);
            i++;
        }
    }

    public void submitFlush(Param param) throws Exception{
        Integer masterCard = param.getMasterCard();
        watcheds.get(masterCard).askFlush(param);
    }

信号量,换起阻塞的线程

public class CookiesFlushSemaphore {

    private boolean signal = false;
   

    public synchronized void waitFlush() throws InterruptedException{

        this.signal = false;

        while (!this.signal)wait();
    }

    public synchronized void confirmFlush(){
        this.signal = true;
        this.notifyAll();
    }

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值