栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

2021-09-30

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021-09-30

网络安全(一):爬虫和反爬虫

文章目录
  • 前言
  • 一、爬虫
  • 二、反爬虫


前言 一、爬虫

我们的爬虫程序以一个固定的ip去访问目标网站,目标网站会发现这个固定的ip有大量的请求,会判定为爬虫,直接进行屏蔽。
提供一种思路:代理服务器,代理服务器能够将固定的ip变成随机的ip,去访问目标网站。

public class ipliProxyProvider implements ProxyProvider {
    private Logger logger = Logger.getLogger(ipliProxyProvider.class);

    private List proxyList = new ArrayList<>();
    private volatile Map> siteProxysMap = new HashMap>();
    private Object siteProxysMapLock = new Object();
    //获取代理信息的地址
    private String apiurl;
    //用户名
    private String username;
    //密码
    private String password;
    private volatile static ipProxyProvider instance = null;

    public ipProxyProvider(String apiurl, String username, String password) {
        this.apiurl = apiurl;
        this.username = username;
        this.password = password;
        this.init();
    }

    public static ipProxyProvider getInstance(String apiurl, String username, String password) {
        if (instance == null) {
            synchronized (ipProxyProvider.class) {
                if (instance == null) {
                    instance = new ipProxyProvider(apiurl, username, password);
                }
            }
        }
        return instance;
    }

    private void init() {
        try {
            logger.info("get proxy");
            String s = HttpsUtil.requestGet(this.apiurl);
            logger.info(s);
            if (StringUtil.isNotEmpty(s)) {
                final JSONObject jsonObject = JSON.parseObject(s);
                if (jsonObject == null) {
                    return;
                }
                final JSONObject data = jsonObject.getJSONObject("data");
                if (data == null) {
                    return;
                }
                final JSONArray proxy_list = data.getJSONArray("proxy_list");
                if (proxy_list == null && proxy_list.size() == 0) {
                    return;
                }
                List tempList = new ArrayList<>();
                for (int i = 0; i < proxy_list.size(); i++) {
                    final String string = proxy_list.getString(i);
                    final String[] split = string.split(":");
                    proxyList.add(new Proxy(split[0], Integer.parseInt(split[1]), this.username, this.password));
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    private ArrayBlockingQueue get(String key) {
        try {
            ArrayBlockingQueue queue = siteProxysMap.get(key);
            if (queue == null) {
                synchronized (siteProxysMapLock) {
                    queue = siteProxysMap.get(key);
                    if (queue == null) {
                        ArrayBlockingQueue proxies = new ArrayBlockingQueue(proxyList.size());
                        for (Proxy proxy : proxyList) {
                            proxies.put(proxy);
                        }
                        siteProxysMap.put(key, proxies);
                    }
                }
            }
        } catch (InterruptedException e) {
            this.logger.error(e.getMessage(), e);
        }
        return siteProxysMap.get(key);
    }

    @Override
    public void returnProxy(Proxy proxy, Page page, Task task) {
        this.logger.info(proxy);
        try {
            String key = getKey(task);
            this.get(key).put(proxy);
        } catch (InterruptedException e) {
            this.logger.error(e.getMessage(), e);
        }
    }

    private String getKey(Task task) {
        final String domain = task != null && task.getSite() != null ? task.getSite().getDomain() : null;
        return StringUtil.isNotEmpty(domain) ? domain : KuaidailiProxyProvider.class.getName();
    }

    @Override
    public Proxy getProxy(Task task) {
        Proxy proxy = null;
        try {
            proxy = this.get(this.getKey(task)).take();
            this.logger.info(proxy);
        } catch (InterruptedException e) {
            logger.error(e.getMessage(), e);
        }
        return proxy;
    }
}
二、反爬虫

1.对爬虫客户端以一个固定的ip去访问网站,网站会发现这个固定的ip有大量的请求,会判定为爬虫,直接进行屏蔽。

2.对于一些重要的接口进行隐藏,比如电商软件的抢购接口,实现思路:每次点击秒杀按钮,先从服务器获取一个秒杀验证值(接口内判断是否到秒杀时间)。Redis以缓存用户ID和商品ID为Key,秒杀地址为Value缓存验证值
用户请求秒杀商品的时候,要带上秒杀验证值进行校验。

@Override
public int createVerifiedOrder(Integer sid, Integer userId, String verifyHash) throws Exception {

    // 验证是否在抢购时间内
    LOGGER.info("请自行验证是否在抢购时间内,假设此处验证成功");

    // 验证hash值合法性
    String hashKey = CacheKey.HASH_KEY.getKey() + "_" + sid + "_" + userId;
    String verifyHashInRedis = stringRedisTemplate.opsForValue().get(hashKey);
    if (!verifyHash.equals(verifyHashInRedis)) {
        throw new Exception("hash值与Redis中不符合");
    }
    LOGGER.info("验证hash值合法性成功");

    // 检查用户合法性
    User user = userMapper.selectByPrimaryKey(userId.longValue());
    if (user == null) {
        throw new Exception("用户不存在");
    }
    LOGGER.info("用户信息验证成功:[{}]", user.toString());

    // 检查商品合法性
    Stock stock = stockService.getStockById(sid);
    if (stock == null) {
        throw new Exception("商品不存在");
    }
    LOGGER.info("商品信息验证成功:[{}]", stock.toString());

    //乐观锁更新库存
    saleStockOptimistic(stock);
    LOGGER.info("乐观锁更新库存成功");

    //创建订单
    createOrderWithUserInfo(stock, userId);
    LOGGER.info("创建订单成功");

    return stock.getCount() - (stock.getSale()+1);
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/284371.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号