吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 43371|回复: 72
收起左侧

[Android工具] Android爬虫

  [复制链接]
孤云 发表于 2018-10-18 19:40
本帖最后由 孤云 于 2018-10-18 22:00 编辑

由于最近想换壁纸,但是又懒得去翻帖子一个个的看,所以自已动手写了个简单的app下载图片。
由于我不会安卓,所以写得很多bug、简陋,下载速度慢(可以用多线程优化,不会安卓的我不知道怎么写),而且只支持三楼的链接才能爬取。
安卓跟web爬虫基本上没什么区别,都是通过请求获得响应。Android返回的是json格式的字符串,web返回的是页面。
这里思路就是通过抓包抓取请求,查看他的响应内容,将我们需要的数据取出来就ok了。
下面开始教程:
需要用到抓包,手机电脑都行,因为是android爬虫,所有就以手机为例了,这里我用的是数据包捕获抓包。
1.打开三楼的一篇帖子,打开抓包 软件

Screenshot_2018-10-18-19-34-54-005_com.huati.png

2.开始抓包,并刷新一下帖子,然后从大到小从数据包里找到请求。
找到下图这样的内容,title是标题的意思,然后跟帖子的标题对比一下,如果是一样的就是他了。
Screenshot_2018-10-18-18-42-29-297_app.greyshirts.png

3.将图片中蓝色区域的那一块复制出来,将Host和GET后面的以host在前,get在后的方式拼接起来,不要host和get!(注意空格,得到的链接可以先拿到浏览器试下)
最后获得这样的一个链接。
[Java] 纯文本查看 复制代码
http://floor.huluxia.com/post/detail/ANDROID/2.2?platform=2&gkey=440000&app_version=3.5.0.83.2&versioncode=20141384&market_id=floor_tencent&_key=6DBDBD8B6601BFF3BC3F87DF526DD80EABA9E4557F5F7B8745B40F9E7075239D052447C61C5F77EEF718DE489A7A21DB49D0F5B90A55F166&device_code=%5Bw%5D02%3A00%3A00%3A00%3A00%3A00-%5Bi%5D864447034701670-%5Bs%5D89860040221578535925&post_id=32336552&page_no=1&page_size=20&doc=1


将链接输入到浏览器得到的如下图。
sl.png

4.将链接复制到软件中,点击下载即可。(速度有点慢)
Screenshot_2018-10-18-18-46-11-591_cn.d1999.guyun.png
可以将链接中的page_no的修改控制从第几页开始。

下载完成效果图

