通过爬取微博评论,发现好看的小姐姐...

通过爬取微博评论,发现好看的小姐姐...

前言

刷微博刷到一个博主求好看小姐姐照片的微博,内心不由得轻蔑一笑,好看的小姐姐凭啥理你,滑到评论区,我瞬间就酸了,内心对这个博主留下了嫉妒的泪水。
在这里插入图片描述
这样的照片评论区多的是,滑屏滑到手指酸痛还没有看完所有小姐姐的我灵机一动,不如写个爬虫把小姐姐照片全爬下来慢慢欣赏吧(吸溜~)!

页面分析

首先在chrom中打开开发者工具,打开微博链接,在network分析页面筛选XHR项,分析所有的请求
在这里插入图片描述
发现有一个hotflow的链接很有意思,查看了一下response,将json串在json解析工具中一看,果然就是我们要找的东西
在这里插入图片描述
顾名思义,user中是微博用户信息(有用户名,头像等信息),pic就是小改改们评论的图片,追求高清的我们当然要选择large中的图片啦!

正当我感觉一大波小姐姐在向我走来时,突然想到一个问题,微博评论的分页加载又该怎么处理?

下滑页面再次查看network控制台,发现请求的url中增加了一个max_id项,而这个参数正是第一次请求返回的json串中的max_id的值,至此,对于微博页面的这些分析已经可以让我们将小姐姐收入囊中了!

技术栈

  • 语言:java
    本来想用python来分析html页面操作的,但是发现使用一个http请求就可以完成,而自己手里又有现成的轮子,所以就用了自己比较熟悉的java
  • 数据库:redis
    使用redis的原因主要是安装使用方便,用它来存储http请求获取到的max_id,实现断点续传,同时存储图片信息防止重复爬取
  • 中间件:kafka
    因为程序是部署在我自己的服务器上的,由于服务器存储比较小,所以服务器只将爬取到的信息处理后发送到kafka,我本地再起消费者来下载图片

架构

在这里插入图片描述

关键点

  • 代理池
    为防止同一ip访问微博过于频繁而被限制访问,增加了代理池,关键代码如下:
public static String sendPost(String url,String proxyHost,int proxyPort) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        Random random = new Random();

// 设置代理ip和端口信息
        System.setProperty("https.proxyHost", proxyHost);
        System.setProperty("https.proxyPort", proxyPort+"");
        
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            
            String useAgent = useAgentsList.get(random.nextInt(useAgentsList.size()));
            System.out.println("本次请求使用agent"+useAgent);
            conn.setRequestProperty("user-agent", useAgent);
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            // out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

免费代理ip获取地址: https://www.kuaidaili.com/free/

我直接复制了几个地址写死在程序中了,有需求可以自己去爬一下这个网站做代理池的定时更新

  • 图片下载
    代码如下:
public static int saveImg(String picUrl,String comId,String userName,int num) throws IOException{
     // 保存图片
        // new一个URL对象
        URL url = null;
        FileOutputStream outStream = null;
        try {
            url = new URL(picUrl);

            // 打开链接
            HttpURLConnection conn = (HttpURLConnection) url
                    .openConnection();
            // 设置请求方式为"GET"
            conn.setRequestMethod("GET");
            // 超时响应时间为5秒
            conn.setConnectTimeout(5 * 1000);
            // 通过输入流获取图片数据
            InputStream inStream = conn.getInputStream();
            // 得到图片的二进制数据,以二进制封装得到数据,具有通用性
            byte[] data = readInputStream(inStream);
            // new一个文件对象用来保存图片,默认保存当前工程根目录
            String fileName = comId+";"+userName+ ".jpg";
            File imageFile = new File(imgPath+fileName);
            // 创建输出流
            outStream = new FileOutputStream(imageFile);
            // 写入数据
            outStream.write(data);
            // 关闭输出流
            outStream.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            outStream.close();
            ++num;
            return num;
        }
    }

剩下的就是kafka的生产消费者代码和json解析以及逻辑处理了,在这里就不多介绍了,大家可以按照自己的思路去处理。

成果

在这里插入图片描述
emmm,因为直接爬取的这条微博下的所有图片评论,所以好像混进了一些奇怪的东西,无伤大雅!不得不感叹,好看的小姐姐是真的好看,溜了溜了!

欢迎关注我的个人微信公众号,一个菜鸟程序猿的技术技术分享和奔溃日常

一个菜鸟程序猿的技术技术分享和奔溃日常

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值