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

Android从指定网页提取表格数据并保存为字符串的实现方案

解决方案:Android Studio中提取指定网页的列表数据

嘿,我来帮你搞定这个网页数据提取的需求!在Android里要从指定URL抓取table>tr>td>ol>li路径下的文本内容,咱们可以借助Jsoup这个强大的HTML解析库来实现,不用自己手动写复杂的正则或者DOM解析逻辑。下面是一步步的具体方案:

1. 添加Jsoup依赖

首先,在你的Module级别的build.gradle文件(注意不是Project级的)里添加Jsoup的依赖,这样我们就能直接用它来解析HTML了:

dependencies {
    // 其他依赖...
    implementation 'org.jsoup:jsoup:1.17.2' // 可以替换为最新版本
}

2. 配置必要权限

在AndroidManifest.xml里添加网络请求权限,因为我们要访问外部网页:

<uses-permission android:name="android.permission.INTERNET" />

另外,如果你用的是Android 9(API 28)及以上版本,因为目标URL是HTTP明文地址,需要在application标签里允许明文流量:

<application
    // 其他属性...
    android:usesCleartextTraffic="true">
    // 活动、服务等配置...
</application>

3. 编写数据提取逻辑

Kotlin版本(推荐用协程处理异步)

在你的Activity或者ViewModel里,用协程来执行网络请求和HTML解析(避免阻塞主线程导致ANR):

import org.jsoup.Jsoup
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import android.util.Log
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    // 定义要保存的字符串变量
    private var string1: String = ""
    private var string2: String = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 启动协程执行网络操作
        GlobalScope.launch(Dispatchers.Main) {
            try {
                // 在IO线程中获取网页内容
                val document = withContext(Dispatchers.IO) {
                    Jsoup.connect("http://self.shahroodut.ac.ir/Ghaza.aspx?date=970229").get()
                }
                // 定位到所有符合路径的li元素
                val menuItems = document.select("table tr td ol li")
                
                // 提取前两个li的文本到string1和string2
                if (menuItems.size >= 2) {
                    string1 = menuItems[0].text().trim()
                    string2 = menuItems[1].text().trim()
                    // 这里可以测试输出,或者后续在应用中调用这些变量
                    Log.d("MenuData", "String1: $string1, String2: $string2")
                } else {
                    Log.e("MenuData", "网页中没有找到足够的列表项")
                }
            } catch (e: Exception) {
                e.printStackTrace()
                Log.e("MenuData", "请求或解析失败: ${e.message}")
            }
        }
    }
}

Java版本(用AsyncTask处理异步,适合老项目)

如果你还在使用Java,可以用AsyncTask来实现(虽然官方已不推荐,但老项目仍可使用):

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import android.os.AsyncTask;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    private String string1 = "";
    private String string2 = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 启动异步任务
        new FetchMenuTask().execute();
    }

    private class FetchMenuTask extends AsyncTask<Void, Void, String[]> {
        @Override
        protected String[] doInBackground(Void... voids) {
            try {
                Document document = Jsoup.connect("http://self.shahroodut.ac.ir/Ghaza.aspx?date=970229").get();
                Elements menuItems = document.select("table tr td ol li");
                if (menuItems.size() >= 2) {
                    return new String[]{
                            menuItems.get(0).text().trim(),
                            menuItems.get(1).text().trim()
                    };
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String[] strings) {
            super.onPostExecute(strings);
            if (strings != null) {
                string1 = strings[0];
                string2 = strings[1];
                Log.d("MenuData", "String1: " + string1 + ", String2: " + string2);
                // 后续可以在这里调用string1和string2做业务处理
            } else {
                Log.e("MenuData", "获取菜单数据失败");
            }
        }
    }
}

4. 后续调用说明

把string1和string2定义为Activity、ViewModel或者单例类的成员变量后,你就可以在应用的任何需要的地方直接调用这些变量了。如果需要跨页面传递,也可以用Intent、ViewModel或者SharedPreferences(如果需要持久化的话)。

注意事项

  • 线程安全:绝对不能在主线程执行网络请求和HTML解析,一定要用协程、AsyncTask或者其他异步方式处理,否则会触发ANR。
  • 异常处理:一定要捕获网络异常、解析异常等情况,避免应用崩溃。
  • 精确选择器:如果网页中有多个table,建议给目标table加上id或者类名的选择器(比如document.select("table#menuTable tr td ol li")),这样能更精准地定位到目标元素,避免抓取到无关数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:11:45