【问题标题】:How to get element by class name with Jsoup?如何使用 Jsoup 按类名获取元素?
【发布时间】:2016-01-22 17:53:07
【问题描述】:

我正在尝试从 Android 中的 yahoo 财务页面中提取一些数据。

特定股票的摘要页面和历史价格页面都包含许多 class="yfnc_tabledata1" 的 td,我需要从中提取数字。我可以在历史价格页面中轻松提取这些 td 中的数据,如下所示:

Document document = Jsoup.connect("http://finance.yahoo.com/q/hp?s=LUX.MI").get();
            Elements html = document.getElementsByClass("yfnc_tabledata1");

但似乎同样的 sn-p 不适用于摘要页面,如下所示:

Document document = Jsoup.connect("http://finance.yahoo.com/q?s=LUX.MI").get();
            Elements html = document.getElementsByClass("yfnc_tabledata1");

在阅读了其他问题后,我也尝试了以下 3 种方法,但均未成功:

Elements html = document.select(".yfnc_tabledata1");
html.size() = 0

Elements html = document.getElementsByAttributeValueContaining("class", "yfnc_tabledata1");
html.size() = 0

Element el = document.getElementById("table#table1");
Elements html = el.getAllElements();
html.size() = error due for el being null 

知道我做错了什么吗?

这是我无法从中提取数据的摘要页面的 sn-p:

<div class="yui-u first yfi-start-content">
  <div class="yfi_quote_summary">
    <div id="yfi_quote_summary_data" class="rtq_table">
      <table id="table1">
        <tr>
          <th scope="row" width="48%">Prev Close:</th>
          <td class="yfnc_tabledata1">61.15</td>
        </tr>
        <tr>
          <th scope="row" width="48%">Open:</th>
          <td class="yfnc_tabledata1">61.45</td>
        </tr>
        <tr>
          <th scope="row" width="48%">Bid:</th>
          <td class="yfnc_tabledata1">
            <span id="yfs_b00_lux.mi">61.20</span>
          </td>
        </tr>
        <tr>
          <th scope="row" width="48%">Ask:</th>
          <td class="yfnc_tabledata1">
            <span id="yfs_a00_lux.mi">61.30</span>
          </td>
        </tr>
        <tr>
          <th scope="row" width="48%">1y Target Est:</th>
          <td class="yfnc_tabledata1">N/A</td>
        </tr><tr><th scope="row" width="48%">Beta:</th>
        <td class="yfnc_tabledata1">N/A</td>
        </tr>
        <tr>
          <th scope="row" width="54%">Next Earnings Date:</th>
          <td class="yfnc_tabledata1">N/A</td>
        </tr>
      </table>
      <table id="table2">
        <tr>
          <th scope="row" width="48%">Day's Range:</th>
          <td class="yfnc_tabledata1">
            <span>
              <span id="yfs_g53_lux.mi">60.75</span>
            </span> - 
            <span>
            <span id="yfs_h53_lux.mi">61.60</span>
            </span>
          </td>
        </tr>
        <tr>
          <th scope="row" width="48%">52wk Range:</th>
          <td class="yfnc_tabledata1">
            <span>34.74</span>
            - <span>62.50</span>
          </td>
        </tr>
        <tr>
          <th scope="row" width="48%">Volume:</th>
          <td class="yfnc_tabledata1">
            <span id="yfs_v53_lux.mi">1,057,884</span>
          </td>
        </tr>
        <tr>
          <th scope="row" width="48%">Avg Vol 
            <span class="small">(3m)</span>
            :</th>
          <td class="yfnc_tabledata1">740,908</td>
        </tr>
        <tr>
          <th scope="row" width="48%">Market Cap:</th>
          <td class="yfnc_tabledata1"
              ><span id="yfs_j10_lux.mi">29.36B</span>
          </td>
        </tr>
        <tr>
          <th scope="row" width="48%">P/E 
            <span class="small">(ttm)</span>
            :</th>
          <td class="yfnc_tabledata1">42.28</td>
        </tr>
        <tr>
          <th scope="row" width="48%">EPS 
            <span class="small">(ttm)</span>
            :</th>
          <td class="yfnc_tabledata1">1.45</td>
        </tr>
        <tr class="end"><th scope="row" width="48%">Div &amp; Yield:</th>
          <td class="yfnc_tabledata1">N/A (N/A) </td>
        </tr>
      </table>
    </div>
  </div>

EDIT1

我发现为什么相同的 sn-p 在两个页面上都不起作用。 sn-p 适用于历史价格页面,如果我尝试检索该页面的 html,我可以看到它与我在 chrome 中该页面的视图源中看到的完全相同的 html。摘要页面不会发生同样的情况:当我尝试检索它的 html 时,它与 chrome 中的视图源无关,它检索的是不同的东西,我不知道究竟是什么。那么现在的问题是:为什么这个 sn-p 没有检索到页面的正确 html?

Document document = Jsoup.connect("http://finance.yahoo.com/q?s=LUX.MI").get();
            temp = document.html();

【问题讨论】:

  • 好的,找到了解决这个问题的方法,尽管我还是无法解释为什么Jsoup 无法检索到页面的正确html。无论如何...为问题添加另一个编辑
  • 尝试在jsoup中添加一个userAgent。

标签: android html jsoup


【解决方案1】:

最初由 OP 找到的解决方案:

EDIT2-解决方案: 万一发生在其他人身上:如果 Jsoup.connect(url).get() 出于某种原因没有检索到正确的页面,首先在不使用 Jsoup 的情况下获取字符串中的 HTML,然后才使用 Jsoup 解析字符串。

HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://google.com");
HttpResponse response = httpclient.execute(httpget); 
HttpEntity entity = response.getEntity();

InputStream is = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
    sb.append(line + "\n");

String html = sb.toString();
is.close();
Document document = Jsoup.parse(html);

【讨论】:

    【解决方案2】:

    另一种解决方案...

    这是 OP 解决方案的一种变体。这里我们直接把httpclient提供的输入流给Jsoup。 Jsoup 能够解析输入流。

    String url = "http://google.com";
    
    HttpClient httpclient = new DefaultHttpClient();
    HttpGet httpget = new HttpGet(url);
    HttpResponse response = httpclient.execute(httpget); 
    HttpEntity entity = response.getEntity();
    
    InputStream is = entity.getContent();
    Document document = Jsoup.parse(is, null, url);
    is.close();
    

    ...但是如何按类名选择元素?

    要按类名选择元素,需要一个简单的 CSS 选择器。例如:

    • HTML
    • CSS 选择器

    下面列表中的任何选择器都可以找到上一个 HTML 部分中显示的 div。

    div.container
    div.open
    div.container.open
    

    还是不行……

    有时这不起作用,因为您可以在浏览器中看到的最终 HTML 是由一些 javascript 代码动态生成的。 Jsoup(撰写本文时为 1.8.3)不支持 Javascript。它无法运行 javascript。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-09
      • 2020-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-06
      • 1970-01-01
      • 2013-02-17
      相关资源
      最近更新 更多