Site icon Mobilhanem

Android Jsoup ile HTML Parsing

Merhaba arkadaşlar,  Bugün sizlere Jsoup kütüphanesi kullanımı ile HTML parse işleminin nasıl gerçekleştirileceğini anlatacağım. HTML Parse , HTML ayrıştırma anlamına gelmektedir.   Herhangi bir Html sayfasından istediğimiz yerleri alabilir ve uygulamalarımızda kullanabiliriz. Örneğin web sitemizi , mobil uygulamaya dönüştürmek istiyoruz diyelim; web sitemizin html sayfasında bulunan tag leri ayrıştırarak verileri elde ederiz, bunu da uygulamamızda şekillendiririz.

Jsoup ise Java programlama diline ait açık kaynak kodlu html parser kütüphanesidir. Html element lerine ulaşmamız için bu kütüphaneyi kullanacağız , bu kütüphaneyi kullanabilmek için de projemize import etmemiz gerekiyor.

http://www.mobilhanem.com sitemizden bir kaç veri çekip uygulamamızda gösterelim Android Studio yu açıyoruz Gradle Scripts segmesinden build.gradle a aşağıdaki kodu yapıştırıyoruz, yapıştırdıktan sonra uygulamanızı  Rebuild project yapmayı unutmayın. Android Studio arka planda derleme işlemlerini tamamladıktan sonra artık Jsoup kütüphanemizi kullanabilir duruma geleceğiz.

compile 'org.jsoup:jsoup:1.7.3'

Az çok web sayfası kavramından anlayanlarımız bilir ki html tag larını oluştururken id ler kullanabiliriz yada class tag ı vererek onun içinde şekillendirmeler yapabiliriz. Jsoup kütüphanesinin mantığı ise , istenilen url ye bağlantıyı gerçekleştirip , select komutu ile html tag lerine ulaşarak verileri elde etmemizi sağlamaktır. Internet üzerinden bu verilere ulaşmak istediğimiz için Async Task yapısını kullanacağız. Nasıl Json Parse işlemlerinde bu yapıyı kullanıyorsak, Html Parse yaparken de bu yapıyı kullanmamız doğru olacaktır.

url ye bağlantıyı şu şekilde sağlayacağız.

Document doc  = Jsoup.connect(URL).get();

URL yazan kısma ulaşmak istediğimiz web sayfasının linkini vermemiz yeterli.

Daha sonra Html elemanlarına ulaşabilmek için belli başlı select komutları var onlardan ihtiyacımız olanları kullanacağız. Daha detaylı komutlara bakmak için tıklayınız.

html <div id=”yourDivName”> tag lerine ulaşabilmek için “#” kullanarak aşağıdaki gibi yazıyoruz.

Elements info = doc.select("div#yourDivName");

Elements info = doc.select("div[id=yourDivName"); // alternatif olarak bunuda kullanabilirsiniz.

html <div class=”yourClassName”> tagıne ulaşabilmek için “.” kullanarak aşağıdaki gibi yazıyoruz.

Elements info = doc.select("div.yourClassName");

Elements info = doc.select("div[class=yourClassName"); // alternatif olarak bunuda kullanabilirsiniz.

Yayınlamış olduğum Parse SDK ile Anlık Bildirim dersi sayfasından verileri çekeceğiz. Burada yer alan site başlığını , açıklamasını ve sitemizin logosunu çekmeye çalışalım. Uygulamamızda 4 adet buton bulunuyor. Bu butonların ne işe yaradığını kaynak kodların içinde yorum olarak belirttim.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent"  tools:context=".MainActivity">


    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/linearLayout">

        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Başlık Göster"
            android:id="@+id/buttonTitle" />

        <LinearLayout
            android:visibility="gone"
            android:id="@+id/title_layout"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">

            <TextView
                android:textStyle="bold"
                android:id="@+id/txt_title"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" />


        </LinearLayout>

        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Açıklama Göster"
            android:id="@+id/buttonDesc" />

        <LinearLayout
            android:visibility="gone"
            android:id="@+id/desc_layout"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">


            <TextView
                android:textStyle="bold"
                android:id="@+id/txt_desc"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" />


        </LinearLayout>

        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Logo Göster"
            android:id="@+id/buttonImage" />

        <LinearLayout
            android:visibility="gone"
            android:id="@+id/logo_layout"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:background="#0000ff"
                android:id="@+id/img_logo"
                android:layout_width="fill_parent"
                android:layout_height="100dp" />


        </LinearLayout>

        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Yazarlar Göster"
            android:id="@+id/buttonYazarlar" />

        <LinearLayout
            android:visibility="gone"
            android:id="@+id/yazarlar_layout"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">


            <TextView
                android:textStyle="bold"
                android:id="@+id/txt_yazarlar"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" />


        </LinearLayout>
    </LinearLayout>


