簡體   English   中英

使用 Python Xpath 將數據提取到 csv 文件

[英]Using Python Xpath to extract data to a csv file

感謝 Python Xpath 的幫助。 我有以下 xml 代碼。 目前,我正在使用 python 並逐行讀取,然后嘗試提取它。 但是我意識到這些表格有 1000 行長,並且逐行閱讀它並將邏輯放入其中超出了我的范圍。

我想從 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>

示例輸出到 excel 作為表格報告

在此處輸入圖片說明

我之前不得不解決這個問題,並為https://pypi.python.org/pypi/messytables編寫了一個 HTML 解析器來獲得對表的編程訪問。

您應該將 lxml.html 用於 html,而不是 lxml.etree。 界面大同小異。

本質上,您應該遍歷每個table元素以提取行 ( tr ),每個tr以提取tdth ,並從每個元素中獲取文本。 我不會過度指定您想要獲取的元素。

如果您遇到問題,然后必須重組您得到的數據,您可能會發現https://github.com/sensiblecodeio/xypath很有用。 [免責聲明:我寫了大部分]

是的,可以使用 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 中(抱歉我不知道)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM