【问题标题】:I am coding in Android Studio, and I need to fetch and display a specific line of data from a specific webpage我在 Android Studio 中编码,我需要从特定网页中获取并显示特定的数据行
【发布时间】:2020-10-03 01:30:08
【问题描述】:

我对 Java/Android Studio 中的编码非常陌生。到目前为止,我已经能够弄清楚所有设置。我有一个按钮,我需要将代码放在按钮单击事件中,该事件将从网站获取信息,将其转换为字符串并显示它。我想我必须使用 html 源代码才能做到这一点,所以我安装了 Jsoup html 解析器。我发现的所有关于 Jsoup 的帮助只会引导我将 HTML 放入“文档”中。而且我不确定这是否是完成我需要的最佳方式。谁能告诉我使用什么代码从网站获取 html 代码,然后通过 html 进行搜索以查找特定匹配项,并将该匹配项转换为字符串。或者谁能​​告诉我是否有更好的方法来做到这一点。我只需要抓取一条信息并显示出来。

这是一段 html 代码,其中包含我想要的值:

writeBidRow('小麦',-60,false,false,false,0.5,'01/15/2015','02/26/2015','全部',' ',' ',60,'偶数',' c=2246&l=3519&d=G15',quotes['KEH15'], 0-0);

我需要在那个 html 代码中抓取并显示代表引号 ['KEH15'] 的任何值。 提前感谢您的帮助。

基思