</RelativeLayout>

 

MainAcitivity sınıfımız aşağıdadır.

MainActivity.java

package com.mobilhanem.htmlparsingandroid;

import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.InputStream;


public class MainActivity extends Activity {

    private Button titleButton, descButton, logoButton, yazarlarButton;
    LinearLayout title_layout, desc_layout, logo_layout, yazarlar_layout;
    private ProgressDialog progressDialog;
    private static String URL = "http://www.mobilhanem.com/parse-sdk-ile-anlik-bildirim-gonderme-push-notification/";
    private static String baseUrl = "http://www.mobilhanem.com/";
    private static String authorUrl = "http://www.mobilhanem.com/yazarlar/";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        titleButton = (Button)findViewById(R.id.buttonTitle);
        descButton = (Button)findViewById(R.id.buttonDesc);
        logoButton = (Button)findViewById(R.id.buttonImage);
        yazarlarButton = (Button)findViewById(R.id.buttonYazarlar);

        titleButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                new FetchTitle().execute(); // başlık çekmek için
            }
        });

        descButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                new FetchDescription().execute(); // açıklama çekmek için
            }
        });

        logoButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                new FetchImageLogo().execute();  // logo çekmek için
            }
        });

        yazarlarButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                new FetchYazarlar().execute();    // yazarlar kısmını çekmek için
            }
        });

    }
    private class FetchTitle extends AsyncTask<Void, Void, Void> {

        String title;
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog = new ProgressDialog(MainActivity.this);
            progressDialog.setTitle("BAŞLIK");
            progressDialog.setMessage("Başlık Çekiliyor...");
            progressDialog.setIndeterminate(false);
            progressDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {

            try{

                Document doc  = Jsoup.connect(URL).get();    // web siteye bağlantıyı gerçeleştirme

                title = doc.title();  // ilgili sayfanın başlığını almak için

            }catch (Exception e){

                e.printStackTrace();
            }


            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {

            title_layout = (LinearLayout)findViewById(R.id.title_layout);
            TextView txt_title = (TextView)findViewById(R.id.txt_title);
            title_layout.setVisibility(View.VISIBLE);
            txt_title.setText("Title: " + "" + title);
            progressDialog.dismiss();
        }
    }

    private class FetchDescription extends AsyncTask<Void, Void, Void> {

        String desc;
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog = new ProgressDialog(MainActivity.this);
            progressDialog.setTitle("AÇIKLAMA");
            progressDialog.setMessage("Açıklama Çekiliyor...");
            progressDialog.setIndeterminate(false);
            progressDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {

            try{

                Document doc  = Jsoup.connect(URL).get();
                Elements elements = doc.select("meta[name=description]");  // ilgili sayfanın açıklamasını almak için
                desc = elements.attr("content");


            }catch (Exception e){

                e.printStackTrace();
            }


            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {

            desc_layout = (LinearLayout)findViewById(R.id.desc_layout);
            TextView txt_desc = (TextView)findViewById(R.id.txt_desc);
            desc_layout.setVisibility(View.VISIBLE);
            txt_desc.setText("Description: " + "" + desc);
            progressDialog.dismiss();
        }
    }

    private class FetchImageLogo extends AsyncTask<Void, Void, Void> {

        Bitmap bitmap;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog = new ProgressDialog(MainActivity.this);
            progressDialog.setTitle("LOGO");
            progressDialog.setMessage("Logo Çekiliyor...");
            progressDialog.setIndeterminate(false);
            progressDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {

            try{

                Document doc  = Jsoup.connect(baseUrl).get();
                Elements elements = doc.select("img[src]");
                String imgSrc = elements.attr("src");
                InputStream input = new java.net.URL(imgSrc).openStream();
                bitmap = BitmapFactory.decodeStream(input);

            }catch (Exception e){

                e.printStackTrace();
            }


            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {

            logo_layout = (LinearLayout)findViewById(R.id.logo_layout);
            ImageView img_logo = (ImageView)findViewById(R.id.img_logo);
            logo_layout.setVisibility(View.VISIBLE);
            img_logo.setImageBitmap(bitmap);
            progressDialog.dismiss();
        }
    }

    private class FetchYazarlar extends AsyncTask<Void, Void, Void> {

        String authors;
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog = new ProgressDialog(MainActivity.this);
            progressDialog.setTitle("YAZARLAR");
            progressDialog.setMessage("Yazarlar Çekiliyor...");
            progressDialog.setIndeterminate(false);
            progressDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {

            try{

                Document doc  = Jsoup.connect(authorUrl).get();
                Elements elements = doc.select("div[class=post-content]");  // class ismi post-content olan verileri çekmek için
                authors = elements.text();

            }catch (Exception e){

                e.printStackTrace();
            }


            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {

            yazarlar_layout = (LinearLayout)findViewById(R.id.yazarlar_layout);
            TextView txt_yazarlar = (TextView)findViewById(R.id.txt_yazarlar);
            yazarlar_layout.setVisibility(View.VISIBLE);
            txt_yazarlar.setText(authors);
            progressDialog.dismiss();
        }
    }
}

MainActivity sınıfımızda yer alan kodları incelemeye başlayalım. Uygulamayı çalıştırdığınız zaman göreceksiniz ki ilk butona tıklandığı an ilgili sayfanın başlığını çekip ekrana yazdırıyoruz. Bunu FetchTitle ismini verdiğim methodu incelersek eğer Async Task yapısında bildiğiniz üzere ilk olarak onPreExecute methodu çalışıyor orada kullanıcıya mesajı gösteriyoruz ve hemen ardından çalışan doInBackground methodu ile ilgili url ye bağlanıyoruz. ( http://www.mobilhanem.com/parse-sdk-ile-anlik-bildirim-gonderme-push-notification/ )  bu sayfamızda çekmeye çalıştığımız başlık kısmına sayfanın source-code nu görüntüleyerek bakarsak eğer ; resimde de görüldüğü gibi title kısmında yer alan yazıyı onPostExecute methodunda TextView e yazdırdık.

İkinci butona tıklandığı zaman ise FetchDescription isimli method çalışarak; ilgili sayfanın açıklaması çekilip ekrana yazdırılıyor. Yukarıda anlatmış olduğum yapı burası içinde geçerli bu yüzden tekrardan aynı şeylerden bahsetmeyeceğim. meta tagında yer alan description un content değişkenine  ulaştıktan sonra bunu TextView e yazdırıyoruz. Bu veriyi çektiğimiz ilgili sayfanın html görüntüsüne bakacak olursak ;

Üçüncü butona tıklandığı zaman ise FetchImageLogo isimli method çalışarak; ilgili sayfanın logo su çekilip ekranda gösteriliyor. Bu dersimizin kaynak kodunu incelerseniz eğer, başka bir url segmesine bağlantıyı gerçekleştirdiğimi göreceksiniz. Burada ilgili web sayfalarının farklı kısımlarına da ulaşabileceğimizi göstermek istedim. Sayfanın logo sunu çekerken img[src] ifadesini kullandığımı göreceksiniz burada sayfanın kaynak resim dosyasını çekebilmemiz için gerekli olan bu kodu kullanarak, çekilen veriyi önce Bitmap e çevirip daha sonra ImageView e set ettik.  Logo yu çektiğimiz ilgili sayfanın html görüntüsüne bakacak olursak ;

 

ve son olarak dördüncü butona basıldığında FetchYazarlar methodunu çağırdık burada yine ilgili web sitesinin başka bir sayfasına bağlantıyı gerçekleştirdik ve yazarlar bölümünü çekip ekrana yazdırdık. Zaten bağlantıyı kurduğumuz url yi görüntüleyecek olursanız class adının post-content verildiğini göreceksiniz, div[class=post-content] komutunu kullanarak gerekli işlemleri gerçekleştirdik. Yazarlar kısmını çektiğimiz ilgili sayfanın html görüntüsüne bakacak olursak ;

Html parse nasıl yapılır böylece sizlere göstermiş oldum, gerçekten çok kullanışlı ve  biraz html bilginiz var ise bunu Android ile birleştirip işinize yarayabilecek işlemleri kolayca gerçekleştirebilirsiniz. Jsoup mantığını ilerletmek istiyorsanız eğer uygulamalarınızda kullanmadan önce online-tool kullanarak alıştırmalar yapabilirsiniz.     ( http://try.jsoup.org/~iayWCMYVlvXEUrAws7ziRaMU3bM ) Kullanmak istediğiniz web sayfasına gelip sağ tıklayarak Inspect Element deyin ve html kodlarını seçip bu online-tool a yapıştırın. Daha sonrasında Jsoup daki Select komutlarını kullanmaya çalışın gerçekten çok işinize yaradığını göreceksiniz.

Tüm Android Ders, Proje ve Kaynak Kodlar için tıklayınız.

Ders hakkında soru ve önerilerinizi çekinmeden yorum bırakabilirsiniz. Bol Android’li günler sizin olsun 

Sizlerden ricamız facebook.com/mobilhanem sayfamızı beğenmenizdir. Diğer dersimde görüşmek üzere kendinize iyi bakın..

5

Exit mobile version