python - 使用 Python,如何根据 id 标签从 HTML 文件中提取信息?
问题描述
我正在尝试创建一个 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>: XYZ</td>
我没有得到任何有用的东西。我插入了打印语句,我可以看到元素td
(没有id
和没有text
)和span
(有id
,但也没有text
)。
然后是这个:
<td><table><tr>
<td><a href="..." id="ipLink"> <span id="ipTxt"></span></a>:
</td><td>
1.2.4.3 (<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>: 1.23</td>
<td>
1.2.1.1 (<span id="xyz"></span>)
</td>
<td colspan="2">
<a href="/?id=171" id="dateTimeLink">
<span id="datTimTxt"></span>
</a>
<input type="text" name="CurrentServerDate" value="2018-08-14" disabled>
<input type="text" name="CurrentServerTime" value="11:03:49" disabled>
</td>
<td><table><tr>
<td><a href="..." id="ipLink">
<span id="ipTxt"></span>
</a>:
</td><td>
1.2.4.3 (<span id="staTxt"></span>)
</td>
</tr></table></td>
</tr>
<tr>
<td nowrap colspan="2">:
1
<span id="videoTxt"></span>
0
<span id="audTxt"></span>
</td>
<td colspan="2" nowrap>
<span id="upTimTxt"></span>
<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'
解决方案
好吧,以下内容非常复杂,可能很脆弱,但它在提供的 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
如果你玩它,你可能会改进它,但应该是一个开始......
推荐阅读
- c# - C#:对于标志,bitvector32 比 bool 更有效吗?
- laravel - 是否可以将数据传递给 Laravel 中的 app.js?
- android - Android Webview 记住账号密码
- android - 找不到任何与 com.android.support:appcompat-v7:29.+ 匹配的版本
- python - 如何在 SciKit-Learn Python 中识别 KNN 模型中每个集群内的记录?
- flutter - 如何从 aync/await 函数返回布尔值并将其传递给其他页面中的其他变量
- ruby - 最新的 gem 版本未安装
- python - 如何在 Beam 中将单例 pvalue 输出到控制台?
- windows - 普通 Powershell 提示符中的工作命令在 PSSession 中拒绝访问
- stripe-payments - 如何将优惠券添加到 Stripe 的结账处