【问题标题】:How to correctly parse HTML in Java如何在 Java 中正确解析 HTML
【发布时间】:2018-02-13 08:51:02
【问题描述】:

我正在尝试使用 Jsoup 从网站中提取信息,但我没有获得与浏览器中相同的 HTML 代码。

我尝试使用.userAgent(),但没有成功。我目前使用以下适用于 Amazon.com 的功能:

public static String getHTML(String urlToRead) throws Exception {
      StringBuilder result = new StringBuilder();
      URL url = new URL(urlToRead);
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:19.0) Gecko/20100101 Firefox/19.0");
      conn.setRequestMethod("GET");
      BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
      String line;
      while ((line = rd.readLine()) != null) {
         result.append(line);
      }
      rd.close();
      return result.toString();
   }

我要解析的网站是http://www.asos.com/,但始终缺少产品的价格。

我喜欢this topic,它与我的非常接近,但我想只使用 java 而不是外部应用程序。

【问题讨论】:

  • 当您说I would like to do it using only java and no external app. 时,您的意思是您不想使用诸如org.Jsouporg.Json 之类的第三方库吗?

标签: java web-scraping jsoup


【解决方案1】:

因此,在对该网站进行了一些尝试之后,我想出了一个解决方案。

现在网站使用 API 响应来获取每件商品的价格,这就是为什么您没有从 Jsoup 收到的 HTML 中获取价格的原因。不幸的是,代码比最初预期的要多一些,您必须弄清楚它应该如何知道要使用哪个产品 ID 而不是硬编码的值。但是,除此之外,以下代码应该适用于您的情况。

我已经包含了希望解释每个步骤的 cmets,并且我建议您查看 API 响应,因为您可能需要一些其他数据,实际上这可能与产品详细信息和描述相同,作为进一步的数据将需要从elementById 字段中解析出来。

祝你好运,如果您需要任何进一步的帮助,请告诉我!

import org.json.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.*;
import org.jsoup.select.Elements;

import java.io.IOException;

public class Main
{
    final String productID = "8513070";
    final String productURL = "http://www.asos.com/prd/";
    final Product product = new Product();

    public static void main( String[] args )
    {
        new Main();
    }

    private Main()
    {
        getProductDetails( productURL, productID );
        System.out.println( "ID: " + product.productID + ", Name: " + product.productName + ", Price: " + product.productPrice );
    }

    private void getProductDetails( String url, String productID )
    {
        try
        {
            // Append the product url and the product id to retrieve the product HTML
            final String appendedURL = url + productID;

            // Using Jsoup we'll connect to the url and get the HTML
            Document document = Jsoup.connect( appendedURL ).get();
            // We parse the HTML only looking for the product section
            Element elementById = document.getElementById( "asos-product" );
            // To simply get the title we look for the H1 tag
            Elements h1 = elementById.getElementsByTag( "h1" );

            // Because more than one H1 tag is returned we only want the tag that isn't empty
            if ( !h1.text().isEmpty() )
            {
                // Add all data to Product object
                product.productID = productID;
                product.productName = h1.text().trim();
                product.productPrice = getProductPrice(productID);
            }
        }
        catch ( IOException e )
        {
            e.printStackTrace();
        }
    }

    private String getProductPrice( String productID )
    {
        try
        {
            // Append the api url and the product id to retrieve the product price JSON document
            final String apiURL = "http://www.asos.com/api/product/catalogue/v2/stockprice?productIds=" + productID + "&store=COM";
            // Using Jsoup again we connect to the URL ignoring the content type and retrieve the body
            String jsonDoc = Jsoup.connect( apiURL ).ignoreContentType( true ).execute().body();

            // As its JSON we want to parse the JSONArray until we get to the current price and return it.
            JSONArray jsonArray = new JSONArray( jsonDoc );
            JSONObject currentProductPriceObj = jsonArray
                    .getJSONObject( 0 )
                    .getJSONObject( "productPrice" )
                    .getJSONObject( "current" );
            return currentProductPriceObj.getString( "text" );
        }
        catch ( IOException e )
        {
            e.printStackTrace();
        }

        return "";
    }

    // Simple Product object to store the data
    class Product
    {
        String productID;
        String productName;
        String productPrice;
    }
}

哦,您还需要org.json 来解析来自 API 的 JSON 响应。

【讨论】:

  • 问题已解决,我没有使用 apiURL,因为价格在产品 HTML 页面中以 JSON 格式提供。我直接从那里创建我的 JSONObject。感谢您的回答,您带我找到解决方案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-01
  • 2014-10-10
  • 1970-01-01
  • 1970-01-01
  • 2016-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多