在Java中获取网站源代码

3
我想使用Java获取一个网站(安全的)的源代码,然后解析其中包含的链接。我已经找到了如何连接到该URL,但是如何轻松地获取源代码呢?最好是作为DOM文档,这样我就可以轻松地获取所需的信息。
或者有没有更好的方法连接到HTTPS网站,获取源代码(我需要这样做来获取数据表格...非常简单),然后这些链接是我要下载的文件。
我希望它是FTP,但这些文件存储在我的Tivo上(我想以编程方式将它们下载到我的计算机上)。
8个回答

6
您可以使用套接字请求低级别的内容。在Java中,它看起来像这样:
// Arg[0] = Hostname
// Arg[1] = File like index.html
public static void main(String[] args) throws Exception {
    SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();

    SSLSocket sslsock = (SSLSocket) factory.createSocket(args[0], 443);

    SSLSession session = sslsock.getSession();
    X509Certificate cert;
    try {
        cert = (X509Certificate) session.getPeerCertificates()[0];
    } catch (SSLPeerUnverifiedException e) {
        System.err.println(session.getPeerHost() + " did not present a valid cert.");
        return;
    }

    // Now use the secure socket just like a regular socket to read pages.
    PrintWriter out = new PrintWriter(sslsock.getOutputStream());
    out.write("GET " + args[1] + " HTTP/1.0\r\n\r\n");
    out.flush();

    BufferedReader in = new BufferedReader(new InputStreamReader(sslsock.getInputStream()));
    String line;
    String regExp = ".*<a href=\"(.*)\">.*";
    Pattern p = Pattern.compile( regExp, Pattern.CASE_INSENSITIVE );

    while ((line = in.readLine()) != null) {
        // Using Oscar's RegEx.
        Matcher m = p.matcher( line );  
        if( m.matches() ) {
            System.out.println( m.group(1) );
        }
    }

    sslsock.close();
}

我最喜欢你的答案,计划明天尝试一下。如果有效,我会接受它。唯一的问题是如何发送用户名和密码? - Adam Lerman
嘿,亚当。这段代码使用SSL连接到一个HTTPS(安全)站点。用户名/密码是特定于该站点的。这就好像询问如何登录美国银行,并期望它与华美银行的不同登录方式兼容一样。希望你仍然接受我的答案是正确的,因为这就是你所要求的。 - Bernie Perez


3

建议尝试使用HttpUnit或者HttpClient。虽然前者主要用于撰写集成测试,但它具备一个便捷的API,可以编程迭代网页链接,例如使用WebResponse.getLinks()进行以下操作:

WebConversation wc = new WebConversation();
WebResponse resp = wc.getResponse("https://dev59.com/fkbRa4cB1Zd3GeqPxyxc");
WebLink[] links = resp.getLinks();
// Loop over array of links...

好的选择,我建议将HtmlUnit添加到列表中。 - Brian Matthews
不要滥用它的目的。HtmlUnit是一个专门用于单元测试的库。 - Adeel Ansari
@Adeel:我不知道HtmlUnit是什么,但在链接的URL中,HtmlUnit在第一段中说它是“Java程序的浏览器”,在第三段列出了“测试目的或从网站检索信息”的典型用途。我不明白Adam想要什么与这种典型用法相矛盾。 - Miserable Variable

3

如果您想获得更好的结果,可以考虑使用Pete或sktrdie选项。如果您想了解如何通过手动方式执行此操作,则可以使用以下附加方式。

我不太擅长正则表达式,因此在这种情况下,它将返回行中的最后一个链接。嗯,这是一个开始。

import java.io.*;
import java.net.*;
import java.util.regex.*;

public class Links { 
    public static void main( String [] args ) throws IOException  { 

        URL url = new URL( args[0] );
        InputStream is = url.openConnection().getInputStream();

        BufferedReader reader = new BufferedReader( new InputStreamReader( is )  );

        String line = null;
        String regExp = ".*<a href=\"(.*)\">.*";
        Pattern p = Pattern.compile( regExp, Pattern.CASE_INSENSITIVE );

        while( ( line = reader.readLine() ) != null )  {
            Matcher m = p.matcher( line );  
            if( m.matches() ) {
                System.out.println( m.group(1) );
            }
        }
        reader.close();
    }
}

编辑

哎呀,我完全忽略了“安全”部分。不管怎样,我还是忍不住要写这个示例 :P


我以为他说他需要安全访问支持。url.openConnection是否支持SSL? - Bernie Perez
好的,没问题。如果你不介意的话,我会在我的例子中使用你的正则表达式。 - Bernie Perez

1
你可以使用 javacurl 获取网站的 HTML,然后使用 Java DOM 进行分析。

1
尝试使用jsoup库。
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;


public class ParseHTML {

    public static void main(String args[]) throws IOException{
        Document doc = Jsoup.connect("https://www.wikipedia.org/").get();
        String text = doc.body().text();

        System.out.print(text);
    }
}

你可以在这里下载jsoup库。

0

在Web上下文中,source有两个含义:

HTML源代码:如果您通过URL请求网页,则始终会获取HTML源代码。实际上,您无法从URL获取其他任何内容。网页始终以源代码形式传输,不存在所谓的“已编译网页”。对于您正在尝试的内容,这应该足以完成您的任务。

脚本源代码:如果网页是动态生成的,则它是使用某种服务器端脚本语言(如PHP、Ruby、JSP等)编写的。在这个级别上也存在源代码。但是,使用HTTP连接您无法获取此类源代码。这不是一个“缺失的功能”,而是完全出于目的。

解析:说到这里,您需要以某种方式解析HTML代码。如果您只需要链接,使用正则表达式(如Oscar Reyes所示)将是最实用的方法,但您也可以手动编写一个简单的解析器。它可能会慢一些,需要更多的代码...但是可以工作。

如果您想在更逻辑的层面上访问代码,将其解析为DOM是一种方法。如果代码是有效的XHTML,则可以将其解析为org.w3c.dom.Document并对其进行任何操作。如果它至少是有效的HTML,则可以应用一些技巧将其转换为XHTML(在某些罕见情况下,通过将<br>替换为<br/>并更改文档类型就足够了),然后将其用作XML。

如果它不是有效的XML,则需要使用HTML DOM解析器。我不知道Java是否有这样的东西,以及它是否表现良好。


抱歉我没有详细说明如何完成具体任务,但我觉得应该先指出一些基本事项。如果你确切知道该做什么,你会很容易找到细节。 - Lena Schimmel

0

存在一种FTP服务器可以安装在您的Tivo上,允许进行节目下载,请参见这里http://dvrpedia.com/MFS_FTP

问题的表述方式不同(如何在Java中处理http / html),但最终提到您想要下载节目。 Tivo使用自己的唯一文件系统(MFS-媒体文件系统),因此很难在另一台机器上挂载驱动器-相反,更容易在Tivo上运行http或ftp服务器并从这些服务器下载。


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