Hello All:
In application development, sometimes we want to parse HTML data to get relevant information. In this post I will show you how to parse HTML data using JSoup and Volley.
Let us start.
We will be using following external libraries
Below are some of the important classes to use. I will be sharing the link for fully functional code at the bottom of the post.
BaseApplication
Classes
Hope this helps. The full working code can be found here.
In application development, sometimes we want to parse HTML data to get relevant information. In this post I will show you how to parse HTML data using JSoup and Volley.
Let us start.
We will be using following external libraries
- JSoup: JSoup is a Java library for working with real-world HTML. It provides a very convenient API for extracting and manipulating data, using the best of DOM, CSS, and jquery-like methods. More info can be found here.
- Volley: Volley is an excellent framework to make network calls.More info can be found here.
- Interfaces
- IHTMLParser
- IAsyncCallback
- Classes
- HTMLParseAsyncTask: Extends Async task
- BlogPostParser: Implements IHTMLParser
- BaseHttpRequest: Main class to make network calls
Below are some of the important classes to use. I will be sharing the link for fully functional code at the bottom of the post.
BaseApplication
public class BaseApplication extends Application { private static BaseApplication sInstance; private RequestQueue mRequestQueue; public synchronized static BaseApplication getInstance() { return sInstance; } public RequestQueue getRequestQueue() { return mRequestQueue; } @Override public void onCreate() { super.onCreate(); sInstance = this; mRequestQueue = Volley.newRequestQueue(this); } }Interfaces
public interface IAsyncCallback { void onComplete(WebResponse responseContent); void onError(String errorData); }
public interface IHTMLParser { BaseObject parseHTML(String htmlToParse); }
Classes
public class BaseHttpRequest { ProgressDialog progressDialog; int responseCode; IAsyncCallback callback; Response.Listener<String> stringResponseListener; private IHTMLParser htmlParser; private String url; Response.ErrorListener errorListener = new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { StringWriter errors = new StringWriter(); error.printStackTrace(new PrintWriter(errors)); dismissProgressDialog(); callback.onError(error.toString()); } }; private Context context; public BaseHttpRequest(Activity localActivity, String url) { context = localActivity; this.url = url; setListeners(); } public IHTMLParser getHtmlParser() { return htmlParser; } public void setHtmlParser(IHTMLParser htmlParser) { this.htmlParser = htmlParser; } public IAsyncCallback getCallback() { return callback; } public Context getContext() { return context; } private void setListeners() { stringResponseListener = new Response.Listener<String>() { @Override public void onResponse(String response) { HTMLParseAsyncTask task = new HTMLParseAsyncTask(); task.setCurrentRequest(BaseHttpRequest.this); task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, response); } }; } public void dismissProgressDialog() { if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } } public void execute(IAsyncCallback callback, RequestQueue requestQueue) { this.callback = callback; progressDialog = new ProgressDialog(getContext()); progressDialog.setCancelable(false); progressDialog.setMessage("Please wait..."); dismissProgressDialog(); progressDialog.show(); addToRequestQueue(requestQueue, getStringRequest()); } public <X> void addToRequestQueue(RequestQueue requestQueue, Request<X> req) { requestQueue.add(req); } Request<String> getStringRequest() { return new StringRequest(Request.Method.GET, url, stringResponseListener, errorListener); } }
public class HTMLParseAsyncTask extends AsyncTask<String, Void, Void> { private BaseObject baseObject; private BaseHttpRequest currentRequest; public BaseHttpRequest getCurrentRequest() { return currentRequest; } public void setCurrentRequest(BaseHttpRequest currentRequest) { this.currentRequest = currentRequest; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Void doInBackground(String... params) { if (getCurrentRequest().getHtmlParser() != null) { baseObject = getCurrentRequest().getHtmlParser().parseHTML(params[0]); } return null; } @Override protected void onPostExecute(Void result) { getCurrentRequest().dismissProgressDialog(); try { WebResponse webResponse = new WebResponse(baseObject); getCurrentRequest().getCallback().onComplete(webResponse); } catch (Exception exception) { exception.printStackTrace(); } } }
public class BlogPostParser implements IHTMLParser { @Override public BaseObject parseHTML(String htmlToParse) { BlogResponse response = new BlogResponse(); try { Document doc = Jsoup.parse(htmlToParse); response.setPosts(new ArrayList<BlogPost>()); BlogPost post; Elements anchors = doc.select(".entry-header a"); for (Element anchor : anchors) { post = new BlogPost(); post.setURL(anchor.attr("href")); post.setText(anchor.text()); response.getPosts().add(post); } } catch (Exception exception) { exception.printStackTrace(); } return response; } }
public class MainActivity extends FragmentActivity { Button button; ListView listView; BlogResponse blogPosts; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); listView = (ListView) findViewById(R.id.listView); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try { BaseHttpRequest request = new BaseHttpRequest(MainActivity.this, "http://blog.ashwanik.in/search?max-results=50"); request.setHtmlParser(new BlogPostParser()); IAsyncCallback callback = new IAsyncCallback() { @Override public void onComplete(WebResponse responseContent) { blogPosts = (BlogResponse) responseContent.getTypedObject(); listView.setAdapter(new BlogPostAdapter(MainActivity.this)); } @Override public void onError(String errorData) { Toast.makeText(MainActivity.this, errorData, Toast.LENGTH_SHORT).show(); } }; request.execute(callback, BaseApplication.getInstance().getRequestQueue()); } catch (Exception e) { Toast.makeText(MainActivity.this, "Some error occurred.", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } } }); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { try { MainActivity.this.startActivity(new Intent(Intent.ACTION_VIEW, Uri .parse(blogPosts.getPosts().get(i).getURL()))); } catch (Exception exception) { exception.printStackTrace(); } } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } static class ViewHolder { TextView post; } public class BlogPostAdapter extends BaseAdapter { Activity context; ArrayList<BlogPost> arrayList; LayoutInflater inflater; public BlogPostAdapter(Activity context) { super(); this.context = context; this.arrayList = blogPosts.getPosts(); inflater = context.getLayoutInflater(); } public int getCount() { return arrayList.size(); } public BlogPost getItem(int position) { return arrayList.get(position); } public long getItemId(int position) { return 0; } public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; BlogPost metaData = getItem(position); if (convertView == null) { convertView = inflater.inflate(R.layout.r_blogpost, parent, false); holder = new ViewHolder(); holder.post = (TextView) convertView .findViewById(R.id.post); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.post.setText(metaData.getText()); return convertView; } } }
Hope this helps. The full working code can be found here.
Thanks for printing this post. Hope you liked it.
Keep visiting and sharing.
Thanks,
Ashwani.
Keep visiting and sharing.
Thanks,
Ashwani.
thanks for your qualified tutorial :)
ReplyDeletegreat work, thank you ; keep up the good work
ReplyDelete