Screenshot_2018-10-18-18-46-43-468_bin.mt.plus.png
教程完毕。
最后附上软件,和源码。
软件链接:https://pan.baidu.com/s/1pQlXarBYNZHkOV5_nUjvxg 提取码:4q2w
[Java] 纯文本查看 复制代码
public class MainActivity extends AppCompatActivity {
    private Thread t;//线程
    private static int page = 0;//页数
    private static int countPage = 1;//总数
    private static int downloading = 0;//下载数
    private EditText et_main_url;
    private Button btn_main_download;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_main_url = (EditText) findViewById(R.id.et_main_url);
        btn_main_download = (Button) findViewById(R.id.bt_main_download);
        if (Build.VERSION.SDK_INT >= 23) { //安卓6.0以上需要允许授权才能写入图片到本地
            int REQUEST_CODE_CONTACT = 101;
            String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
            //验证是否许可权限
            for (String str : permissions) {
                if (this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) {
                    //申请权限
                    this.requestPermissions(permissions, REQUEST_CODE_CONTACT);
                }
            }
        }

    }
    //按钮的点击事件
    public void download(View v){
       String text = et_main_url.getText().toString();
        if(text != null && !"".equals(text)) {
            if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//判断是否有读写权限
                Toast.makeText(MainActivity.this, "开始下载...", Toast.LENGTH_SHORT).show();
                new MainActivity().getAllLinks(text);
                btn_main_download.setEnabled(false);//设置按钮不能点击
                btn_main_download.setText("正在下载");//设置文字
            }else {
                Toast.makeText(this, "没有权限!", Toast.LENGTH_LONG).show();
            }
        }else {
            Toast.makeText(MainActivity.this, "链接不能为空!", Toast.LENGTH_LONG).show();
        }
    }

    /**
     * 获取所有图片链接
     * @return
     */
    public void getAllLinks(final String str){
        //因为安卓不能在主线程执行耗时的网络操作,所以需要开个分线程
         t =new Thread(() ->{ //jdk1.8新特性lambda表达式
                 try {
                     int count = 0;//定义一个变量控制链接的截取和给总页数赋值
                     for (; page < countPage; page++) {
                         String link = str;//将传入的参数赋值给link
                         String page_no = link.substring(link.indexOf("page_no"));//字符串截取
                         if(count == 0) {
                             //当第一次进入方法时,将用户输入的链接页数截取出来
                             page = Integer.valueOf(page_no.substring(page_no.indexOf("=") + 1, page_no.indexOf("&")));
                         }
                         //将链接截取拼接成新的链接
                         page_no = page_no.substring(0, page_no.indexOf("=") + 1);
                         link = link.substring(0, link.lastIndexOf("page_no"));
                         link = link + page_no + page;
                         //连接到url
                         Document doc = Jsoup.connect(link).timeout(10000).ignoreContentType(true).get();
                         //将返回回来的json字符串转换
                         JSONObject json = JSONObject.fromObject(doc.text());
                         //如果是第一页,就获取主题的图片
                         if (page == 1) {
                             String theme = json.getJSONObject("post").getString("images");//主题的图片
                         }
                         //如果是第一进入方法就获取总页数的值,并将count的值改变
                         if(count == 0) {
                             countPage = json.getInt("totalPage");//获取总页数
                             count = count + 1;
                         }
                         //获取装有图片的json数组
                         JSONArray jsonArray = json.getJSONArray("comments");
                         //遍历json数组
                         for (int i = 0; i < jsonArray.size(); i++) {
                             //获取到图片的链接,因为是多个图片连接的,所以将链接拆分
                             String images = jsonArray.getJSONObject(i).getString("images");
                             String imgLink = images.replaceAll("\\[", "").replaceAll("]", "");
                             if (imgLink != null && !"".equals(imgLink)) {
                                 //以","将链接分成一个数组
                                 String[] strs = imgLink.split(",");
                                 for (int j = 0; j < strs.length; j++) {
                                    //链接格式有问题,需要处理
                                     strs[j] = strs[j].substring(1, strs[j].lastIndexOf("\""));
                                     download(strs[j]);//调用下载方法
                                 }
                             }
                         }
                     }
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
         });
        t.start();
    }

    /**
     * 下载图片
     * @param link
     */
    public void download(String link){
        try {
            URL url = new URL(link);//定义一个URL
            //输入流,读取图片
            DataInputStream dis = new DataInputStream(url.openStream());
            byte[] bytes = new byte[1024];
            //截取后缀
            String suffix = link.substring(link.lastIndexOf("."));
            //获取用户的sd卡目录
            File directory = Environment.getExternalStorageDirectory();
            File file = new File(directory + "/guyun/");
            if(!file.exists()){
                file.mkdirs();
            }
            Log.e("输出目录",file.getAbsolutePath());
            //输出流,用时间的毫秒值当图片名称
            FileOutputStream fos = new FileOutputStream(new File(file.getAbsolutePath()+ "/" +  new Date().getTime() + suffix));
            ByteArrayOutputStream baos =  new ByteArrayOutputStream();
            //写出图片
            int len = -1;
            while ((len = dis.read(bytes)) != -1){
                baos.write(bytes,0,len);
            }
            fos.write(baos.toByteArray());
            downloading ++;
            dis.close();
            baos.close();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

免费评分

参与人数 15吾爱币 +18 热心值 +14 收起 理由
zhanglunfu + 1 + 1 我很赞同!
yosi2009 + 1 + 1 一群大佬在讨论编码,可以的可以的
ovodestroy + 1 + 1 我很赞同!
derSir + 1 + 1 我很赞同!
xiazhi1128 + 1 我很赞同!
Deltar + 1 + 1 谢谢@Thanks!
suadzh + 1 + 1 谢谢@Thanks!
wxfhf520 + 1 谢谢@Thanks!
Toosan + 1 + 1 用心讨论,共获提升!
污火盟灬盟主 + 1 + 1 热心回复!
紫轩冰凌 + 2 + 1 谢谢@Thanks!
dengsha + 1 + 1 谢谢@Thanks!
云在天 + 6 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
kk1212 + 1 新手能做到这样也不错了,支持你!
hearne + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 孤云 发表于 2018-10-18 22:02
发现了一个bug必须带上协议才能下载图片,不然连接不上
 楼主| 孤云 发表于 2019-3-19 21:25
轩东丨Away 发表于 2019-3-19 14:08
刚下下来,还没时间去试。不过我有个疑问。如果不是抓非壁纸网站的话会出现图片模糊的情况吗?

我这只是针对这一个app写的爬虫
ebf 发表于 2018-10-18 19:42
hearne 发表于 2018-10-18 19:59
然后呢?   
 楼主| 孤云 发表于 2018-10-18 20:03

大概编辑好了
 楼主| 孤云 发表于 2018-10-18 20:05

编辑好了。
xixicoco 发表于 2018-10-18 20:14
手机端操作吗?
 楼主| 孤云 发表于 2018-10-18 20:19

手机电脑都可以
头像被屏蔽
炫金呀 发表于 2018-10-18 20:57
提示: 作者被禁止或删除 内容自动屏蔽
Adler_qy 发表于 2018-10-18 21:01
感谢分享!!不错的!!!
wuyy 发表于 2018-10-18 21:10

谢谢楼主分享教程!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 19:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表