2016-07-06 16 views
1

Xpathの使い方は初めてです。私はXpathを使ってPythonでいくつかのデータを解析しようとしています。以下のHTML解析他の兄弟まで兄弟に続くXpath

<table> 
    <tr> 
     <td class="DT">29-04-14</td> 
     <td class="Regio">Text</td> 
     <td class="Md">Text</td> 
    </tr> 
    <tr> 
     <td></td> 
     <td></td> 
     <td class="SomeClass">Some other text</td> 
    </tr> 
    <tr> 
     <td></td> 
     <td></td> 
     <td class="SomeOtherClass">Some more text</td> 
    </tr> 
    <tr> 
     <td class="DT">22-04-14</td> 
     <td class="Regio">Text</td> 
     <td class="Md">Text</td> 
    </tr> 
    <tr> 
     <td></td> 
     <td></td> 
     <td class="OmsAm">more text</td> 
    </tr> 
    <tr> 
     <td class="DT">30-04-14</td> 
     <td class="Regio">Text</td> 
     <td class="Md">Text</td> 
    </tr> 
    <tr> 
     <td></td> 
     <td></td> 
     <td class="OmsBr">Some other Text</td> 
    </tr> 
    <tr> 
     <td></td> 
     <td></td> 
     <td class="OmsBr">More Text</td> 
    </tr> 
    <tr> 
     <td></td> 
     <td></td> 
     <td class="OmsBr">Some different text</td> 
    </tr> 
</table> 

を私はすべて<td> s内のいくつかの値を持つ次の<tr>まで、すべての彼の<td> s内のいくつかの値を持つ<tr>した後、次の兄弟で<td><tr>が、を必要としています。

など。私の現在位置が最初<tr>であると仮定すると、私は、これらの表のセルを必要とする:

<td class="SomeClass">Some other text</td> 
    <td class="SomeOtherClass">Some more text</td> 

は私の現在位置がテーブルの行4

<tr> 
    <td class="DT">22-04-14</td> 
    <td class="Regio">Text</td> 
    <td class="Md">Text</td> 
</tr> 

であると仮定すると、私は

<td class="OmsAm">more text</td> 

を必要としますこれは私がすべての兄弟を得るために使用しているXパスです<tr>、それは私を得るすべて follinwg兄弟./following-sibling::tr/td[1][not(text()[1])]/..

私はKayesianメソッドを実装する必要があると思いますが、私の場合はこれを理解できません。どんな助けでも本当に感謝します!

+0

私は真剣に、私は彼の​​s内のいくつかの値を持つした後、次の兄弟のすべての​​を必要とする '得るが、全てではいくつかの値を持つ次のまではありません​​s.' – SomeDude

+0

Pythonコードを表示してください。この問題を解決するXPath式は長らく残っています。むしろ、比較的簡単なXPath式を記述して、その結果をPythonで処理する必要があります。 –

+0

'"を境界として ''を分割しますか? –

答えて

0

私は質問を誤解することができるが、各<tr><td class="DT">xx-xx-xx</td>のために、あなたはそれの後に、すべての<tr>をしたい、と次<tr><td class="DT">xx-xx-xx</td>前に、一つのパターンを持つ兄弟行以下これらの「境界」<tr><td class="DT">xx-xx-xx</td>要素、および選択にループしている場合以前に見つかった「境界」の数に関する条件。

説明のためにlxmlを使用しましょう。まず、我々はあなたのサンプル入力から文書を作成します。

>>> import lxml.html 
>>> t = '''<table> 
...  <tr> 
...   <td class="DT">29-04-14</td> 
...   <td class="Regio">Text</td> 
...   <td class="Md">Text</td> 
...  </tr> 
...  <tr> 
...   <td></td> 
...   <td></td> 
...   <td class="SomeClass">Some other text</td> 
...  </tr> 
...  <tr> 
...   <td></td> 
...   <td></td> 
...   <td class="SomeOtherClass">Some more text</td> 
...  </tr> 
...  <tr> 
...   <td class="DT">22-04-14</td> 
...   <td class="Regio">Text</td> 
...   <td class="Md">Text</td> 
...  </tr> 
...  <tr> 
...   <td></td> 
...   <td></td> 
...   <td class="OmsAm">more text</td> 
...  </tr> 
...  <tr> 
...   <td class="DT">30-04-14</td> 
...   <td class="Regio">Text</td> 
...   <td class="Md">Text</td> 
...  </tr> 
...  <tr> 
...   <td></td> 
...   <td></td> 
...   <td class="OmsBr">Some other Text</td> 
...  </tr> 
...  <tr> 
...   <td></td> 
...   <td></td> 
...   <td class="OmsBr">More Text</td> 
...  </tr> 
...  <tr> 
...   <td></td> 
...   <td></td> 
...   <td class="OmsBr">Some different text</td> 
...  </tr> 
... </table>''' 
>>> doc = lxml.html.fromstring(t) 

をそれでは、これらは<tr><td class="DT">xx-xx-xx</td>数えてみましょう。(私たち

>>> doc.xpath('//table/tr[td/@class="DT"]') 
[<Element tr at 0x7f948ab00548>, <Element tr at 0x7f948ab005e8>, <Element tr at 0x7f948ab00638>] 
>>> doc.xpath('count(//table/tr[td/@class="DT"])') 
3.0 
>>> list(enumerate(doc.xpath('//table/tr[td/@class="DT"]'), start=1)) 
[(1, <Element tr at 0x7f948ab00548>), (2, <Element tr at 0x7f948ab005e8>), (3, <Element tr at 0x7f948ab00638>)] 

私たちは、これらの行のループと文書で後に来るの行を選択することができます

>>> for cnt, row in enumerate(doc.xpath('//table/tr[td/@class="DT"]'), start=1): 
...  print(row.xpath('./following-sibling::tr/td/text()')) 
... 
['Some other text', 'Some more text', '22-04-14', 'Text', 'Text', 'more text', '30-04-14', 'Text', 'Text', 'Some other Text', 'More Text', 'Some different text'] 
['more text', '30-04-14', 'Text', 'Text', 'Some other Text', 'More Text', 'Some different text'] 
['Some other Text', 'More Text', 'Some different text'] 

我々はの終わりまで、各反復内のすべての行をあまりにも多くの行を選択している:「これらがどの行 『を参照してください』にテキストノードを選択するでしょう。後続の行に追加の「終了」条件が必要です。

私たちは、ループ内でtr[td/@class="DT"]をカウントしているので、我々はtr[td/@class="DT"]各行に先行する持っているどのように多く確認することができます。第二のために

row.xpath('./following-sibling::tr[count(./preceding-sibling::tr[td/@class="DT"])=1] 

row.xpath('./following-sibling::tr[count(./preceding-sibling::tr[td/@class="DT"])=2] 
第一セットの場合

など

>>> for cnt, row in enumerate(doc.xpath('//table/tr[td/@class="DT"]'), start=1): 
...  print(row.xpath('./following-sibling::tr[count(./preceding-sibling::tr[td/@class="DT"])=$count]', count=cnt)) 
... 
[<Element tr at 0x7f948ab00548>, <Element tr at 0x7f948ab005e8>, <Element tr at 0x7f948ec02f98>] 
[<Element tr at 0x7f948ab00548>, <Element tr at 0x7f948ab00638>] 
[<Element tr at 0x7f948ab00548>, <Element tr at 0x7f948ab005e8>, <Element tr at 0x7f948ab00688>] 
>>> 

フム、私たちは各反復であまりにも多くの1行を選択している:

ので、ループでは、我々はlxmlの(an underrated XPath feature supported by lxml)でのXPath変数で現在のカウントを使用することができます。

<tr><td class="DT">30-04-14</td>はまた、我々は、反復ごとの結果の数が右に見える<td class="DT">

>>> for cnt, row in enumerate(doc.xpath('//table/tr[td/@class="DT"]'), start=1): 
...  print(row.xpath(''' 
...   ./following-sibling::tr[count(./preceding-sibling::tr[td/@class="DT"])=$count] 
...        [not(td/@class="DT")]''', count=cnt)) 
... 
[<Element tr at 0x7f948ab00548>, <Element tr at 0x7f948ab005e8>] 
[<Element tr at 0x7f948ab00548>] 
[<Element tr at 0x7f948ab00548>, <Element tr at 0x7f948ab005e8>, <Element tr at 0x7f948ab00688>] 
>>> 

を持っていない行を選択するための余分な述語を追加することができます<tr><td class="DT">

の前の1を持っているためです。 のは、最終的にはテキストノードを使用して確認してみましょう:

>>> for cnt, row in enumerate(doc.xpath('//table/tr[td/@class="DT"]'), start=1): 
...  print(row.xpath(''' 
...   ./following-sibling::tr[count(./preceding-sibling::tr[td/@class="DT"])=$count] 
...        [not(td/@class="DT")] 
...    /td/text()''', count=cnt)) 
... 
['Some other text', 'Some more text'] 
['more text'] 
['Some other Text', 'More Text', 'Some different text'] 
>>> 
+0

うわー、素晴らしい説明と完璧な作品!どうもありがとう! – Gino