0

Hướng dẫn viết tool Crawl dư liệu bằng Android.(p3)

Ở phần này mình sẽ chia sẽ project của mình link github nhé

Dưới đây là chi tiết một file crawl mà mình đã code: Có thể code chưa được tối ứu vì lúc đó mình mới tập code thôi mà :DDDD.

Bạn có thế tối ưu nha :DDD

File crawl

package net.blogsv.craw;

import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;

import net.blogsv.database.entity.LyEntity;
import net.blogsv.database.repository.RepositoryDATA;
import net.blogsv.retrofit2.DownloadFile;
import net.blogsv.tooljackviet.R;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import pl.droidsonroids.gif.GifImageView;

/**
 * Created by LilWind NTS on 10/09/2019.
 * ABBA Studio
 * admin@blogsv.net
 */
public class LiActivity extends AppCompatActivity {
    GifImageView gifImageView;
    WebView webView;
    Button btnCraw;
    ExecutorService service;
    ExecutorService threadPool;
    RepositoryDATA repositoryDATA;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_content_craw);
        repositoryDATA = new RepositoryDATA(getApplication());
        service = Executors.newSingleThreadExecutor();
        threadPool = Executors.newFixedThreadPool(30);
        addControls();
        addEvents();
    }

    @SuppressLint("SetJavaScriptEnabled")
    private void addControls() {
        gifImageView = findViewById(R.id.img_cao);
        webView = findViewById(R.id.webview);
        btnCraw = findViewById(R.id.btnSubmit);
        webView.setWebChromeClient(new WebChromeClient());
        webView.setWebViewClient(new WebViewClient());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            webView.getSettings().setUserAgentString("Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.65 Mobile Safari/537.36");
        } else {
            webView.getSettings().setUserAgentString("Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/_BuildID_) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36");
        }
        webView.getSettings().setJavaScriptEnabled(true);
    }

    private void addEvents() {
        btnCraw.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                gifImageView.setVisibility(View.VISIBLE);
                service.execute(new Runnable() {
                    @Override
                    public void run() {
                        crawData();

                    }
                });
            }
        });

    }

    private void crawData() {
        try {
            Document document = Jsoup.connect("https://vietjack.com/giai-bai-tap-vat-ly-12/index.jsp").get();
            Element body = document.getElementsByClass("col-md-7 middle-col").get(0);
            System.out.println("data  body " + body.text());
            body.getElementsByClass("ads_txt").remove();
            body.getElementsByClass("ads_ads").remove();
            body.getElementsByClass("vj-more").remove();
            System.out.println("data c1" + body);
            for (Element e :
                    body.children()) {
                if (!e.tagName().equals("h2")) {
                    e.remove();
                } else {
                    break;
                }
            }
            for (final Element e : body.children()
            ) {
                if (e.tagName().equals("h3") && !e.attr("style").isEmpty()) {
                    break;
                }
                if (e.tagName().equals("h2")) {
                    LyEntity data = new LyEntity();
                    data.setH2(e.text());
                    repositoryDATA.insertLy(data);
                } else if (e.tagName().equals("h3")) {
                    LyEntity data = new LyEntity();
                    data.setH3(e.text());
                    repositoryDATA.insertLy(data);
                } else if (e.tagName().equals("ul")) {
                    for (final Element li : e.getElementsByTag("li"
                    )) {
                        System.out.println("ten bai hoc" + li.text().substring(0, 6));
                        if (li.text().contains("Bài 29:")) {
                            System.out.println("vào bài 13 rồi nè");
                            Runnable runnable = new Runnable() {
                                @Override
                                public void run() {
                                    synchronized (this) {
                                        try {
                                            String ulTitle = li.getElementsByTag("b").text();
                                            LyEntity data = new LyEntity();
                                            data.setUl(ulTitle);
                                            repositoryDATA.insertLy(data);
                                            String href = li.getElementsByTag("a").attr("href");
                                            if (href.contains("..")) {
                                                href = href.replace("..", "https://vietjack.com");
                                            }
                                            System.out.println(href);
                                            Document document1 = Jsoup.connect(href).get();
                                            Element body = document1.getElementsByClass("col-md-7 middle-col").get(0);
                                            body.getElementsByClass("ads_txt").remove();
                                            body.getElementsByClass("ads_ads").remove();
                                            body.getElementsByClass("vj-more").remove();
                                            body.getElementsByClass("baner-commer").remove();
                                            System.out.println("data c2" + body);
                                            boolean delete = true;
                                            for (Element e : body.children()) {
                                                if (delete) {
                                                    if (e.tagName().contains("h2")) {
                                                        delete = false;
                                                    } else {
                                                        e.remove();
                                                    }
                                                } else {
                                                    if (e.text().contains("Tham khảo")) {
                                                        e.remove();
                                                        delete = true;
                                                    }
                                                }
                                            }
                                            for (final Element e : body.children()
                                            ) {
                                                System.out.println("bai 29" +e.text());
//                                                if (e.tagName().equals("h3")) {
//                                                    break;
//                                                }
                                                if (e.tagName().equals("h2")) {
//                                                LyEntity data = new LyEntity();
//                                                data.setH2(e.text());
//                                                repositoryDATA.insertLy(data);
                                                } else if (e.tagName().equals("h3")) {
                                                    LyEntity datan = new LyEntity();
                                                    datan.setH3(e.text());
                                                    repositoryDATA.insertLy(datan);
                                                } else if (e.tagName().equals("ul")) {
                                                    for (final Element li : e.getElementsByTag("li"
                                                    )) {
                                                        System.out.println("aaaaaaaaaaaa" + li.text().substring(0, 7));
                                                        Runnable runnable = new Runnable() {
                                                            @Override
                                                            public void run() {
                                                                synchronized (this) {
                                                                    try {
                                                                        String ulTitle = li.getElementsByTag("b").text();
                                                                        String href = li.getElementsByTag("a").attr("href");
                                                                        if (href.contains("..")) {
                                                                            href = href.replace("..", "https://vietjack.com");
                                                                        }
                                                                        System.out.println(href);
                                                                        Document document1 = Jsoup.connect(href).get();
                                                                        Element body = document1.getElementsByClass("col-md-7 middle-col").get(0);
                                                                        body.getElementsByClass("ads_txt").remove();
                                                                        body.getElementsByClass("ads_ads").remove();
                                                                        body.getElementsByClass("vj-more").remove();
                                                                        body.getElementsByClass("baner-commer").remove();
                                                                        System.out.println("data c3" + body);
                                                                        for (int i = 0; i < body.childNodeSize(); i++) {
                                                                            Node child = body.childNode(i);
                                                                            if (child.nodeName().equals("#comment")) {
                                                                                child.remove();
                                                                            }
                                                                        }
                                                                        boolean delete = true;
                                                                        for (Element e :
                                                                                body.children()) {

                                                                            if (delete) {
                                                                                if (e.tagName().contains("h2") || e.text().contains("Bài") || e.text().contains("Lý thuyết")) {
                                                                                    delete = false;
                                                                                } else {
                                                                                    e.remove();
                                                                                }
                                                                            } else {
                                                                                if (e.tagName().equals("p") && e.text().length() > 10 && e.text().substring(0, 10).contains("Tham khảo") || e.tagName().equals("p") && e.text().length() > 8 && e.text().substring(0, 8).contains("Các bài")) {
                                                                                    e.remove();
                                                                                    delete = true;
                                                                                }
                                                                            }
                                                                        }
                                                                        for (final Element eimg : body.getElementsByTag("img")) {
                                                                            Runnable runnable1 = new Runnable() {
                                                                                @Override
                                                                                public void run() {
                                                                                    synchronized (this) {
                                                                                        try {
                                                                                            String urlImg = eimg.attr("src");
                                                                                            if (urlImg.contains("..")) {
                                                                                                urlImg = urlImg.replace("..", "https://vietjack.com");
                                                                                            }
                                                                                            String[] splitss = urlImg.split("/");
                                                                                            String fileName = splitss[splitss.length - 1];
                                                                                            System.out.println("urlImge  " + urlImg + fileName);
                                                                                            eimg.attr("src", "http://abbaserver2.com/app/sachgiai/sgk12/ly/" + fileName);
                                                                                            final DownloadFile downloadFile = new DownloadFile(urlImg, fileName, "ly", getApplicationContext());
                                                                                            if (!urlImg.isEmpty() && urlImg != null) {
                                                                                                downloadFile.download();
                                                                                            }
                                                                                        } catch (Exception e1) {
                                                                                            System.out.println(e1);
                                                                                        }
                                                                                    }
                                                                                }
                                                                            };
                                                                            try {
                                                                                Thread exec = new Thread(runnable1);
                                                                                exec.start();
                                                                                exec.join();
                                                                            } catch (Exception exx) {
                                                                                exx.printStackTrace();
                                                                            }
                                                                        }

                                                                        String style = "<style>.color-green{color:#008000}</style>";
                                                                        LyEntity data = new LyEntity();
                                                                        data.setUl2(ulTitle);
                                                                        data.setContentUl(style + body.toString());
                                                                        repositoryDATA.insertLy(data);
                                                                        Log.d("content finish", "run: " + body.toString());
                                                                    } catch (Exception e) {
                                                                        e.printStackTrace();
                                                                    }

                                                                }
                                                            }
                                                        };
                                                        try {
                                                            Thread exec = new Thread(runnable);
                                                            exec.start();
                                                            exec.join();
                                                        } catch (Exception exx) {
                                                            exx.printStackTrace();
                                                        }

                                                    }
                                                }

                                            }
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
                                    }
                                }
                            };
                            try {
                                Thread exec = new Thread(runnable);
                                exec.start();
                                exec.join();
                            } catch (Exception exx) {
                                exx.printStackTrace();
                            }
                        } else if (!li.text().contains("Bài 29:")){
                            Runnable runnable = new Runnable() {
                                @Override
                                public void run() {
                                    synchronized (this) {
                                        try {
                                            String ulTitle = li.getElementsByTag("b").text();
                                            LyEntity data = new LyEntity();
                                            data.setUl(ulTitle);
                                            repositoryDATA.insertLy(data);
                                            String href = li.getElementsByTag("a").attr("href");
                                            if (href.contains("..")) {
                                                href = href.replace("..", "https://vietjack.com");
                                            }
                                            System.out.println(href);
                                            Document document1 = Jsoup.connect(href).get();
                                            Element body = document1.getElementsByClass("col-md-7 middle-col").get(0);
                                            body.getElementsByClass("ads_txt").remove();
                                            body.getElementsByClass("ads_ads").remove();
                                            body.getElementsByClass("vj-more").remove();
                                            body.getElementsByClass("baner-commer").remove();
                                            System.out.println("data c2" + body);
                                            boolean delete = true;
                                            for (Element e : body.children()) {
                                                if (delete) {
                                                    if (e.tagName().contains("h2")) {
                                                        delete = false;
                                                    } else {
                                                        e.remove();
                                                    }
                                                } else {
                                                    if (e.tagName().equals("p") && e.text().length() > 8 && e.text().contains("Tham khảo")) {
                                                        e.remove();
                                                        delete = true;
                                                    }
                                                }
                                            }
                                            for (final Element e : body.children()
                                            ) {
                                                if (e.tagName().equals("h3") && !e.attr("style").isEmpty()) {
                                                    break;
                                                }
                                                if (e.tagName().equals("h2")) {
//                                                LyEntity data = new LyEntity();
//                                                data.setH2(e.text());
//                                                repositoryDATA.insertLy(data);
                                                } else if (e.tagName().equals("h3")) {
                                                    LyEntity datan = new LyEntity();
                                                    datan.setH3(e.text());
                                                    repositoryDATA.insertLy(datan);
                                                } else if (e.tagName().equals("ul")) {
                                                    for (final Element li : e.getElementsByTag("li"
                                                    )) {
                                                        System.out.println("bbbbbbbbbb" + li.text().substring(0, 7));
                                                        Runnable runnable = new Runnable() {
                                                            @Override
                                                            public void run() {
                                                                synchronized (this) {
                                                                    try {
                                                                        String ulTitle = li.getElementsByTag("b").text();
                                                                        String href = li.getElementsByTag("a").attr("href");
                                                                        if (href.contains("..")) {
                                                                            href = href.replace("..", "https://vietjack.com");
                                                                        }
                                                                        System.out.println(href);
                                                                        Document document1 = Jsoup.connect(href).get();
                                                                        Element body = document1.getElementsByClass("col-md-7 middle-col").get(0);
                                                                        body.getElementsByClass("ads_txt").remove();
                                                                        body.getElementsByClass("ads_ads").remove();
                                                                        body.getElementsByClass("vj-more").remove();
                                                                        body.getElementsByClass("baner-commer").remove();
                                                                        System.out.println("data c3" + body);
                                                                        for (int i = 0; i < body.childNodeSize(); i++) {
                                                                            Node child = body.childNode(i);
                                                                            if (child.nodeName().equals("#comment")) {
                                                                                child.remove();
                                                                            }
                                                                        }
                                                                        boolean delete = true;
                                                                        for (Element e :
                                                                                body.children()) {

                                                                            if (delete) {
                                                                                if (e.tagName().contains("h2")) {
                                                                                    delete = false;
                                                                                } else {
                                                                                    e.remove();
                                                                                }
                                                                            } else {
                                                                                if (e.tagName().equals("p") && e.text().length() > 10 && e.text().substring(0, 10).contains("Tham khảo") || e.tagName().equals("p") && e.text().length() > 8 && e.text().substring(0, 8).contains("Các bài")) {
                                                                                    e.remove();
                                                                                    delete = true;
                                                                                }
                                                                            }
                                                                        }
                                                                        for (final Element eimg : body.getElementsByTag("img")) {
                                                                            Runnable runnable1 = new Runnable() {
                                                                                @Override
                                                                                public void run() {
                                                                                    synchronized (this) {
                                                                                        try {
                                                                                            String urlImg = eimg.attr("src");
                                                                                            if (urlImg.contains("..")) {
                                                                                                urlImg = urlImg.replace("..", "https://vietjack.com");
                                                                                            }
                                                                                            String[] splitss = urlImg.split("/");
                                                                                            String fileName = splitss[splitss.length - 1];
                                                                                            System.out.println("urlImge  " + urlImg + fileName);
                                                                                            eimg.attr("src", "http://abbaserver2.com/app/sachgiai/sgk12/ly/" + fileName);
                                                                                            final DownloadFile downloadFile = new DownloadFile(urlImg, fileName, "ly", getApplicationContext());
                                                                                            if (!urlImg.isEmpty() && urlImg != null) {
                                                                                                downloadFile.download();
                                                                                            }
                                                                                        } catch (Exception e1) {
                                                                                            System.out.println(e1);
                                                                                        }
                                                                                    }
                                                                                }
                                                                            };
                                                                            try {
                                                                                Thread exec = new Thread(runnable1);
                                                                                exec.start();
                                                                                exec.join();
                                                                            } catch (Exception exx) {
                                                                                exx.printStackTrace();
                                                                            }
                                                                        }

                                                                        String style = "<style>.color-green{color:#008000}</style>";
                                                                        LyEntity data = new LyEntity();
                                                                        data.setUl2(ulTitle);
                                                                        data.setContentUl(style + body.toString());
                                                                        repositoryDATA.insertLy(data);
                                                                        Log.d("content finish", "run: " + body.toString());
                                                                    } catch (Exception e) {
                                                                        e.printStackTrace();
                                                                    }

                                                                }
                                                            }
                                                        };
                                                        try {
                                                            Thread exec = new Thread(runnable);
                                                            exec.start();
                                                            exec.join();
                                                        } catch (Exception exx) {
                                                            exx.printStackTrace();
                                                        }

                                                    }
                                                }

                                            }
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
                                    }
                                }
                            };
                            try {
                                Thread exec = new Thread(runnable);
                                exec.start();
                                exec.join();
                            } catch (Exception exx) {
                                exx.printStackTrace();
                            }
                        }

                    }
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

Giải thích một chút về file code

Như đã nói Jsoup là một thư viện của Java để cung câp một bộ các API cho việc trích xuất và thao tác các file HTML . Có một vài phương thức cho việc đọc và phân tích một trang HTML , trong trường hợp của chúng ta, chúng ta muốn lấy một vài thông tin từ một trang HTML trên server ở xa và chúng ta phải cung cấp một URL. Nếu chúng ta muốn phân tích trang như là DOM,

 Document document = Jsoup.connect("https://vietjack.com/giai-bai-tap-vat-ly-12/index.jsp").get();
            Element body = document.getElementsByClass("col-md-7 middle-col").get(0);

document là một biến thuộc class Document để lưu trữ những tài liệu đã được lấy về. Bây giờ chúng ta đã có Document và chúng ta có thể tự do trích xuất thông tin. Chúng ta có thể lấy title và những thông tin khác đang được sử dụng trong các Tag HTML

Jsoup.connect("https://vietjack.com/giai-bai-tap-vat-ly-12/index.jsp").get(); 

Nó sẽ tạo Document từ địa chỉ link trên

Và trong phần bóc tách dữ liệu từ document được giới thiệu ở phía dưới, mình cũng sẽ sử dụng cách này.

Bóc tách dữ liệu từ Document

document.getElementsByClass("col-md-7 middle-col").get(0);

nó sẽ lấy toàn bộ nội dung của thẻ "col-md-7 middle-col" đầu tiên trong document trên.

 body.getElementsByClass("ads_txt").remove();

ở đây mình sẽ xóa đi các element mà sử dụng hoặc không cần thiết vì dụ trên thì mình xóa các element quảng cáo theo class "ads", tương tự thì bạn cũng có thể xóa đi các element khác.

 for (final Element e : body.children()) 

children() method trả về các direct children của selected element.

Method này chỉ traverse một level thấp xuống DOM tree.

Nó gắn e cho lần lượt từng thẻ con trong body.

Link project

ToolJackviet


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí