使用RegEx从伪标记之间提取数据(不能使用BeautifulSoup)

2024-06-10 19:11:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在尝试各种方法,不管我做什么,我都得到一个空白输出。下面是我要导入和解析的文件的简短版本:

<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>

比如说,在每一个条目之间都有一个“我的地址”和“我的地址”列。在每个标记的数据后面也有返回,当我将其拉入python时,返回结果为“\n”。以下是我目前为止尝试的RegEx(s是我读入文件并重新导入的变量):

^{2}$

我尝试过不带“\n”和使用(+?)的方法而不是(.*)。在

如果您需要更多的信息来帮助我,请告诉我,我们将非常感谢您的帮助。我的最终目的是能够很容易地从ftp://ftp.fbo.gov/FBOFeed20130311导入数据(似乎有多种表类型,但我现在关注的是PRESOL,只是为了让这个概念的证明从地面上开始。在


Tags: 文件数据方法版本date地址ftp空白
1条回答
网友
1楼 · 发布于 2024-06-10 19:11:57

我在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标记包围。也许你最好使用一个更算法化的方法,而不是试图用一个regex解析整个“行”数据。我想可能有足够多的案子可以考虑一行一行地走。在

祝你好运!在

网友
2楼 · 发布于 2024-06-10 19:11:57

以下是创建一个可以转换为表的数据结构的方法:

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"]))
网友
3楼 · 发布于 2024-06-10 19:11:57

花了一些时间,并且能够为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'}

相关问题 更多 >