使用Java从网页中提取数据?

33

我正试图编写我的第一个Java程序。目标是编写一个程序,让它浏览到一个网站并为我下载一个文件。然而,我不知道如何使用Java与互联网进行交互。有人可以告诉我需要查阅/阅读哪些主题或推荐一些好的资源吗?


您可以使用Apache的HttpClient。这里也有类似的答案 here - iruediger
5个回答

45

最简单的解决方案(不依赖任何第三方库或平台)是创建一个指向要下载的网页/链接的URL实例,并使用流来读取内容。

例如:

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.URL;
    import java.net.URLConnection;
    
    
    public class DownloadPage {
    
        public static void main(String[] args) throws IOException {
            
            // Make a URL to the web page
            URL url = new URL("https://dev59.com/3G025IYBdhLWcg3wNC11);
            
            // Get the input stream through URL Connection
            URLConnection con = url.openConnection();
            InputStream is = con.getInputStream();
            
            // Once you have the Input Stream, it's just plain old Java IO stuff.
            
            // For this case, since you are interested in getting plain-text web page
            // I'll use a reader and output the text content to System.out.
            
            // For binary content, it's better to directly read the bytes from stream and write
            // to the target file.          
            
            try(BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
                String line = null;
            
                // read each line and write to System.out
                while ((line = br.readLine()) != null) {
                    System.out.println(line);
                }
            }
        }
    }
希望这能帮到你。

嗨,当我实现这个时,在我的控制台中会得到HTML文件。如何从网站获取特定值? - flowers1234

30

基础知识

从头开始构建一个解决方案,可以看以下内容:

易于组装和拼接的工具

您始终可以选择使用exec() 和类似方法从 Java 调用外部工具。例如,您可以使用wgetcURL

高级内容

如果您想进入更全面的内容,则幸运的是,自动化 Web 测试的需求为我们提供了非常实用的工具。请看:

还有一些库是专门为 Web 抓取而编写的:

一些解决方法

Java是一门语言,也是一个平台,许多其他语言都在其上运行。其中一些集成了很好的语法糖或库来轻松构建网络爬虫。

请查看以下内容:

如果您知道适用于Ruby(使用JRuby,有一篇关于使用JRuby和HtmlUnit进行网络爬虫的文章)或PythonJython)的优秀库,或者您更喜欢这些语言,那么请给它们的JVM端一个机会。

一些补充内容

一些类似的问题:


在那个答案中我没有写的一件事是:我真的不推荐用Java做这种事情(当然你可能没有选择,但我只是指出来)。它是可行的,并且有很多工具可以用,但是Java天生的冗长使得它不太适合尝试对网站进行抓取。通常情况下,我更愿意使用带有REPL的动态语言,或直接从我的浏览器控制台等方式来完成这个任务...但是当然,没有什么能阻止你像这样开始然后用Java或另一种基于JVM的语言实现解决方案! - haylem

8

这里是我的解决方案,使用URLtry with resources语句捕获异常。

/**
 * Created by mona on 5/27/16.
 */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
public class ReadFromWeb {
    public static void readFromWeb(String webURL) throws IOException {
        URL url = new URL(webURL);
        InputStream is =  url.openStream();
        try( BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        }
        catch (MalformedURLException e) {
            e.printStackTrace();
            throw new MalformedURLException("URL is malformed!!");
        }
        catch (IOException e) {
            e.printStackTrace();
            throw new IOException();
        }

    }
    public static void main(String[] args) throws IOException {
        String url = "https://madison.craigslist.org/search/sub";
        readFromWeb(url);
    }

}

根据您的需要,您还可以将其保存到文件或使用 XMLHTML 库进行解析。


3
自Java 11以来,最方便的方法是使用标准库中的java.net.http.HttpClient

示例:

HttpClient client = HttpClient.newBuilder()
     .version(Version.HTTP_1_1)
     .followRedirects(Redirect.NORMAL)
     .connectTimeout(Duration.ofSeconds(20))
     .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
     .authenticator(Authenticator.getDefault())
     .build();

HttpRequest request = HttpRequest.newBuilder()
     .uri(URI.create("httpss://foo.com/"))
     .timeout(Duration.ofMinutes(2))
     .GET()
     .build();

HttpResponse<String> response = client.send(request, BodyHandlers.ofString());

System.out.println(response.statusCode());

System.out.println(response.body());

我不得不添加一堆导入:import java.net.http.HttpClient; import java.net.http.HttpClient.Version; import java.net.http.HttpClient.Redirect; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers;import java.time.Duration; 但是在验证器行上仍然出现空指针异常错误,也不确定代理应该放什么。 :( - gfmoore

1
我使用以下代码来操作我的API:

try {
        URL url = new URL("https://dev59.com/3G025IYBdhLWcg3wNC11");
        InputStream content = url.openStream();
        int c;
        while ((c = content.read())!=-1) System.out.print((char) c);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException ie) {
        ie.printStackTrace();
    }

你可以捕获字符并将它们转换为字符串。

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