1

Nokogiri、Mechanize、および XPath を使用してページを解析しようとしていますが、何を試しても空の配列が返されます。

解析しようとしているページ。

Chrome で調べて XPath を取得し、複数の方法で解析しようとしましたが、常に空の配列を受け取りました。

私は試した:

puts page.search('/html/body/div/table/tbody/tr[2]/td/table/tbody/tr[2]/td[2]').inspect

puts  post_page.parser.xpath('/html/body/div/table/tbody/tr[2]/td/table/tbody/tr[2]/td[2]').inspect

puts  post_page.parser.at_xpath('/html/body/div/table/tbody/tr[2]/td/table/tbody/tr[2]/td[2]').inspect

末尾の "/text" の有無にかかわらずすべて

これは、私がスクレイピングしようとしているページのソースです:

<SCRIPT language="JavaScript">
<!-- 
document.cookie = "IV_JCT=%2FMPIS; path=/";
//--> 
</SCRIPT>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>

  <head>
    <title>My Schedule</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="-1">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my schedule">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>

  <body>
  <div align="center"> 
    <strong>My Schedule</strong><br>as of Sun Feb 24 2013 06:43:09 PM CST<br><br>
    <div align="left"><pre><br>Employee Name: Johnson Appleseed    
Unit = 12345</pre>    
    <br> 
  </div>

    <table border="0" cellpadding="0" cellspacing="0" width="100%">
     <tr>
     <td colspan="8" align="center"><b><font size="+1">Schedules may be subject to change based on business needs or demand</font></b></td>
     </tr>   

      <tr><td>
      <table border="4" bordercolor="#2D73B9" cellpadding="2" cellspacing="2" width="100%">
      <tr bgcolor="#7C9BCF">
        <td width="12%" align="center"><b>Sunday</b></td>
        <td width="12%" align="center"><b>Monday</b></td>
        <td width="12%" align="center"><b>Tuesday</b></td>
        <td width="12%" align="center"><b>Wednesday</b></td>
        <td width="12%" align="center"><b>Thursday</b></td>
        <td width="12%" align="center"><b>Friday</b></td>
        <td width="12%" align="center"><b>Saturday</b></td>
        <td rowspan="2" width="12%" align="center"><b>Total weekly Hours</b></td>
      </tr>  

      <tr bgcolor="#7C9BCF">

        <td width="14%" align="center">2013-02-24</td>

        <td width="14%" align="center">2013-02-25</td>

        <td width="14%" align="center">2013-02-26</td>

        <td width="14%" align="center">2013-02-27</td>

        <td width="14%" align="center">2013-02-28</td>

        <td width="14%" align="center">2013-03-01</td>

        <td width="14%" align="center">2013-03-02</td>

      </tr>  

      <tr bgcolor="#FFFFFF">

        <td width="14%" align="left"><pre>&nbsp;</pre></td>

        <td width="14%" align="left"><pre><b>Shift: </b>
5:30 PM - 9:00 PM
<b>Meal:</b>
 - </pre></td>


        <td width="14%" align="left"><pre>&nbsp;</pre></td>

        <td width="14%" align="left"><pre>&nbsp;</pre></td>

        <td width="14%" align="left"><pre>&nbsp;</pre></td>

        <td width="14%" align="left"><pre><b>Shift: </b>
2:00 PM - 9:15 PM
<b>Meal:</b>
5:45 PM - 6:30 PM</pre></td>

        <td width="14%" align="left"><pre><b>Shift: </b>
