1

So, I'm trying to extract JSON from the Guardian newspaper API.

Basically I can get everything except the author which is crucial.

How do or what is a different way of extracting this.

Many thanks in advance I'm new to all this and have asked questions i n the past to no avail any advice would be greatly appreciated.

QueryUtils.Java

    package com.example.android.newsapp;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;


public class QueryUtils {

    private static final String TAG = QueryUtils.class.getSimpleName();
    public static Context context;

    private QueryUtils() {

    }

    public static List<News> fetchNews(String requestUrl) {
        URL url = createUrl(requestUrl);
        String json_response = null;
        try {
            json_response = makeHttpRequest(url);
            Log.i(TAG, json_response);
        } catch (IOException e) {
            e.printStackTrace();
        }

        List<News> news = extractFromJson(json_response);

        return news;
    }

    private static URL createUrl(String StringUrl) {
        URL url = null;
        try {
            url = new URL(StringUrl);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        return url;
    }

    private static String makeHttpRequest(URL url) throws IOException {
        String json_response = "";

        if (url == null) {
            return json_response;
        }

        HttpURLConnection httpURLConnection = null;
        InputStream inputStream = null;

        try {
            httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setReadTimeout(10000);
            httpURLConnection.setConnectTimeout(15000);
            httpURLConnection.setRequestMethod("GET");
            httpURLConnection.connect();

            if (httpURLConnection.getResponseCode() == 200) {
                inputStream = httpURLConnection.getInputStream();
                json_response = readFromString(inputStream);
            } else {
                Log.e(TAG, "Error" + httpURLConnection.getResponseCode());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (httpURLConnection != null) {
                httpURLConnection.disconnect();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        }
        return json_response;
    }

    private static String readFromString(InputStream inputStream) throws IOException {
        StringBuilder output = new StringBuilder();
        if (inputStream != null) {
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
            BufferedReader reader = new BufferedReader(inputStreamReader);
            String line = reader.readLine();
            while (line != null) {
                output.append(line);
                line = reader.readLine();
            }
        }
        return output.toString();
    } private static String extractString(JSONObject newInfo, String stringName) {
        String str = null;

        try {
            str = newInfo.getString(stringName);
        } catch (JSONException e) {
            Log.e(TAG, context.getString(R.string.query_util_error_extract_string) + stringName);
        }

        if (str != null) {
            return str;
        } else {
            return context.getString(R.string.empty_string);
        }
    }

    private static List<News> extractFromJson(String news_json) {
        if (TextUtils.isEmpty(news_json)) {
            return null;
        }

        List<News> news = new ArrayList<News>();

        try {
            JSONObject baseJson = new JSONObject(news_json);
            JSONArray news_array = baseJson.getJSONObject("response").getJSONArray("results");

            for (int i = 0; i < news_array.length(); i++) {
                JSONObject currentNews = news_array.getJSONObject(i);
                String name = currentNews.getString("sectionName");
                String title = currentNews.getString("webTitle");
                String date = currentNews.getString("webPublicationDate");
                String url = currentNews.getString("webUrl");

                JSONArray tags = baseJson.getJSONArray("tags");


                String contributor = null;
                if (tags.length() == 1) {
                    JSONObject contributorTag = (JSONObject) tags.get(0);


                    contributor = extractString(contributorTag, context.getString(R.string.query_util_json_web_title));

                } else {
                    //no contributor
                    contributor = context.getString(R.string.empty_string);
                }

                    News mNews = new News(name, title, date, url, contributor);

                news.add(mNews);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return news;
    }
}

This is the JSON that I'm extracting from. https://content.guardianapis.com/search?q=debate&tag=politics/politics&from-date=2014-01-01&api-key=test

This is the Data-Provider.. http://open-platform.theguardian.com/documentation/

  • Have you tried adding `&show-tags=contributor` to your url? – Tom Alabaster Feb 20 '18 at 10:47
  • Yes Tom I have unfortunately I'm very lost but plodding on.......Do youo know any other good resourceful forums?? –  Feb 20 '18 at 15:22
  • I dont think you get author from guardian api. Just visit the web url returned in the json content for any article you will not see any author related info even on that site (web link) – BetaDev May 02 '18 at 17:24

1 Answers1

1

I too had trouble getting the author. There were two changes I made that resolved the issue.

First, I did have to change the add the &show-tags=contributor to the url.

Second, I had to tweak your your if statement in parsing to read. Instead of :

contributor = extractString(contributorTag, context.getString(R.string.query_util_json_web_title));

I replaced with :

contributor = contributorTag.getString("webTitle");

(The key "webTitle" contains the author's name)

A problem for you is the url you used doesn't give the tag array which contains the webTitle key, even after I adjusted it with the &show-tags=contributor.

The url I used is: http://content.guardianapis.com/search?&show-tags=contributor&q=%27tech%27&api-key=2bbbc59c-5b48-46a5-83d3-8435d3136348

The full QueryUtils.java file is:

package com.example.android.technewsapps1;

import android.text.TextUtils;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;


public final class QueryUtils {

    private static final String LOG_TAG = QueryUtils.class.getSimpleName();

    private QueryUtils() {
    }

    /**
     * Query the Guardian dataset and return a list of NewsStory objects.
     */
    public static List<NewsStory> fetchNewsStoryData(String requestUrl) {

        // Create URL object
        URL url = createUrl(requestUrl);

        // Perform HTTP request to the URL and receive a JSON response back
        String jsonResponse = null;
        try {
            jsonResponse = makeHttpRequest(url);
        } catch (IOException e) {
            Log.e(LOG_TAG, "Problem making the HTTP request.", e);
        }

        // Extract relevant fields from the JSON response and create a list of NewsStories
        List<NewsStory> newsStories = extractFeatureFromJson(jsonResponse);

        // Return the list of NewsStories
        return newsStories;
    }


    /**
     * Returns new URL object from the given String URL.
     */
    private static URL createUrl(String stringUrl) {
        URL url = null;
        try {
            url = new URL(stringUrl);
        } catch (MalformedURLException e) {
            Log.e(LOG_TAG, "Problem building the URL ", e);
        }
        return url;
    }

    /**
     * Make an HTTP request to the given URL and return a String as the response.
     */
    private static String makeHttpRequest(URL url) throws IOException {
        String jsonResponse = "";

        // If the URL is null, then return early.
        if (url == null) {
            return jsonResponse;
        }

        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;
        try {
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setReadTimeout(10000 /* milliseconds */);
            urlConnection.setConnectTimeout(15000 /* milliseconds */);
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            // If the request was successful (response code 200),
            // then read the input stream and parse the response.
            if (urlConnection.getResponseCode() == 200) {
                inputStream = urlConnection.getInputStream();
                jsonResponse = readFromStream(inputStream);
            } else {
                Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
            }
        } catch (IOException e) {
            Log.e(LOG_TAG, "Problem retrieving the newsStory JSON results.", e);
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (inputStream != null) {
                // Closing the input stream could throw an IOException, which is why
                // the makeHttpRequest(URL url) method signature specifies than an IOException
                // could be thrown.
                inputStream.close();
            }
        }
        return jsonResponse;
    }


    /**
     * Convert the {@link InputStream} into a String which contains the
     * whole JSON response from the server.
     */
    private static String readFromStream(InputStream inputStream) throws IOException {
        StringBuilder output = new StringBuilder();
        if (inputStream != null) {
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
            BufferedReader reader = new BufferedReader(inputStreamReader);
            String line = reader.readLine();
            while (line != null) {
                output.append(line);
                line = reader.readLine();
            }
        }
        return output.toString();


    }

    /**
     * Return a list of NewsStory objects that has been built up from
     * parsing the given JSON response.
     */
    private static List<NewsStory> extractFeatureFromJson(String newsStoryJSON) {
        // If the JSON string is empty or null, then return early.
        if (TextUtils.isEmpty(newsStoryJSON)) {
            return null;
        }

        // Create an empty ArrayList that we can start adding news stories to
        List<NewsStory> newsStories = new ArrayList<>();

        // Try to parse the JSON response string. If there's a problem with the way the JSON
        // is formatted, a JSONException exception object will be thrown.
        // Catch the exception so the app doesn't crash, and print the error message to the logs.
        try {

            // Create a JSONObject from the JSON response string
            JSONObject baseJsonResponse = new JSONObject(newsStoryJSON);

            //Create the JSONObject with the key "response"
            JSONObject responseJSONObject = baseJsonResponse.getJSONObject("response");
            //JSONObject responseJSONObject = baseJsonResponse.getJSONObject("response");

            // Extract the JSONArray associated with the key called "results",
            // which represents a list of news stories.
            JSONArray newsStoryArray = responseJSONObject.getJSONArray("results");

            // For each newsStory in the newsStoryArray, create an NewsStory object
            for (int i = 0; i < newsStoryArray.length(); i++) {

                // Get a single newsStory at position i within the list of news stories
                JSONObject currentStory = newsStoryArray.getJSONObject(i);

                // Extract the value for the key called "webTitle"
                String title = currentStory.getString("webTitle");

                // Extract the value for the key called "sectionName"
                String sectionName = currentStory.getString("sectionName");

                // Extract the value for the key called "webPublicationDate"
                String date = currentStory.getString("webPublicationDate");

                // Extract the value for the key called "url"
                String url = currentStory.getString("webUrl");

                //Extract the JSONArray with the key "tag"
                JSONArray tagsArray = currentStory.getJSONArray("tags");

                //Declare String variable to hold author name
                String authorName = null;

                if (tagsArray.length() == 1) {
                    JSONObject contributorTag = (JSONObject) tagsArray.get(0);
                    authorName = contributorTag.getString("webTitle");
                }

                // Create a new NewsStory object with the title, section name, date,
                // and url from the JSON response.
                NewsStory newsStory = new NewsStory(title, sectionName, date, url, authorName);

                // Add the new NewsStory to the list of newsStories.
                newsStories.add(newsStory);
            }

        } catch (JSONException e) {
            // If an error is thrown when executing any of the above statements in the "try" block,
            // catch the exception here, so the app doesn't crash. Print a log message
            // with the message from the exception.
            Log.e("QueryUtils", "Problem parsing the newsStory JSON results", e);
        }

        // Return the list of earthquakes
        return newsStories;
    }


}
Sven Eberth
  • 3,057
  • 12
  • 24
  • 29
Wallace S.
  • 26
  • 4