0

I'm using Jsoup to parse an amazon link. I'm trying to figure out a way for the code to search for a specific element; if it finds it, complete action; if it doesn't, look for a different specific element and complete action etc.

Here's my code:

protected Void doInBackground(Void... params) {
        //String url = "http://www.amazon.com/gp/product/B00FRDUZXM/ref=s9_simh_gw_p14_d0_i2?pf_rd_m=ATVPDKIKX0DER&pf_rd_s=desktop-4&pf_rd_r=0ZV79CBKAVKNW0RD843D&pf_rd_t=36701&pf_rd_p=1970566762&pf_rd_i=desktop";
        String url = "http://www.amazon.com/VeggieTales-Very-Merry-Larry-Christmas/dp/B00H2T37SO/ref=pd_rhf_gw_p_img_3";
        //String url = "http://www.amazon.com/Sony-A7-A7R-Snapshots-Great/dp/0321968603/ref=pd_rhf_gw_p_img_4";
        try {
            // Connect to the web site
            Document document = Jsoup.connect(url).get();
            // Get the html document title
            Elements trs = document.select("table.a-lineitem");

            if(trs != null)
            {
                Elements tds = trs.select("span");
                Element price1 = tds.first();
                System.out.println(price1);
                String str1 = price1.text();
                System.out.println(str1);
                String str2 = str1.replaceAll( "[$,]", "" );
                double aInt = Double.parseDouble(str2);
                System.out.println("Price: " + aInt);
            }
            else
            {
                Elements prices = document.select("table.product b.priceLarge");

                if(prices != null)
                {
                    String priceWithCurrency = prices.text();
                    System.out.println(priceWithCurrency);
                    System.out.println(priceWithCurrency);
                    String priceAsText = priceWithCurrency.replaceAll( "[$,]", "" );
                    double priceAsNumber = Double.parseDouble(priceAsText);
                    System.out.println("Price: " + priceAsNumber);
                }
                else
                {
                    Elements prices2 = document.select("div.a-row span.a-size-medium a-color-price");

                    String priceWithCurrency2 = prices2.text();
                    System.out.println(priceWithCurrency2);
                    String priceAsText2 = priceWithCurrency2.replaceAll( "[$,]", "" );
                    double priceAsNumber2 = Double.parseDouble(priceAsText2);
                    System.out.println("Price: " + priceAsNumber2);
                }
            }

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

        return null;
    }

I'm positive I'm looking for the correct element on the page (as in, table.a-lineitem and the other two selected elements aren't the problem, so I have to assume it's something to do with my if/else statement. Any ideas?

Here's the error:

12-17 23:10:05.145  10907-11060/nathanieljones.amazonpricechecker E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #3
    Process: nathanieljones.amazonpricechecker, PID: 10907
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:300)
            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
            at java.util.concurrent.FutureTask.run(FutureTask.java:242)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.jsoup.nodes.Element.text()' on a null object reference
            at nathanieljones.amazonpricechecker.MainActivity$Title.doInBackground(MainActivity.java:102)
            at nathanieljones.amazonpricechecker.MainActivity$Title.doInBackground(MainActivity.java:73)
            at android.os.AsyncTask$2.call(AsyncTask.java:288)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
12-17 23:10:05.834  10907-10907/nathanieljones.amazonpricechecker E/WindowManager﹕ android.view.WindowLeaked: Activity nathanieljones.amazonpricechecker.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{12e2885 V.E..... R......D 0,0-959,322} that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:363)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:261)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
            at android.app.Dialog.show(Dialog.java:298)
            at nathanieljones.amazonpricechecker.MainActivity$Title.onPreExecute(MainActivity.java:83)
            at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:587)
            at android.os.AsyncTask.execute(AsyncTask.java:535)
            at nathanieljones.amazonpricechecker.MainActivity$1.onClick(MainActivity.java:57)
            at android.view.View.performClick(View.java:4756)
            at android.view.View$PerformClick.run(View.java:19749)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Nate
  • 15
  • 2
  • What is the question? You are calling `text()` on a null `Element`, so you get a NPE.. –  Dec 18 '14 at 07:15
  • possible duplicate of [What is a Null Pointer Exception, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it) –  Dec 18 '14 at 07:16
  • `at nathanieljones.amazonpricechecker.MainActivity$Title.doInBackground(MainActivity.java:102)` - so which line is MainActivity.java 102, and what is on that line? – user253751 Dec 18 '14 at 07:22
  • @immibis String str1 = price1.text(); – Nate Dec 18 '14 at 07:27
  • @Virt then price1 is null. – user253751 Dec 18 '14 at 07:43

1 Answers1

0
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.jsoup.nodes.Element.text()' on a null object reference

Seems like one of these element is null, which is causing error on call of .text()

Element price1 = tds.first();

or

Elements prices2 = document.select("div.a-row span.a-size-medium a-color-price");

Keep a null check before you call .text() just as you have put it for Element prices

if(price1 != null){
    //get String using .text()
}

and

if(prices2 != null){
    //get String using .text()
}

Hope this helps.

MysticMagicϡ
  • 28,593
  • 16
  • 73
  • 124
  • So first of all, thanks for the help! What I'm confused on is if there is any way to detect if "Elements trs = document.select("table.a-lineitem");" can't find "table.lineitem" because it isn't on that html page, can it instead look for a different Element like "table.product". – Nate Dec 18 '14 at 07:30
  • just check if that element returns null, and try to get other one. @Virt – MysticMagicϡ Dec 18 '14 at 07:32
  • But isn't that exactly what I'm doing in my Else statements? If not null, complete action. Else if null, check for different element. @MagicalPhoenixϡ – Nate Dec 18 '14 at 07:34
  • Yes, you are getting error when element is null and you try to get its text, put that condition – MysticMagicϡ Dec 18 '14 at 07:35
  • Oh, I think I understand. So for the first If statement, add a if/null statement after I select "span" and before price1.text()? @MagicalPhoenixϡ – Nate Dec 18 '14 at 07:42
  • Yup. exactly. Check if element is null or not before you actually call a method on that element :) – MysticMagicϡ Dec 18 '14 at 07:43
  • Thanks! I tried that, but it still brings up null pointer exception. It now says essentially: **Element trs = doc.select("span") --- if(trs != null) { Element price1 = trs.first(); --- String str1 = price1.text(); ---etc** so the element is selected, I check for a null, and then I call .text(). Shouldn't that get rid of the NPE? Sorry to keep bothering you, I really appreciate it. Just a bit frustrating. @MagicalPhoenixϡ – Nate Dec 18 '14 at 07:57
  • Check for price1 too. `if(price1 != null){String str1 = price1.text();}` – MysticMagicϡ Dec 18 '14 at 08:05
  • 1
    It works! Wow, thank you so much! This thing has been giving me a headache for hours. Really appreciate it! @MagicalPhoenixϡ – Nate Dec 18 '14 at 08:26