2017-02-12 18 views
-1

Python Xpathでヘルプを評価してください。私は次のXMLコードを持っています。 現在、私はPythonを使用していて、1行ずつ読み込み、それを抽出しようとしています。しかし、私はテーブルが1000行の長さであることを理解しています。Python Xpathを使用してCSVファイルにデータを抽出する

私はXMLコードからこのデータを抽出し、csvファイルに入力したいと考えています。

Xpathを使用するにはどうすればいいですか?

サンプルXMLコード:

<thead> 
    <tr> 
     <th class="section" data-bind="text: name">Ratios</th> 
     <!-- ko foreach : $parent.dataPoints --> 
      <th> 
       <span data-bind="text: absPeriod.indexOf('LTM') != -1 ? 'LTM Ending' : absPeriod">FY2013</span> 
       <br> 
       <span data-bind="text: periodDate, format: 'date'">30/Jun/2013</span> 
      </th> 

      <th> 
       <span data-bind="text: absPeriod.indexOf('LTM') != -1 ? 'LTM Ending' : absPeriod">FY2014</span> 
       <br> 
       <span data-bind="text: periodDate, format: 'date'">30/Jun/2014</span> 
      </th> 

      <th> 
       <span data-bind="text: absPeriod.indexOf('LTM') != -1 ? 'LTM Ending' : absPeriod">FY2015</span> 
       <br> 
       <span data-bind="text: periodDate, format: 'date'">30/Jun/2015</span> 
      </th> 

      <th> 
       <span data-bind="text: absPeriod.indexOf('LTM') != -1 ? 'LTM Ending' : absPeriod">FY2016</span> 
       <br> 
       <span data-bind="text: periodDate, format: 'date'">30/Jun/2016</span> 
      </th> 

      <th> 
       <span data-bind="text: absPeriod.indexOf('LTM') != -1 ? 'LTM Ending' : absPeriod">LTM Ending</span> 
       <br> 
       <span data-bind="text: periodDate, format: 'date'">31/Dec/2016</span> 
      </th> 
     <!-- /ko --> 
     <th class="uncheck" data-bind="visible: $root.series().length > 0" style="display: none;">&nbsp;</th> 
    </tr> 
</thead> 
<tbody> 
    <!-- ko foreach : dataPoints --> 
     <tr data-bind="css: { 'odd': ($index() % 2 == 0) }" class="odd"> 
      <td class="checkbox left"> 
       <div class="trigger" data-bind="attr: { 'data-name': property, 'data-group': group }, click: function(data, event) { $root.handleClick($root, data, event); }" data-name="returnAssets" data-group="ratio"> 
        <span class="name" data-bind="text: name">Return on Assets</span> 
        <span data-bind="visible: $data.hasOwnProperty('glossaryTerm')"> 
         <img src="img/info.png" alt="" data-bind="tooltip: $data.hasOwnProperty('glossaryTerm') ? glossaryTerm : null" tooltip-copy="Return on Assets is a measure of company profitability relative to total assets. It is calculated by dividing tax-effective EBIT (Earnings before Interest and Tax) by Average Total Assets over a 12-months period." class="tooltip-item"> 
        </span> 
       </div> 
       <input type="checkbox"> 
      </td> 
      <!-- ko foreach : $root.dataPoints --> 
       <td data-bind="text: $data.hasOwnProperty($parent.property) &amp;&amp; $data[$parent.property] != null? $data[$parent.property] : '-', formatNonZeroValue: 'number', attr: { 'data-value': $data.hasOwnProperty($parent.property) ? $data[$parent.property] : null, 'data-name': $parent.property }" data-value="14.6931" data-name="returnAssets">14.693</td> 

       <td data-bind="text: $data.hasOwnProperty($parent.property) &amp;&amp; $data[$parent.property] != null? $data[$parent.property] : '-', formatNonZeroValue: 'number', attr: { 'data-value': $data.hasOwnProperty($parent.property) ? $data[$parent.property] : null, 'data-name': $parent.property }" data-value="13.5242" data-name="returnAssets">13.524</td> 

       <td data-bind="text: $data.hasOwnProperty($parent.property) &amp;&amp; $data[$parent.property] != null? $data[$parent.property] : '-', formatNonZeroValue: 'number', attr: { 'data-value': $data.hasOwnProperty($parent.property) ? $data[$parent.property] : null, 'data-name': $parent.property }" data-value="14.5923" data-name="returnAssets">14.592</td> 

       <td data-bind="text: $data.hasOwnProperty($parent.property) &amp;&amp; $data[$parent.property] != null? $data[$parent.property] : '-', formatNonZeroValue: 'number', attr: { 'data-value': $data.hasOwnProperty($parent.property) ? $data[$parent.property] : null, 'data-name': $parent.property }" data-value="13.0935" data-name="returnAssets">13.094</td> 

       <td data-bind="text: $data.hasOwnProperty($parent.property) &amp;&amp; $data[$parent.property] != null? $data[$parent.property] : '-', formatNonZeroValue: 'number', attr: { 'data-value': $data.hasOwnProperty($parent.property) ? $data[$parent.property] : null, 'data-name': $parent.property }" data-value="15.4657" data-name="returnAssets">15.466</td> 
      <!-- /ko --> 
      <td class="uncheck" data-bind="visible: $root.series().length > 0, click: function(data, event) { $root.handleClick($root, data, event); }" style="display: none;"> 
       <span data-bind="visible: $root.canUncheck($root, property)" style="display: none;">[UNCHART]</span> 
      </td> 
     </tr> 

     <tr data-bind="css: { 'odd': ($index() % 2 == 0) }"> 
      <td class="checkbox left"> 
       <div class="trigger" data-bind="attr: { 'data-name': property, 'data-group': group }, click: function(data, event) { $root.handleClick($root, data, event); }" data-name="returnCapital" data-group="ratio"> 
        <span class="name" data-bind="text: name">Return on Capital</span> 
        <span data-bind="visible: $data.hasOwnProperty('glossaryTerm')"> 
         <img src="img/info.png" alt="" data-bind="tooltip: $data.hasOwnProperty('glossaryTerm') ? glossaryTerm : null" tooltip-copy="Return on Capital is a measure of company profitability relative to total capitals. It is calculated by dividing tax-effective EBIT (Earnings before Interest and Tax) by Average Total Capital over a 12-months period." class="tooltip-item"> 
        </span> 
       </div> 
       <input type="checkbox"> 
      </td> 
      <!-- ko foreach : $root.dataPoints --> 
       <td data-bind="text: $data.hasOwnProperty($parent.property) &amp;&amp; $data[$parent.property] != null? $data[$parent.property] : '-', formatNonZeroValue: 'number', attr: { 'data-value': $data.hasOwnProperty($parent.property) ? $data[$parent.property] : null, 'data-name': $parent.property }" data-value="30.0726" data-name="returnCapital">30.073</td> 

       <td data-bind="text: $data.hasOwnProperty($parent.property) &amp;&amp; $data[$parent.property] != null? $data[$parent.property] : '-', formatNonZeroValue: 'number', attr: { 'data-value': $data.hasOwnProperty($parent.property) ? $data[$parent.property] : null, 'data-name': $parent.property }" data-value="25.6597" data-name="returnCapital">25.66</td> 

       <td data-bind="text: $data.hasOwnProperty($parent.property) &amp;&amp; $data[$parent.property] != null? $data[$parent.property] : '-', formatNonZeroValue: 'number', attr: { 'data-value': $data.hasOwnProperty($parent.property) ? $data[$parent.property] : null, 'data-name': $parent.property }" data-value="26.4617" data-name="returnCapital">26.462</td> 

       <td data-bind="text: $data.hasOwnProperty($parent.property) &amp;&amp; $data[$parent.property] != null? $data[$parent.property] : '-', formatNonZeroValue: 'number', attr: { 'data-value': $data.hasOwnProperty($parent.property) ? $data[$parent.property] : null, 'data-name': $parent.property }" data-value="26.0215" data-name="returnCapital">26.021</td> 

       <td data-bind="text: $data.hasOwnProperty($parent.property) &amp;&amp; $data[$parent.property] != null? $data[$parent.property] : '-', formatNonZeroValue: 'number', attr: { 'data-value': $data.hasOwnProperty($parent.property) ? $data[$parent.property] : null, 'data-name': $parent.property }" data-value="27.67" data-name="returnCapital">27.67</td> 
      <!-- /ko --> 
      <td class="uncheck" data-bind="visible: $root.series().length > 0, click: function(data, event) { $root.handleClick($root, data, event); }" style="display: none;"> 
       <span data-bind="visible: $root.canUncheck($root, property)" style="display: none;">[UNCHART]</span> 
      </td> 
     </tr> 
