所以我有一段使用 JSoup 的代码,我认为它不能正常工作(因为 JSoup 的大多数事情至少需要一点点修改才能正确)。然而,我不断尝试,但我的代码无法在 Android Studio 中运行。最后,我用 Eclipse 碰碰运气,唉,同样的代码块运行得很好!当然,由于我正在开发一个应用程序,因此我需要此代码在 Android Studio 上运行,但我不知道该怎么做才能让它运行!
下面是在 Eclipse 上运行但不在 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);
以下是 Studio 给我的错误消息:
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)
对于这两个 IDE,导入完全相同,我通过 Android Studio 使用 AsyncTask 运行该进程,但没有在 Eclipse 中使用任何线程。
完整代码如下:
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);
}
感谢您的宝贵时间!
最佳答案
我检查了你的代码,它完全正常并且可以工作。
另一方面,不起作用的是您在 div
容器上的第一个选择。
我的意思是:
doc.select("div.searchTemplate.listLayout.so_us_en")
因为 DOM 树中不存在 listLayout
。
我对您正在解析的网站做了一些研究。您应该将 listLayout
更改为: CorrectedResultsLayout
。
这将导致以下结果:
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();
我还对您的 substring
方法做了一些更改:
System.out.println(link);
listSize = Integer.parseInt(link.substring(0, 2));
System.out.println(listSize);
然后将打印找到的结果数(在我的例子中:21)
注意:请记住,您可能必须更改此设置!
编辑:
只是给您一点建议或改进问题。只搜索匹配的 id 不是更好/更好吗?在这种情况下,您可以提高自己代码的可读性。
对于您的选择,这意味着 - 将 killer doc.select(....)...
语句更改为更小、更易读的语句:
String link = doc.select("h2#s-result-count").first().text();
关于java - 代码块在 Android Studio 中无法运行,但在 Eclipse 中运行良好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45604730/