0

So I have this piece of code that uses JSoup that I thought wasn't working properly (as most things with JSoup require atleast a little bit of tinkering to get right). However, I kept trying and trying but my code just would not run in Android Studio. Finally, I tried my luck with Eclipse and alas, the same chunk of code was working fine! Of course, since I'm working on an app, I need this code to run on Android Studio, but I have no idea what to do to get it to run!

Here is the chunk of code that is running on Eclipse but not Studio:

String link= doc.select("div.searchTemplate.listLayout.so_us_en")
                        .select("div[id= topDynamicContent]")
                        .select("div.a-row.a-spacing-base.searchUndoAUIHacks")
                        .select("div.a-row")
                        .select("div.a-column.a-span8.a-spacing-none")
                        .select("div.s-first-column")
                        .select("h2.a-size-base.a-spacing-small.a-spacing-top-small.a-text-normal").first().text();
                System.out.println(link);
                int listSize= Integer.parseInt(link.substring(2,4));
                System.out.println(listSize); 

And here are the error messages that Studio is giving me:

08-09 23:46:30.939 32525-532/com.velesapp.jsouptutorial W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.jsoup.nodes.Element.text()' on a null object reference
08-09 23:46:30.939 32525-532/com.velesapp.jsouptutorial W/System.err:     at com.velesapp.jsouptutorial.MainActivity$getProductAttributes.doInBackground(MainActivity.java:82)
08-09 23:46:30.939 32525-532/com.velesapp.jsouptutorial W/System.err:     at com.velesapp.jsouptutorial.MainActivity$getProductAttributes.doInBackground(MainActivity.java:58)
08-09 23:46:30.939 32525-532/com.velesapp.jsouptutorial W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:305)
08-09 23:46:30.939 32525-532/com.velesapp.jsouptutorial W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
08-09 23:46:30.939 32525-532/com.velesapp.jsouptutorial W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
08-09 23:46:30.939 32525-532/com.velesapp.jsouptutorial W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
08-09 23:46:30.939 32525-532/com.velesapp.jsouptutorial W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
08-09 23:46:30.939 32525-532/com.velesapp.jsouptutorial W/System.err:     at java.lang.Thread.run(Thread.java:761)

For both IDEs, the imports are exactly the same, and I am running the process with an AsyncTask through Android Studio, but did not use any threads in Eclipse.

Here is the full code:

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;


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


public class MainActivity extends AppCompatActivity {
    Button but;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        but = (Button)findViewById(R.id.but1);
        but.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

               new getProductAttributes("https://www.amazon.com/s/ref=nb_sb_noss_1?url=search-alias%3Delectronics&field-keywords=rx+390").execute();


            }
        });



    }

    public class getProductAttributes extends AsyncTask<Void,Void,Void>{
        String url;
        int listSize;

        public getProductAttributes(String url){
            this.url = url;
        }
        protected Void doInBackground (Void... voids) {
          try{
                Document doc = Jsoup.connect(url).get();
                String link= doc.select("div.searchTemplate.listLayout.so_us_en")
                        .select("div[id= topDynamicContent]")
                        .select("div.a-row.a-spacing-base.searchUndoAUIHacks")
                        .select("div.a-row")
                        .select("div.a-column.a-span8.a-spacing-none")
                        .select("div.s-first-column")
                        .select("h2.a-size-base.a-spacing-small.a-spacing-top-small.a-text-normal").first().text();
                System.out.println(link);
                listSize= Integer.parseInt(link.substring(2,4));
                System.out.println(listSize);

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

                return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);


        }

Thanks for your time!

coolyfrost
  • 145
  • 10

1 Answers1

1

I checked your code and it's completely fine and working. On the other hand what's not working is, your first selection on the div container.

What I mean exactly is:

doc.select("div.searchTemplate.listLayout.so_us_en")

because listLayout is not existing in the DOM tree.

I did some research on the site you were parsing. And you should change listLayout to this: correctedResultsLayout.

Which will then result in the following:

String link = doc.select("div.searchTemplate.correctedResultsLayout.so_us_en")
                    .select("div[id= topDynamicContent]")
                    .select("div.a-row.a-spacing-base.searchUndoAUIHacks")
                    .select("div.a-row")
                    .select("div.a-column.a-span8.a-spacing-none")
                    .select("div.s-first-column")
                    .select("h2.a-size-base.a-spacing-small.a-spacing-top-small.a-text-normal").first().text();

As well I did some changes to your substring method:

        System.out.println(link);
        listSize = Integer.parseInt(link.substring(0, 2));
        System.out.println(listSize);

Which then will print the number of results found (in my case: 21)

Note: Keep in mind, that you may have to change this!

EDIT:

Just a little suggestion or improvement question for you. Wouldn't it be nicer/better to just search for a matching id, would it? In this case you could improve the readability of your own code.

For your selection this means - change the killer doc.select(....)... statement into a smaller much more readable:

String link = doc.select("h2#s-result-count").first().text();
r3dst0rm
  • 1,876
  • 15
  • 21
  • This works and somehow gets rid of the NullPointerException in Studio, thanks! Also thanks for the tip of searching for a matching id, that works much better than having to select a chain of elements. Thanks again! – coolyfrost Aug 10 '17 at 17:23