1

我一直在尝试各种方式,无论我做什么,我都会得到一个空白输出。这是我试图导入和解析的文件中的缩短版本:

<PRESOL>
<DATE>0310
<AGENCY>Defense Logistics Agency
<DESC>*(this is full of HTML tags and the such)*
<URL>https://www.fbo.gov/spg/DLA/J3/DSCR-BSM/SPE4A713R0575/listing.html
<SETASIDE>N/A
</PRESOL>

我想为每个 DATE、AGENCY、DESC、URL 和 SETASIDE 创建一个包含一列的表,因为在“PRESOL”标签之间有 100 个这样的条目。每个标签的数据之后也有返回,当我将它拉入 python 时,它会显示为“\n”。这是我到目前为止尝试过的正则表达式(s 是我将文件读入并重新导入的变量):

testall = re.findall(r'<PRESOL>\n<DATE>(.*?)\n<AGENCY>(.*?)\n<DESC>(.*?)\n<URL>(.*?)\n<SETASIDE>(.*?)\n</PRESOL>', s)

我在没有“\n”的情况下尝试了这个,也没有使用 (.+?) 而不是 (.*?)。

如果您需要更多信息来帮助我,请告诉我,非常感谢任何帮助。我的最终目标是能够轻松地从ftp://ftp.fbo.gov/FBOFeed20130311导入数据(似乎有多种表类型,但我目前专注于 PRESOL 只是为了得到这个概念证明地面。

4

3 回答 3

1

花了一些时间,能够为 FBO 数据构建解析器函数。怀疑您仍然需要它,但也许这会对其他人有所帮助。

def fbo_parser(fbo):
     split_fbo = fbo.split('<PRESOL>')
     n_ops = len(split_fbo)
     all_ops_dict = {}
     for i in range(1, n_ops):
         strings = fbo.split('<PRESOL>')[i].replace('</PRESOL>', '')
         strings = strings.split('<')
         lists = [x.split('>') for x in strings]
         opp_dict = {}
         desc_count = 0 
         desc = ['OpDesc', 'URL_Desc', 'EMAIL_Desc']
         for ii in lists:
             if len(ii) == 2:
                 if ii[0] == 'DESC':
                     #TODO: Figure out a better name for the duplicate DESC
                     ii[0] = ii[0] + str(desc_count)
                     desc_count += 1

                 opp_dict[ii[0]] = ''.join([x for x in filter(None, ii[1].split('\\n'))])
         all_ops_dict[i] = opp_dict
     return all_ops_dict

f = open('FBOFeed19991231', 'rb')
fbo = str(f.read())
fbop = fbo_parser(fbo)

fbop[68]
RETURNS:>>
{'ADDRESS': 'Christel.Wittmer@ramstein.af.mil',
 'AGENCY': 'Department of the Air Force',
 'CLASSCOD': '32',
 'CONTACT': 'Christel Wittmer, Ms., Phone (49) 631 3539 174, Fax (49) 631 3539 158, Email Christel.Wittmer@ramstein.af.mil - Ursula Nabinger, Ms., Phone (49) 631 3539 178, Fax (49) 631 3539 158, Email Ursula.Nabinger@ramstein.af.mil',
 'DATE': '0720',
 'DESC0': 'WORKBENCH FOR VEHICLE MAINTENANCE,2 METER LONG, TOP IS METAL COVERWERKBANK, 2 METER LANG, SCHICHSTOFF OEL AND FEUCHTIGKEITSBESTAENDIG  (22EA/STCK)WORKBENCH FOR VEHICLE MAINTENANCE, 2 METER LONG TOP CONSISTS 40 MM TICK WOODWERKBANK, 2 METER LANG ARBEITSPLATTE HOLZ MEHRSCHICHTVERLEIMTESBUECHENHOLZ (22EA/STCK)FOR MORE INFO CALL MRS WITTMER 0631-3539-174!',
 'DESC1': 'Link to FedBizOpps document.',
 'DESC2': 'Christel Wittmer',
 'EMAIL': '',
 'LINK': '',
 'LOCATION': '700 CONS',
 'OFFADD': 'United States Air Force, United States Air Force Europe, Rhine Ordnance Barracks, USAFE CONS, UNIT 3115, Germany, .  09094-3115',
 'OFFICE': 'United States Air Force Europe',
 'RESPDATE': '073099',
 'SOLNBR': 'F61521-99T0607',
 'SUBJECT': 'WORKBENCH FOR VEHICLE MAINTENANCE',
 'URL': 'http://www.fbo.gov/spg/USAF/USAFE/ROB/F61521-99T0607/listing.html',
 'YEAR': '99',
 'ZIP': '09021'}
于 2017-05-19T04:18:09.600 回答
0

我在 ftp 中看到了以下示例(我删除了第一个字段以专注于 popaddress):

In [7]: data = """<PRESOL>
   ...: <DESC>Link To Document
   ...: <SETASIDE>N/A
   ...: <POPCOUNTRY>US
   ...: <POPADDRESS>Moody AFB, GA
   ...: Avon Park, FL
   ...: </PRESOL>"""

In [11]: re.findall(r'<PRESOL>\n<DESC>(.*?)\n<SETASIDE>(.*?)\n<POPCOUNTRY>(.*?)\n<POPADDRESS>(.*?)\n</PRESOL>', data)
Out[11]: []

由于最后一个字段的 \n 后面没有标签,因此它不匹配。那就是问题所在。

查看 FTP 中的数据,我发现还有其他多行字段,例如 DESC、CONTACT,在某些情况下相当大并且被 HTML 标记包围。也许您最好使用更算法的方法,而不是尝试使用单个正则表达式解析整个“行”数据。我认为可能有足够的极端案例可以考虑逐行进行。

祝你好运!

于 2013-03-15T01:35:55.280 回答
0

这是创建可以变成表格的数据结构的一个想法:

presol = []
split = re.split('<\/PRESOL>', file_data)

for s in split:
    d = {}
    for k,v in re.findall('<([^>]+)>(.[^<]+)\n', s, re.M|re.S):
        d[k]=v
        presol.append(d)

print("DATE\tAGENCY\tDESC\tURL\tSETASIDE\n")
for p in presol:
    print("%s\t%s\t%s\t%s\t%s\n"%(p["DATE"], p["AGENCY"], p["DESC"], p["URL"], p["SETASIDE"]))
于 2013-03-15T01:38:27.453 回答