You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android开发问题:爬取多页网站数据时数组被覆盖而非追加

解决Android Jsoup多页抓取数据覆盖数组的问题

下午好,我是一名Android编程初学者,正在开发一个从网站抓取信息并展示到ListView的界面。仅抓取网站首页时代码可正常运行,但抓取第2页及更多页面时,新数据会覆盖整个数组而非追加到末尾。我已用尽现有知识仍未解决,推测是数组构建的低级错误,但无法独自找到解决方案。若有拼写错误请见谅,我使用了翻译工具。

原代码

package br.com.testejsoup.eu.testejsoup; 
import android.content.Intent; 
import android.os.AsyncTask; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import org.jsoup.Jsoup; 
import org.jsoup.nodes.Document; 
import org.jsoup.nodes.Element; 
import org.jsoup.select.Elements; 
import java.io.IOException; 

public class MainActivity extends AppCompatActivity { 
    private ListView conteudo; 
    String[] aniNomes; 
    String[] aniLinks; 
    ArrayAdapter<String> adaptador; 
    Document doc; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
        conteudo = findViewById(R.id.html_conteudo); 
        new doit().execute(); 
        conteudo.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
            @Override 
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
                int posicao = position; 
                Intent intent = new Intent(MainActivity.this, Episodio.class); 
                intent.putExtra("aniLinks", aniLinks[posicao]); 
                //Toast.makeText(getApplicationContext(), aniLinks[posicao], Toast.LENGTH_LONG).show(); 
                startActivity(intent); 
            } 
        }); 
    } 

    public class doit extends AsyncTask<Void, Void, Void>{ 
        String URL = "http://www.URL.com/lancamentos?page="; 
        String nomeExp; 
        Elements nome; 
        Elements links; 
        int paginas = 5; 

        @Override 
        protected Void doInBackground(Void... voids) { 
            try { 
                for (int i=1; i<= paginas;i++) { 
                    String new_URL = URL + i; 
                    doc = Jsoup.connect(new_URL).get(); 
                    nome = doc.select("div.nome-thumb a.tt"); 
                    links = doc.select("div.nome-thumb a.tt"); 
                    aniNomes = new String[nome.size()]; 
                    aniLinks = new String[links.size()]; 
                    for(Element nomeTemp : nome){ 
                        nomeExp = nomeTemp.text(); 
                        adaptador.add(nomeExp); 
                    } 
                } 
                for (int i = 0; i < nome.size(); i++) { 
                    aniNomes[i] = nome.get(i).text(); 
                } 
                for (int i = 0; i < links.size(); i++) { 
                    aniLinks[i] = links.get(i).attr("abs:HREF"); 
                } 
                adaptador = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, android.R.id.text1, aniNomes); 
            } catch (IOException e) { 
                e.printStackTrace(); 
            } 
            return null; 
        } 

        @Override 
        protected void onPostExecute(Void aVoid) { 
            super.onPostExecute(aVoid); 
            conteudo.setAdapter(adaptador); 
        } 
    } 
}

问题根源

你的核心问题在于使用了固定长度的数组String[]存储多页数据,且每次循环页面时都重新初始化数组:

  • 在页面循环里,每次执行aniNomes = new String[nome.size()]和aniLinks = new String[links.size()]都会彻底覆盖之前页面的数据;
  • 最后仅对最后一页的nome和links进行赋值,导致ListView只显示最后一页内容;
  • 提前调用adaptador.add(nomeExp)时adaptador还未初始化,会触发空指针异常。

修改后的完整代码

package br.com.testejsoup.eu.testejsoup; 
import android.content.Intent; 
import android.os.AsyncTask; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import org.jsoup.Jsoup; 
import org.jsoup.nodes.Document; 
import org.jsoup.nodes.Element; 
import org.jsoup.select.Elements; 
import java.io.IOException; 
import java.util.ArrayList; 

public class MainActivity extends AppCompatActivity { 
    private ListView conteudo; 
    // 改用ArrayList动态存储数据,支持无限制追加元素
    ArrayList<String> aniNomes = new ArrayList<>(); 
    ArrayList<String> aniLinks = new ArrayList<>(); 
    ArrayAdapter<String> adaptador; 
    Document doc; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
        conteudo = findViewById(R.id.html_conteudo); 
        new doit().execute(); 
        conteudo.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
            @Override 
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
                Intent intent = new Intent(MainActivity.this, Episodio.class); 
                // ArrayList用get(position)方法获取对应位置的元素
                intent.putExtra("aniLinks", aniLinks.get(position)); 
                startActivity(intent); 
            } 
        }); 
    } 

    public class doit extends AsyncTask<Void, Void, Void>{ 
        String URL = "http://www.URL.com/lancamentos?page="; 
        Elements nome; 
        Elements links; 
        int paginas = 5; 

        @Override 
        protected Void doInBackground(Void... voids) { 
            try { 
                for (int i=1; i<= paginas;i++) { 
                    String new_URL = URL + i; 
                    doc = Jsoup.connect(new_URL).get(); 
                    nome = doc.select("div.nome-thumb a.tt"); 
                    links = doc.select("div.nome-thumb a.tt"); 
                    // 将当前页的数据直接追加到ArrayList中
                    for (Element nomeT : nome){ 
                        aniNomes.add(nomeT.text()); 
                    } 
                    for (Element linkT : links){ 
                        aniLinks.add(linkT.attr("abs:HREF")); 
                    } 
                } 
            } catch (IOException e) { 
                e.printStackTrace(); 
            } 
            return null; 
        } 

        @Override 
        protected void onPostExecute(Void aVoid) { 
            super.onPostExecute(aVoid); 
            // 所有数据加载完成后,再初始化Adapter并绑定到ListView
            adaptador = new ArrayAdapter<>(getApplicationContext(), 
                    android.R.layout.simple_list_item_1, 
                    android.R.id.text1, 
                    aniNomes); 
            conteudo.setAdapter(adaptador); 
        } 
    } 
}

主要修改点

  1. 替换数组为ArrayList:固定长度数组无法动态追加数据,ArrayList可以灵活添加元素,完美解决数据覆盖问题;
  2. 移除循环内的数组初始化:删除了页面循环中重新创建数组的代码,避免覆盖之前的抓取结果;
  3. 调整Adapter初始化时机:将ArrayAdapter的初始化移到onPostExecute中,确保所有数据加载完成后再绑定到ListView;
  4. 适配ArrayList的元素访问方式:点击事件中用aniLinks.get(position)代替数组下标访问,符合集合类的使用规范;
  5. 移除无效的adaptador.add调用:原代码中提前调用该方法会触发空指针,现在直接将数据存入ArrayList,由Adapter自动处理展示。

内容的提问来源于stack exchange,提问作者wshr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:58:37