使用该库的 makeHTMLTags 方法可以通过 pyparsing 轻松完成一些 HTML 抓取(makeHTMLTags 返回一对表达式,用于开始和结束标签,但在您的示例中,只需要开始标签):
from pyparsing import makeHTMLTags
fcTag = makeHTMLTags("fc")[0]
tagAttrs = 'dt s tx tn'.split()
for match in fcTag.searchString(htmltext):
print ' '.join("%s:%s" % (attr,match[attr]) for attr in tagAttrs)
打印:
dt:2013-03-07 s:d220 tx:16 tn:11
dt:2013-03-08 s:d220 tx:15 tn:10
dt:2013-03-09 s:d220 tx:15 tn:10
这使得将这个片段解析器与 pyparsing 的其他功能(例如运行时解析操作、语义检查等)结合起来变得很容易。
编辑
如果您希望所有 dt、s 等在它们各自的列表中(在 Python 中,我们称它们为“列表”,而不是“向量”),请执行以下操作:
dtArray = []
sArray = []
txArray = []
tnArray = []
for match in fcTag.searchString(htmltext):
dtArray.append(match.dt)
sArray.append(match.s)
txArray.append(match.tx)
tnArray.append(match.tn)
print ' '.join("%s:%s" % (attr,match[attr]) for attr in tagAttrs)
我以前见过这样的代码,这是一种糟糕的数据结构模式。您可以通过获取dtArray[i]、sArray[i] 等来访问原始表的第 i 个条目的值。
请考虑使用 Python 提供的几种结构化类型之一。您有多种选择:
A.使用字典。
fcArray = []
for match in fcTag.searchString(htmltext):
fcArray.append(dict((attr,match[attr]) for attr in tagAttrs))
现在要获取第 i 个条目,只需获取 fc = fcArray[i],然后从该字典中访问 fc['dt']、fc['s'] 等值。
B.使用命名元组。
from collections import namedtuple
FCData = namedtuple("FCData", tagAttrs)
fcArray = []
for match in fcTag.searchString(htmltext):
fcArray.append(FCData(*(match[attr] for attr in tagAttrs)))
您再次使用fc = fcArray[i] 获取第i 个条目,但现在您使用fc.dt、fc.s 等访问值。我发现这种形式比dict 形式看起来更干净,但是是一些限制。所有的标签名称都必须是合法的 Python 标识符,所以如果你有一个标签“rise/run”,那么你就不能使用命名元组。此外,namedtuples 是不可变的 - 您不能使用现有的 FCData fc 并使用 fc.dt = "new datetime value" 分配到其 dt 字段。另一方面,dicts 将允许这样做。
C.使用对象。最简单的是创建空对象实例的“bag”类型对象,您可以通过简单的赋值或 setattr 调用为其添加属性:
class FCData(object): pass
fcArray = []
for match in fcTag.searchString(htmltext):
fc = FCdata()
for attr in tagAttrs:
setattr(fc, attr, match[attr])
fcArray.append(fc)
您使用fc = fcArray[i] 获得第i 个条目,并且像namedtuple 一样,您使用fc.dt 获得属性等等。但如果需要,您也可以修改属性,分配fc.dt = "new datetime value" 将起作用。
D.只需使用 pyparsing 的 searchString 方法创建的对象即可。
fcArray = fcTag.searchString(htmltext)
pyparsing 返回ParseResults,它结合了字典和命名元组的行为。就像在使用 fc = fcArray[i] 访问第 i 个条目之前一样。您可以使用fc.dt 或fc['dt'] 读取dt 属性。你可以阅读fc.dt,但你不能给它赋值,就像namedtuple一样。您可以分配给fc['dt'],就像字典一样。