</tbody> 

サンプル出力は、テーブルレポートとして

enter image description here

+0

残念なことに、これはXMLではないが、後者はXMLよりもマークアップルールの方が剛性が低く、XMLが失敗すると解析するHTMLである。例えば、 '
'タグは整形式のXMLであるために '
'を自動的に閉じるべきであり、これによってXPath呼び出しが壊れることさえあります。 – Parfait

+0

必要な出力テーブルを得るために他にどのような方法を使用する必要がありますか? –

答えて

0

をExcelにはいlxml.etreeでHTMLを解析することが可能です。しかし、正確なコードは、ファイルで使用されている名前空間によって異なります。 あなたはファイルの先頭に

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
</head> 
<body> 

を持っていると仮定すると、このコードは動作します:

from lxml import etree 

parser = etree.XMLParser(attribute_defaults=False, load_dtd=True, resolve_entities=True,remove_comments=False, ns_clean=True, recover=True) 
file = "C:\\test1.html" # your filename here 
data = etree.parse(file, parser=parser) 
headers = etree.XPath('''//h:span [@data-bind="text: absPeriod.indexOf('LTM') != -1 ? 'LTM Ending' : absPeriod"] ''', namespaces={'h':"http://www.w3.org/1999/xhtml"}) 
dates = etree.XPath('''//h:span [@data-bind="text: periodDate, format: 'date'"] ''', namespaces={'h':"http://www.w3.org/1999/xhtml"}) 
assets = etree.XPath('''//h:td [@data-name="returnAssets"]''', namespaces={'h':"http://www.w3.org/1999/xhtml"}) 
capitals = etree.XPath('''//h:td [@data-name="returnCapital"]''', namespaces={'h':"http://www.w3.org/1999/xhtml"}) 
header = [x.text for x in headers(data)] 
date = [x.text for x in dates(data)] 
asset = [x.text for x in assets(data)] 
capital = [x.text for x in capitals(data)] 
print(header) 
print(date) 
print(asset) 
print(capital) 

があなたに与えます:

['FY2013', 'FY2014', 'FY2015', 'FY2016', 'LTM Ending'] 
['30/Jun/2013', '30/Jun/2014', '30/Jun/2015', '30/Jun/2016', '31/Dec/2016'] 
['14.693', '13.524', '14.592', '13.094', '15.466'] 
['30.073', '25.66', '26.462', '26.021', '27.67'] 

これ以降では、今のデータを置くことができますCSV(私はこれについては申し訳ありません)。

1

私は以前にこの問題を解決しなければならず、https://pypi.python.org/pypi/messytablesのためのHTMLパーサを書いて、テーブルにプログラム的にアクセスしました。

lxml.etreeではなく、htmlにはlxml.htmlを使用する必要があります。インターフェイスはほとんど同じです。

基本的に、あなたは行を抽出するために、各table要素(tr)をループ、各trtdthを抽出し、それらのそれぞれからテキストを取得する必要があります。私はあなたが得ようとしている要素を過大に指定しないでしょう。

データを再構成しなければならない問題が発生した場合は、https://github.com/sensiblecodeio/xypathが役に立ちます。 [免責事項:私はほとんどこれを書いた]

関連する問題