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
相关产品推荐
相关产品推荐

