如何在Android中从HTML链接获取页面的HTML源代码?

27

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

你能给我一些例子或起点,帮助我开始编写这样的应用程序吗?


你想做什么不是很清楚?我猜你想获取网页然后解析HTML? - Janusz
我正在处理HTML解析。首先,我想从我的HTML链接中获取HTML源代码。如何做到这一点?对不起,我的英语很糟糕。感谢您的鼓励。 - Praveen
没问题,我试着稍微改一下你的问题。希望它仍然是同一个问题 :) 如果您有进一步的问题,请注意您的问题非常广泛。我们喜欢那些更具特殊性并且在您的应用程序中只有一个问题的问题,也许还附带一些示例代码来解释您的问题... - Janusz
8个回答

47

您可以使用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();

2
很遗憾,我遇到了未知主机异常,但我可以在浏览器中打开相同的URL。 - Rhyous
9
我也遇到了未知主机异常,但是我的问题是权限问题。我在清单文件中添加了以下代码:<uses-permission android:name="android.permission.INTERNET" /> - Michel
我的url是new URI("http://www.google.com/"),但我遇到了“NullReferenceException”的问题。除了“android.permission.INTERNET”之外,还需要其他权限吗? - Kamran Ahmed
1
为什么不使用 String html = EntityUtils.toString(response.getEntity()); - ben
请提到我们应该使用什么替代HttpClient。 - Utkarsh Sinha
显示剩余3条评论

17

我建议使用jsoup

根据他们的网站:

获取维基百科首页,解析为DOM,并从新闻部分选择标题到元素列表中(在线示例):

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

开始:

  1. 下载 jsoup 核心库的 jar 文件
  2. 阅读 菜谱 介绍

14

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

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加载时发送函数数据吗? - user1788736

6
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) {

}
}

1

调用它的方式如下:

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_Response'? - user1091524
另外,Parser(feed)是什么意思?Alt_Enter找不到Parser类。 - user1091524
请修复这些错误“无法解析符号'HTML_Resonse'”和“无法解析方法'Parser(java.lang.String)'”@Nepster - Florida
我已经更新了答案。如果还有其他问题,请问一下。 - Zar E Ahmer

0

其他SO帖子的答案帮助了我。这不是逐行读取;假设html文件中间有一行null。作为前提,在项目设置中添加此依赖项"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

        }
    });

0

如果你在这里这里或者这里看一下,你会发现你不能直接使用Android API来做到那个,你需要一个外部库...

如果你需要一个外部库,你可以在上面的两个中选择一个。


1
这取决于您要解析的网页类型和需求。如果您只是想获取一些特定值,完全可以使用一些正则表达式来抓取这些值 :) 只有在库的使用情况足够复杂时,我才会使用新的外部库。 - Janusz
很好。正则表达式非常容易使用。但是你需要加载整个页面,并使用自定义正则表达式抓取每个你感兴趣的标签,不是吗? - Sephy
在使用正则表达式之前,我们需要将HTML源代码获取为字符串。如何做到这一点? - Praveen

0
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);

    }

1
嗨,Ashique Hira Manzil,欢迎来到StackOverflow。我建议您在回答中添加更多内容,而不仅仅是代码。还要考虑这篇文章已经有10年的历史了。此外,Android已经弃用了Asynk任务。 - Kuruchy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接