从网页获取数据(屏幕抓取)

时间:2012-11-13 11:31:36

标签: java authentication web screen-scraping

有人可以给我一个关于屏幕抓取的好教程。我有一个我的大学用来上传每个班级所有数据的网页。要进入他们网站的主页,有一个输入屏幕,其中有一个登录按钮。按下它会弹出一个浮动对话框,询问用户名和密码。然后它直接进入主页。我不知道它在哪里请求授权,我希望能够以编程方式从网站获取数据。我需要的数据是通过更多的登录屏幕,但如果我可以通过我的ID和密码通过这个第一个屏幕,我会很高兴。我希望在java中这样,但任何语言都会这样做

1 个答案:

答案 0 :(得分:1)

这听起来像登录对话框不是原始页面的一部分,而是由一些JavaScript动态构建,可能通过Ajax调用。

您需要的是某种无头浏览器,它支持javaScript和Ajax。

从介绍中查看 HtmlUnit (http://htmlunit.sourceforge.net/):

HtmlUnit是一个“用于Java程序的GUI-Less浏览器”。它模拟HTML文档并提供一个API,允许您调用页面,填写表单,单击链接等...就像在“普通”浏览器中一样。

它具有相当不错的JavaScript支持(不断改进),即使使用非常复杂的AJAX库也可以工作,根据您要使用的配置模拟Firefox或Internet Explorer。 < / p>

编辑:这是一个例子:

我注意到您要扫描的页面(http://qub.ac.uk/qol/)使用基本身份验证,因此它不是弹出的某种HTML输入表单,而是浏览器对话框。当您按开始页面上的“登录”按钮时,将加载一个页面https://qub.ac.uk/qol/,以这种方式加以保护。

对于测试,我只向您展示如何使用HtmlUnit从不安全的http://qub.ac.uk/qol/页面获取标题,因为我当然无法访问秘密部分。

我认为,应该清楚它是如何运作的。有关如何使用HtmlUnit API的更多详细信息,请参阅Web上的优秀文档和其他资源。

package test;

import java.io.IOException;
import java.net.MalformedURLException;

import javax.xml.bind.DatatypeConverter;

import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.DomNodeList;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

public class Scraper {

    public static void main(String[] args)
            throws FailingHttpStatusCodeException, MalformedURLException,
            IOException {
        WebClient webClient = new WebClient();

        String username = "user";
        String password = "pw";
        String authString = username + ":" + password;
        String authEncoded = DatatypeConverter.printBase64Binary(authString
                .getBytes());

        webClient.addRequestHeader("Authorization", "Basic " + authEncoded);

        HtmlPage page = webClient.getPage("http://qub.ac.uk/qol/");
        // System.out.println(page.asXml());
        DomNodeList<DomElement> headings = page.getElementsByTagName("h3");
        for (DomElement e : headings) {
            System.out.println("Got heading: " + e.getTextContent());
        }

    }

}