4:45 PM - 9:15 PM
<b>Meal:</b>
 - </pre></td>

        <td width="12%" align="center">14.5</td> 
      </tr>  

      <tr bgcolor="#FFFFFF">

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">3.5</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">6.5</td>

        <td width="14%" align="center">4.5</td>

        <td width="14%" align="center">Daily Hours</td>   
      </tr>  

     </table>
     </td></tr>

      <tr><td>
      <table border="4" bordercolor="#2D73B9" cellpadding="2" cellspacing="2" width="100%">
      <tr bgcolor="#7C9BCF">
        <td width="12%" align="center"><b>Sunday</b></td>
        <td width="12%" align="center"><b>Monday</b></td>
        <td width="12%" align="center"><b>Tuesday</b></td>
        <td width="12%" align="center"><b>Wednesday</b></td>
        <td width="12%" align="center"><b>Thursday</b></td>
        <td width="12%" align="center"><b>Friday</b></td>
        <td width="12%" align="center"><b>Saturday</b></td>
        <td rowspan="2" width="12%" align="center"><b>Total weekly Hours</b></td>
      </tr>  

      <tr bgcolor="#7C9BCF">

        <td width="14%" align="center">2013-03-03</td>

        <td width="14%" align="center">2013-03-04</td>

        <td width="14%" align="center">2013-03-05</td>

        <td width="14%" align="center">2013-03-06</td>

        <td width="14%" align="center">2013-03-07</td>

        <td width="14%" align="center">2013-03-08</td>

        <td width="14%" align="center">2013-03-09</td>

      </tr>  

      <tr bgcolor="#FFFFFF">

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="12%" align="center">0.0</td> 
      </tr>  

      <tr bgcolor="#FFFFFF">

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">Daily Hours</td>   
      </tr>  

     </table>
     </td></tr>

      <tr><td>
      <table border="4" bordercolor="#2D73B9" cellpadding="2" cellspacing="2" width="100%">
      <tr bgcolor="#7C9BCF">
        <td width="12%" align="center"><b>Sunday</b></td>
        <td width="12%" align="center"><b>Monday</b></td>
        <td width="12%" align="center"><b>Tuesday</b></td>
        <td width="12%" align="center"><b>Wednesday</b></td>
        <td width="12%" align="center"><b>Thursday</b></td>
        <td width="12%" align="center"><b>Friday</b></td>
        <td width="12%" align="center"><b>Saturday</b></td>
        <td rowspan="2" width="12%" align="center"><b>Total weekly Hours</b></td>
      </tr>  

      <tr bgcolor="#7C9BCF">

        <td width="14%" align="center">2013-03-10</td>

        <td width="14%" align="center">2013-03-11</td>

        <td width="14%" align="center">2013-03-12</td>

        <td width="14%" align="center">2013-03-13</td>

        <td width="14%" align="center">2013-03-14</td>

        <td width="14%" align="center">2013-03-15</td>

        <td width="14%" align="center">2013-03-16</td>

      </tr>  

      <tr bgcolor="#FFFFFF">

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="14%" align="left"><pre>Sched Not Posted</pre></td>

        <td width="12%" align="center">0.0</td> 
      </tr>  

      <tr bgcolor="#FFFFFF">

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">0.0</td>

        <td width="14%" align="center">Daily Hours</td>   
      </tr>  

     </table>
     </td></tr>

     <tr>
     <td colspan="8" align="center"><b><font size="+1">Schedules may be subject to change based on business needs or demand</font></b></td>
     </tr>
    </table >

        <p><br>
        </p>
        <p class="align_center" >      
            <input type=button value="Print this page" onClick="javascript:window.print();">     
            <input type=button value="Close This Window" onClick="javascript:window.close();">
        </p>

  </div>
  </body>

</html>
4

1 に答える 1

5

tbodyXPath アクセサーでは、パスの一部である必要があることに注意してください。

puts page.search('/html/body/div/table/tbody/tr[2]/td/table/tbody/tr[2]/td[2]').inspect
puts  post_page.parser.xpath('/html/body/div/table/tbody/tr[2]/td/table/tbody/tr[2]/td[2]').inspect
puts  post_page.parser.at_xpath('/html/body/div/table/tbody/tr[2]/td/table/tbody/tr[2]/td[2]').inspect

HTML にタグがないためtbody、ルックアップが失敗します。

アクセサーを単純化してみてください。私は通常、Nokogiri がサポートする CSS から始めて、そこにたどり着けない場合は XPath に切り替えます。そのため、走行距離は異なる場合があります。

例えば:

(rdb:1) puts doc.at('table table tr').to_html

出力:

<tr bgcolor="#7C9BCF">
<td width="12%" align="center"><b>Sunday</b></td>
        <td width="12%" align="center"><b>Monday</b></td>
        <td width="12%" align="center"><b>Tuesday</b></td>
        <td width="12%" align="center"><b>Wednesday</b></td>
        <td width="12%" align="center"><b>Thursday</b></td>
        <td width="12%" align="center"><b>Friday</b></td>
        <td width="12%" align="center"><b>Saturday</b></td>
        <td rowspan="2" width="12%" align="center"><b>Total weekly Hours</b></td>
        </tr>

これは、列ヘッダーを取得するためのより簡単な方法です。

2行目に到達するには、次を使用できます。

(rdb:1) puts doc.at('table table tr[2]').to_html

それはあなたを得る:

<tr bgcolor="#7C9BCF">
<td width="14%" align="center">2013-02-24</td>
        <td width="14%" align="center">2013-02-25</td>
        <td width="14%" align="center">2013-02-26</td>
        <td width="14%" align="center">2013-02-27</td>
        <td width="14%" align="center">2013-02-28</td>
        <td width="14%" align="center">2013-03-01</td>
        <td width="14%" align="center">2013-03-02</td>
        </tr>

セルの内容を取得するには、次を使用できます。

(rdb:1) puts doc.search('table table tr[2] td').map(&:text)

どちらが返されますか:

2013-02-24
2013-02-25
2013-02-26
2013-02-27
2013-02-28
2013-03-01
2013-03-02
2013-03-03
2013-03-04
2013-03-05
2013-03-06
2013-03-07
2013-03-08
2013-03-09
2013-03-10
2013-03-11
2013-03-12
2013-03-13
2013-03-14
2013-03-15
2013-03-16

2 つのテーブルの見出しを返す方法に注目してください。atの代わりに使用できる最初のテーブルに制限するには、 search. at最初に一致したノードをsearch返します。ここでは、配列のような NodeSet を返します。また、の動作searchとは異なり、ドキュメント全体を調べてすべての一致を見つけますat

このコードは、最初のテーブルの 2 番目の行を見つけて、埋め込まれたセルをたどります。

(rdb:1) puts doc.at('table table tr[2]').search('td').map(&:text)
2013-02-24
2013-02-25
2013-02-26
2013-02-27
2013-02-28
2013-03-01
2013-03-02

はるかにシンプルで、理解しやすく、維持しやすくなっています。

于 2013-02-25T03:23:58.290 に答える