【问题讨论】:

    标签: java android html parsing jsoup


    【解决方案1】:

    抓取原始 HTML 是一种从 Web 访问信息的极其繁琐的方法,这是一种不好的做法,并且在您从任何地方获取信息都会更改其 HTML 的情况下难以维护。

    我不知道您的具体情况以及您要获取的数据是什么,但如果您有其他方法可以通过 API 获取该数据,请改用它。

    既然你说你对 Android 和 Java 很陌生,让我解释一下我希望很早就向我解释过的东西(尽管我主要是自学成才)。

    人们通过 Internet 访问信息的方式传统上是通过 HTML 和 JavaScript(由您的浏览器(如 Chrome 或 Firefox)解释为看起来很漂亮),它们使用称为HTTP。这是人类与远方计算机交流的好方法,而普通人可能没有意识到互联网上还有比这更多的东西——您的浏览器和您可以访问的网站。

    尽管有多种方法,但出于我认为您正在寻找的目的,应用程序通过 Internet 进行通信的方式略有不同:

    当一个 android 应用程序向服务器询问一些信息时,而不是返回供人类使用的 HTML 和 JavaScript,服务器将(传统上)返回所谓的JSON(或有时是 XML,这非常相似)。 JSON 是一种获取对象信息的非常简单的方法,并将其转换为人类(开发人员)和计算机都可以轻松读取的形式,并且可以轻松地通过 Internet 传输。例如,假设您向服务器请求播放视频的应用程序的某种“视频”对象,它可能会给您如下内容:

    {
      "name": "Gangnam Style",
      "metadata": {
        "url": "https://www.youtube.com/watch?v=9bZkp7q19f0",
        "views": 2000000000,
        "ageRestricted": false,
        "likes": 43434
        "dislikes":124
      },
      "comments": [
        {
          "username": "John",
          "comment": "10/10 would watch again"
        },
        {
          "username": "Jane",
          "number": "12/10 with rice"
        }
      ]
    }
    

    这对我们人类来说是非常可读的,但对计算机来说也是如此!我们知道名字是“Gangnam Style”,视频的链接等等。

    Google 的GSON library 是在 Java 和 Android 中与 JSON 交互的一种非常有用的方法,它允许您将 Java 对象转换为 JSON 或将 JSON 对象解析为 Java 对象。

    首先要获取此信息,您必须对 API(应用程序编程接口)进行网络调用。只是服务器和客户端之间通信的一个花哨术语。我将用于本示例的一个非常酷、免费且易于理解的 API 是 OMDB API,它只是从 IMDB 中返回有关电影的信息。那么你如何与 API 对话呢?幸运的是,他们有一些很好的文档,其中说要获取电影的信息,我们需要在 url 中使用一些参数,比如

    http://www.omdbapi.com/?t=Interstellar
    

    他们想要一个带有参数“t”的标题。我们可以输入年份或返回类型,但这应该有助于理解基础知识。如果您在浏览器中访问该 URL,它会以 JSON 形式返回大量有关星际的信息。我们说的那些东西!那么如何从您的 Android 应用程序中获取这些信息呢?

    好吧,您可以使用 Android 内置的 HttpUrlConnection 类,并花几个小时研究为什么您的呼叫无法正常工作。但是现在基本上不是每个应用程序都使用网络吗?当几乎所有有价值的应用程序以前都可能完成这项工作时,为什么要重新发明轮子呢?也许我们可以在网上找到一些代码来为我们完成这项工作。

    或者更好的是,图书馆!特别是 Square 开发的一个开源库,retrofit。有多个类似的库(继续研究,最好找到最适合您的项目的库),但想法是它们为您完成所有艰苦的工作,例如低级网络编程。按照他们的指南,您可以将大量代码工作减少到几行。所以对于我们的 OMDB API 示例,我们可以像这样设置我们的网络调用:

    //OMDB API
    public ApiClient{
        //an instance of this client object
        private static OmdbApiInterface sOmdbApiInterface;
        //if the omdbApiInterface object has been instantiated, return it, but if not, build it then return it.
        public static OmdbApiInterface getOmdbApiClient() {
            if (sOmdbApiInterface == null) {
                RestAdapter restAdapter = new RestAdapter.Builder()
                        .setEndpoint("http://www.omdbapi.com")
                        .build();
                sOmdbApiInterface = restAdapter.create(OmdbApiInterface.class);
            }
            return sOmdbApiInterface;
        }
        public interface OmdbApiInterface {
            @GET("/")
            void getInfo(@Query("t") String title, Callback<JsonObject> callback);
    
        }
    }
    

    在您使用他们的文档研究并了解那里发生了什么之后,我们现在可以使用我们在您的应用程序中的任何位置设置的这个类来调用 API:

    //you could get a user input string and pass it in as movieName
    ApiClient.getOmdbApiClient().getInfo(movieName, new Callback<List<MovieInfo>>() {
    //the nice thing here is that RetroFit deals with the JSON for you, so you can just get information right here from the JSON object
                @Override
                public void success(JsonObject movies, Response response) {
                    Log.i("TAG","Movie name is " + movies.getString("Title");
                }
    
                @Override
                public void failure(RetrofitError error) {
                    Log.e("TAG", error.getMessage());
                }
            });
    

    现在您已经进行了 API 调用以从网络上获取信息!恭喜!现在对数据做你想做的事。在这种情况下,我们使用了 Omdb,但您可以使用任何具有这种通信方法的东西。出于您的目的,我不确切知道您要获取哪些数据,但如果可能,请尝试找到一个公共 API 或您可以使用类似于此的方法获取它的东西。

    如果您有任何问题,请告诉我。

    干杯!

    【讨论】:

    • 感谢您提供如此详细的回复,但正如下面的海报所假设的那样,我只有网页。但我感谢您的帮助,我相信我会回来查看此代码以供将来参考。
    【解决方案2】:

    正如@caleb-allen 所说,如果您可以使用 API,最好使用它。

    但是,我假设您只需要使用网页即可。

    在 Android 上可以使用许多库来获取 URL 的内容。 选择范围从使用基本的 HTTPUrlConnection 到稍微高级一点的 HTTPClient 到使用像 Retrofit 这样的健壮库。我个人推荐改造。无论您做什么,请确保您的 HTTP 访问是异步的,而不是在 UI 线程上完成。 Retrofit 会默认为你处理。

    对于解析结果,我过去使用开源 HTMLCleaner 库取得了不错的结果 - 请参阅 http://htmlcleaner.sourceforge.net

    与 JSoup 类似,它接受一个可能格式错误的 HTML 文档并从中创建一个有效的 XML 文档。

    一旦你有了一个有效的 XML 文档,你就可以使用 HTMLCleaner 的 XML DOM 实现来解析文档以找到你需要的东西。

    例如,这是我用来从网页上的

    元素中解析“项目”名称的方法,其中项目是表中的链接:
       private List<Project> parseProjects(String html) throws Exception {
            List<Project> parsedProjects = new ArrayList<Project>();
    
            HtmlCleaner pageParser = new HtmlCleaner();
            TagNode node = pageParser.clean(html);
            String xpath = "//table[@class='listtable']".toString();
            Object[] tables = node.evaluateXPath(xpath);
    
            TagNode tableNode;
            if(tables.length > 1) {
                tableNode = (TagNode) tables[0];
            } else {
                throw new Exception("projects table not found in html");
            }
    
            TagNode[] projectLinks = tableNode.getElementsByName("a", true);
            for(int i = 0; i < projectLinks.length; i++) {
                TagNode link = projectLinks[i];
                String projectName = link.getText().toString();
                String href = link.getAttributeByName("href");
                String projectIdString = href.split("=")[1];
                int projectId = Integer.parseInt(projectIdString);
                Project project = new Project(projectId, projectName);
                parsedProjects.add(project);
            }
    
            return parsedProjects;
        }
    

    【讨论】:

    • 是的,我只有网页可用。我认为我需要的只是获取 URL 内容的准系统方法。我要做的就是访问这个网页:antoncoop.com/markets/cash.php 并获得小麦的现金价格。是否可以使用 HtmlCleaner 来获取 URL 的内容,或者我需要多个库来获取 URL 的内容并解析小麦的现金价格?谢谢你的帮助,我真的很感激。
    • HtmlCleaner 不提供 HTTP 访问 - 您必须自己使用 java/Android 提供的类之一(如 HTTPUrlConnection developer.android.com/reference/java/net/… HTTPClient developer.android.com/reference/org/apache/http/client/…)或使用第三方像 Retrofit 这样的库。
    【解决方案3】:

    如果您有权限编辑网页以将超链接添加到该页面的指定行,您可以使用这种方式

    首先在你的页面中添加你想去那里的行头代码

    如果愿意,请在正文中添加标题

    然后在你的apk应用上控制点击代码输入 this.mwebview.loadurl("https:#######.com.html#target")

    在#左侧输入您的网页地址,然后在此示例中输入您的ID为目标的#target。 对不起,如果我的英语语言。不好

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-01
      • 2020-08-15
      • 1970-01-01
      • 2015-09-16
      • 1970-01-01
      • 2018-01-08
      • 1970-01-01
      相关资源
      最近更新 更多