Используя Python, как извлечь информацию из файлов HTML на основе тега id? - PullRequest
0 голосов
/ 27 июня 2019

Я пытаюсь создать скрипт Python, который будет извлекать информацию из некоторых файлов HTML.У меня нет проблем с os и glob, чтобы получить все необходимые файлы.Но самая сложная часть - это анализ этих файлов.Вот мой код:

from lxml import etree
...
parser = etree.HTMLParser(remove_comments=True, recover=True)
tree = etree.parse(os.path.join(path, filename), parser=parser)
...
for item in tree.getiterator():
    id = item.attrib.get('id', None)

    if item.tag == 'title':
        device.name = item.text
    elif id:
        setattr(device, id, item.text)

Этот код, кажется, работает с некоторой информацией в файле, такой как этот:

<td id="type">Network Camera</td>

, но затем файлы HTML имеют несколько строк, напримервот этот:

<td colspan="2"><span id="name"></span>:&nbsp;XYZ</td>

Я не получаю ничего полезного.Я вставил операторы print и вижу элементы td (без id и без text) и spanid, но также без text).

Затемвот это:

<td><table><tr>
    <td><a href="..." id="ipLink"> <span id="ipTxt"></span></a>:&nbsp;
    </td><td>
        1.2.4.3&nbsp;(<span id="staTxt"></span>)
    </td>
</tr></table></td>

... что для моих человеческих глаз кажется очевидным, что я должен получить ip=1.2.4.3, но я не знаю, как убедить Python извлечь это.


обновление:

Полный пример файла ввода:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <meta http-equiv="Pragma" content="no-cache">
<title>AXIS M3037</title>
</head>
<body>


<table>
  <tr>
    <td id="type">Network Camera</td>
    <td>|</td>
    <td valign="middle" align="left" width=169 class="menuActive" id="mainMenu" nowrap>

    </td>
    <td><a href="/" id="tLViewTxt"><span id="ti2LViewTxt"></span></a></td>
    <td><a href="/?id=171" id="tSetTxt"><span id="ti2SetTxt"></span></a></td>
    <td colspan="2"><span id="version"></span>:&nbsp;1.23</td>

    <td>
        1.2.1.1&nbsp;(<span id="xyz"></span>)
    </td>
    <td colspan="2">
        <a href="/?id=171" id="dateTimeLink">
            <span id="datTimTxt"></span>
        </a>&nbsp;
        <input type="text" name="CurrentServerDate" value="2018-08-14" disabled>
        &nbsp;&nbsp;&nbsp;
        <input type="text" name="CurrentServerTime" value="11:03:49" disabled>
    </td>

    <td><table><tr>
        <td><a href="..." id="ipLink">
                <span id="ipTxt"></span>
            </a>:&nbsp;
        </td><td>
            1.2.4.3&nbsp;(<span id="staTxt"></span>)
        </td>
    </tr></table></td>
  </tr>
  <tr>
    <td nowrap colspan="2">:&nbsp;
        1
        &nbsp;<span id="videoTxt"></span>&nbsp;&nbsp;
        0
        &nbsp;<span id="audTxt"></span>
        &nbsp;&nbsp;</td>
    <td colspan="2" nowrap>
        <span id="upTimTxt"></span>&nbsp;
        <span id="theuptimevalue">130 days, 3:40</span></td>
  </tr>
</table>
</body>
</html>

Желаемая извлеченная информация:

'type': 'Network Camera'
'version': '1.23'           (or ': 1.23'  --- I can remove ':')
'xyz': '1.2.1.1'
'staTxt': '1.2.4.3'         (or better: 'ipTxt': '1.2.4.3' )
'videoTxt': '1'
'audTxt': '0'
'theuptimevalue': '130 days, 3:40'

1 Ответ

1 голос
/ 27 июня 2019

Что ж, следующее довольно запутанно и, вероятно, хрупко, но оно помогает при использовании html:

from lxml.html import fromstring
data = [your html above]

tree = fromstring(data)

for typ in tree.xpath("*//td[@id='type']"):
    print('type',typ.text)
for spa in tree.xpath("*//span[@id='version']/../text()"):
    print('version',spa)
for spa in tree.xpath("*//span[@id='name']/../text()"):
    print(spa.replace(':','').strip(),tree.xpath("*//span[@id='name']/../following-sibling::td/text()")[0].strip())
for spa in tree.xpath("(*//span[@id='staTxt']/..)[2]"):
    print('ipTxt',spa.text.strip())
for spa in tree.xpath("*//span[@id='videoTxt']/.."):
    print('videoTxt',spa.text.replace(':','').strip())  
for spa in tree.xpath("*//span[@id='audTxt']/.."):
    num = "".join(spa.text_content().split())
    print('audTxt2',num[2])
for spa in tree.xpath("*//span[@id='theuptimevalue']"):
    print('theuptimevalue',spa.text.replace(':','').strip())  

Выход:

type Network Camera
version : 1.23
XYZ 1.2.1.1
ipTxt 1.2.4.3
videoTxt 1
audTxt2 0
theuptimevalue 130 days, 340

Вы можете улучшить его, если поиграете с ним, но это должно быть началом ...

...