【问题标题】:How to get the HTML source of a page from a HTML link in Android?如何从 Android 中的 HTML 链接获取页面的 HTML 源代码?
【发布时间】:2011-01-26 06:44:08
【问题描述】:

我正在开发一个应用程序,该应用程序需要从链接中获取网页的源代码,然后解析该页面中的 html。

你能给我一些例子,或者从哪里开始编写这样的应用程序?

【问题讨论】:

  • 不完全清楚你想做什么?我猜你想获取网页然后解析 html?
  • 我正在做 html 解析。第一个任务我想从我的 html 链接中获取 html 源代码。怎么做?对不起我最糟糕的英语。谢谢你鼓励我。
  • 没问题我试着重新表述一下你的问题。我希望仍然是同一个问题:) 对于进一步的问题,您的问题非常广泛。我们喜欢一些更特别的问题,并且在您的应用中存在一个问题,也许可以使用一些示例代码来解释您的问题...

标签: html android android-emulator


【解决方案1】:

您可以使用HttpClient 执行 HTTP GET 并检索 HTML 响应,如下所示:

HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);

String html = "";
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder str = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null)
{
    str.append(line);
}
in.close();
html = str.toString();

【讨论】:

  • 不幸的是,我收到了一个未知的主机异常,但我可以打开浏览器访问我的同一个 URL。
  • 也得到了未知主机异常,对我来说这是一个版权问题,将这个` `添加到清单中
  • 有什么方法可以一步读取所有内容,而不是逐行读取?
  • 我收到一个“NullReferenceException”,我的 url 是 new URI("http://www.google.com/")。除了“android.permission.INTERNET”之外还需要其他权限吗?
  • 为什么不使用String html = EntityUtils.toString(response.getEntity());
【解决方案2】:

我建议jsoup

根据他们的网站:

获取 Wikipedia 主页,将其解析为 DOM,然后将新闻部分中的标题选择到元素列表中(在线示例):

Document doc = Jsoup.connect("http://en.wikipedia.org/").get();
Elements newsHeadlines = doc.select("#mp-itn b a");

开始:

  1. Downloadjsoup jar 核心库
  2. 阅读cookbook简介

【讨论】:

    【解决方案3】:

    这个问题有点老了,但我想我应该发布我的答案,因为 DefaultHttpClientHttpGet 等已被弃用。这个函数应该获取并返回 HTML,给定一个 URL。

    public static String getHtml(String url) throws IOException {
        // Build and set timeout values for the request.
        URLConnection connection = (new URL(url)).openConnection();
        connection.setConnectTimeout(5000);
        connection.setReadTimeout(5000);
        connection.connect();
    
        // Read and store the result line by line then return the entire string.
        InputStream in = connection.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        StringBuilder html = new StringBuilder();
        for (String line; (line = reader.readLine()) != null; ) {
            html.append(line);
        }
        in.close();
    
        return html.toString();
    }
    

    【讨论】:

    • 你能告诉我如何将此函数数据发送到 mainActivity 的 webview onload 吗?
    【解决方案4】:
    public class RetrieveSiteData extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
        StringBuilder builder = new StringBuilder(100000);
    
        for (String url : urls) {
            DefaultHttpClient client = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            try {
                HttpResponse execute = client.execute(httpGet);
                InputStream content = execute.getEntity().getContent();
    
                BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
                String s = "";
                while ((s = buffer.readLine()) != null) {
                    builder.append(s);
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        return builder.toString();
    }
    
    @Override
    protected void onPostExecute(String result) {
    
    }
    }
    

    【讨论】:

      【解决方案5】:

      这样称呼

      new RetrieveFeedTask(new OnTaskFinished()
              {
                  @Override
                  public void onFeedRetrieved(String feeds)
                  {
                      //do whatever you want to do with the feeds
                  }
              }).execute("http://enterurlhere.com");
      

      RetrieveFeedTask.class

      class RetrieveFeedTask extends AsyncTask<String, Void, String>
      {
          String HTML_response= "";
      
          OnTaskFinished onOurTaskFinished;
      
      
          public RetrieveFeedTask(OnTaskFinished onTaskFinished)
          {
              onOurTaskFinished = onTaskFinished;
          }
          @Override
          protected void onPreExecute()
          {
              super.onPreExecute();
          }
      
          @Override
          protected String doInBackground(String... urls)
          {
              try
              {
                  URL url = new URL(urls[0]); // enter your url here which to download
      
                  URLConnection conn = url.openConnection();
      
                  // open the stream and put it into BufferedReader
                  BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
      
                  String inputLine;
      
                  while ((inputLine = br.readLine()) != null)
                  {
                      // System.out.println(inputLine);
                      HTML_response += inputLine;
                  }
                  br.close();
      
                  System.out.println("Done");
      
              }
              catch (MalformedURLException e)
              {
                  e.printStackTrace();
              }
              catch (IOException e)
              {
                  e.printStackTrace();
              }
              return HTML_response;
          }
      
          @Override
          protected void onPostExecute(String feed)
          {
              onOurTaskFinished.onFeedRetrieved(feed);
          }
      }
      

      OnTaskFinished.java

      public interface OnTaskFinished
      {
          public void onFeedRetrieved(String feeds);
      }
      

      【讨论】:

      • 在哪里定义“url_search”和“HTML_Resonse”?
      • 另外,Parser(feed); 是什么?参考? Alt_Enter 没有找到 Parser 类。
      • 请修复此错误“无法解析符号'HTML_Resonse'”和“无法解析方法'Parser(java.lang.String)'”@Nepster
      • 我已经更新了答案。询问您是否还有其他问题
      【解决方案6】:

      如果你看看herehere,你会发现你不能直接用android API 来做,你需要一个外部库...

      如果您需要外部库,您可以在上面的 2 个中进行选择。

      【讨论】:

      • 这取决于您拥有并想要解析的网页类型。如果您只是在寻找一些特定的值,那么您完全可以使用一些正则表达式来获取这些值 :) 如果该库的用例足够复杂,我只会使用新的外部库
      • 很公平。正则表达式很容易使用。但是您需要加载整个页面并使用自定义正则表达式获取您感兴趣的每个标签,不是吗?
      • 在使用正则表达式之前,我们需要以字符串形式获取 html 源代码。该怎么做?
      【解决方案7】:

      其中一个 SO 帖子回答帮助了我。这不是逐行读取的;假设 html 文件之间有一行 null 。作为 preRequisite 从项目设置中添加此依赖项“com.koushikdutta.ion:ion:2.2.1”AsyncTASK 中实现此代码。如果您希望返回的 -something- 在 UI 线程中,请将其传递给相互接口。

      Ion.with(getApplicationContext()).
      load("https://google.com/hashbrowns")
      .asString()
      .setCallback(new FutureCallback<String>()
       {
              @Override
              public void onCompleted(Exception e, String result) {
                  //int s = result.lastIndexOf("user_id")+9;
                  // String st = result.substring(s,s+5);
                 // Log.e("USERID",st); //something
      
              }
          });
      

      【讨论】:

        【解决方案8】:
        public class DownloadTask extends AsyncTask<String, Void, String> {
        
                @Override
                protected String doInBackground(String... urls) {
        
                    String result = "";
                    URL url;
                    HttpsURLConnection urlConnection = null;
        
                    try {
                        url = new URL(urls[0]);
        
                        urlConnection = (HttpsURLConnection) url.openConnection();
        
                        BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
        
        
                        String inputLine;
        
                        while ((inputLine = br.readLine()) != null)
                        {
                            // System.out.println(inputLine);
                            result += inputLine;
                        }
                        br.close();
                        return result;
                    } catch (Exception e) {
                        e.printStackTrace();
                        return "failed";
                    }
                }
            }
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
        
                DownloadTask task = new DownloadTask();
        
                String result = null;
        
                try {
                    result = task.execute("https://www.example.com").get();
                }catch (Exception e){
        
                    e.printStackTrace();
                }
                Log.i("Result", result);
        
            }
        

        【讨论】:

        • 嗨 Ashique Hira Manzil,欢迎来到 StackOverflow。我建议添加的不仅仅是代码作为答案。还要考虑到帖子是10岁。 Android 已弃用 Asynk 任务。
        猜你喜欢
        • 2010-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-06
        相关资源
        最近更新 更多