如何从动态更新的网页上抓取价格?

问题描述

当我尝试从动态更新的网页上获取价格时,我遇到了问题。我的意思是,使用UrlConnection,Jsoup,HtmlUnit之类的方式无法获得大部分HTML代码。 我对网页抓取并不太了解,但我想问题是这样的网上商店: AuchanSilpo 使用javascript和ajax加载有关产品的主要信息。在我看来,问题出在重定向或Deley上,它不允许获取具有所有所需数据的完整加载的html文件。 那么,问题是如何从上面的链接中抓取价格?

我已经尝试了几种方法

  1. UrlConnection

        URL url;
        try {
            url = new URL("https://auchan.ua/govjadina-v-kartofel-nom-pjure-so-svekloj-hipp-6440-220-g-297668/");
            URLConnection con = url.openConnection();
            InputStream is = con.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String line;
            try(FileWriter fileWriter = new FileWriter("output.html")){
                while ((line = br.readLine()) != null) {
                    fileWriter.write(line+"\n");
                }
            }
        } catch (IOException e) {
            e.printstacktrace();
        }
    

    运行良好,但返回的HTML没有价格数据。

  2. Jsoup

Document document = null;
String link = "https://auchan.ua/govjadina-v-kartofel-nom-pjure-so-svekloj-hipp-6440-220-g-297668/";
try {
    document = Jsoup.connect(link).get();
} catch (IOException e) {
    e.printstacktrace();
}
if (document != null) {
    try (FileWriter fileWriter = new FileWriter("output.html")) {
        fileWriter.write(document.toString());
    } catch (IOException e) {
        e.printstacktrace();
    }
}

返回相同的结果。

3.HtmlUnit

    String link = "https://auchan.ua/govjadina-v-kartofel-nom-pjure-so-svekloj-hipp-6440-220-g-297668/";
    WebClient webClient = new WebClient(browserVersion.CHROME);
    webClient.getoptions().setJavaScriptEnabled(true);
    webClient.getoptions().setThrowExceptionOnScriptError(false);
    webClient.getoptions().setThrowExceptionOnFailingStatusCode(false);
    webClient.setAjaxController(new NicelyResynchronizingAjaxController());
    webClient.waitForBackgroundJavaScriptStartingBefore(5000);

    HtmlPage htmlPage = null;
    try {
        htmlPage = webClient.getPage(link);
        webClient.waitForBackgroundJavaScript(5000);
    } catch (IOException e) {
        e.printstacktrace();
    }
    if (htmlPage!=null){
        try (FileWriter fileWriter = new FileWriter("output.html")) {
            fileWriter.write(Jsoup.parse(htmlPage.asXml()).toString());
        } catch (IOException e) {
            e.printstacktrace();
        }
    }

返回更多信息,包括一些javascripts标记,但仍然没有任何用处。另外,上面的这段代码引发了很多异常,以至于它们甚至都不适合在控制台中使用。

我也试图像这样设置代理:

java.net.URLConnection conn = url.openConnection();
conn.setRequestProperty("User-Agent","Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");

这:

System.setProperty("http.agent","")

解决方法

您需要使用Chrome的开发工具来查看HTTP请求/响应

页面加载了大量的javascript。反过来,这会产生大量HTTP请求并等待响应:第一个看起来很有趣的是:

https://auchan.ua/graphql是带有重要http标头referer: https://auchan.ua/govjadina-v-kartofel-nom-pjure-so-svekloj-hipp-6440-220-g-297668/的POST请求-请求的响应正文为:{"data":{"urlResolver":{"type":"PRODUCT","id":297668}}}

获取产品ID值并在随后的响应中进行搜索,我发现其中包含产品ID。响应都是转义的unicode字符,但是如果您在浏览器中打开URL,则将呈现内容。

auchan.ua/graphql/?query=query%20getProductDetail...开头的特定URL看起来很有希望,并且肯定special_price与页面上显示的内容匹配。因此,您需要找到一种从初始页面源生成/提取这些URL的方法。

link to product details

您可能还会发现this response我为处理JSON数据提供了帮助。

您链接到的第二家商店需要用户名/密码,但是获取数据的过程可能非常相似;使用开发工具查看http请求,找出价格信息的来源(在响应之一中查找值),然后尝试从初始URL重新创建相同的请求并返回响应。

祝你好运!

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...