示例#1
0
    async def save_ip(self, ip: IPData):
        await self.update_score(ip)
        with await Redis.share() as redis:
            if ip.http is True:
                await redis.sadd(Config.REDIS_KEY_ABLE_HTTP, ip.to_str())
            else:
                await redis.srem(Config.REDIS_KEY_ABLE_HTTP, ip.to_str())

            if ip.https is True:
                await redis.sadd(Config.REDIS_KEY_ABLE_HTTPS, ip.to_str())
            else:
                await redis.srem(Config.REDIS_KEY_ABLE_HTTPS, ip.to_str())

            # Rules check
            for key, res in ip.rules.items():
                if res is True:
                    await redis.sadd(Config.REDIS_KEY_ABLE_RULES % key, ip.to_str())
                else:
                    await redis.srem(Config.REDIS_KEY_ABLE_RULES % key, ip.to_str())

            # Delay pool
            if ip.available():
                delay_key = self.get_delay_key(ip.delay)
                if delay_key:
                    await redis.sadd(delay_key, ip.to_str())

        if ip.available():
            await self.available_call(ip)
        else:
            await self.fail_call(ip)
示例#2
0
    async def https_check(self, ip: IPData, session) -> IPData:
        """
        HTTPS 可用性检测
        :return:
        """
        try:
            async with session.get(self.NORMAL_CHECK_URL.replace(
                    'http', 'https', 1),
                                   proxy=ip.to_http()) as resp:
                result = await resp.json()
                if not result.get('origin'):
                    raise ValidationFailException()
                ip.https = True
        except Exception:
            ip.https = False

        return ip
示例#3
0
    async def http_check(self, ip: IPData, session) -> IPData:
        """
        可用与匿名检测 毫秒
        :param ip:
        :return:
        """
        time_spend = datetime.datetime.now()
        try:
            async with session.get(self.NORMAL_CHECK_URL,
                                   proxy=ip.to_http()) as resp:
                result = await resp.json()
                if not result.get('origin'):
                    raise ValidationFailException()
                time_spend = datetime.datetime.now() - time_spend
                ip.delay = time_spend.total_seconds()
                ip.http = True
        except Exception:
            ip.http = False

        return ip
示例#4
0
 async def rules_check(self, ip: IPData, session) -> IPData:
     """
     通过规则进行检测
     :return:
     """
     rules = {}
     for rule in Config.RULES:
         assert isinstance(rule, RuleData), 'Error rule format'
         if not rule.enable:
             continue
         try:
             async with session.get(rule.url, proxy=ip.to_http()) as resp:
                 result = await resp.text()
                 assert isinstance(result, str)
                 if rule.contains and result.find(rule.contains) < 0:
                     raise ValidationFailException()
                 rules[rule.key] = True
         except Exception:
             rules[rule.key] = False
     ip.rules = rules
     return ip
示例#5
0
 async def start_check(self):
     with await Redis.share() as redis:
         ip_str = await redis.blpop(Config.REDIS_KEY_CHECK_POOL)
     ip_str = ip_str[1].decode()
     Logger.info('[check] got ip %s' % ip_str)
     Prometheus.IP_CHECK_TOTAL.inc(1)
     ip = IPData.with_str(ip_str)
     async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(
             Config.DEFAULT_REQUEST_CHECK_TIME_OUT)) as session:
         ip = await self.http_check(ip, session)
         ip = await self.https_check(ip, session)
         ip = await self.rules_check(ip, session)
         Logger.info(
             '[check] Check result %s http %s https %s %s', ip.to_str(),
             ip.http, ip.https,
             " ".join(["%s %s" % (k, r) for k, r in ip.rules.items()]))
     await IPSaver().save_ip(ip)
示例#6
0
 async def get_ips(cls,
                   http: bool = True,
                   https: bool = False,
                   delay: int = None,
                   rule: str = None):
     keys = []
     if http:
         keys.append(Config.REDIS_KEY_ABLE_HTTP)
     if https:
         keys.append(Config.REDIS_KEY_ABLE_HTTPS)
     if delay:
         keys.append(Config.REDIS_KEY_NET_DELAY % delay)
     if rule:
         keys.append(Config.REDIS_KEY_ABLE_RULES % rule)
     with await Redis.share() as redis:
         ips = await redis.sinter(*keys)
         ips = [IPData.with_str(ip.decode()) for ip in ips]
     return ips
示例#7
0
 async def update_score(self, ip: IPData):
     with await Redis.share() as redis:
         score = await redis.zscore(Config.REDIS_KEY_IP_POOL, ip.to_str())
         ip.score = score if score is not None else 0
示例#8
0
 async def available_call(self, ip: IPData):
     if ip.score >= Config.DEFAULT_MAX_SCORE:
         return
     with await Redis.share() as redis:
         await redis.zincrby(Config.REDIS_KEY_IP_POOL, Config.DEFAULT_INC_SCORE, ip.to_str())
示例#9
0
 async def fail_call(self, ip: IPData):
     if ip.score <= Config.DEFAULT_MINI_SCORE:
         return
     with await Redis.share() as redis:
         await redis.zincrby(Config.REDIS_KEY_IP_POOL, -Config.DEFAULT_DEC_SCORE, ip.to_str())