使用Python我想从一堆包含硬编码数据的javascript文件中将下面显示的数据行提取到csv文件中,如下所示:
....html code.... hotels[0] = new hotelData(); hotels[0].hotelName = "MANHATTAN"; hotels[0].hotelPhone = ""; hotels[0].hotelSalesPhone = ""; hotels[0].hotelPhone = 'Phone: 888-350-6432
'; hotels[0].hotelStreet = "787 11TH AVENUE"; hotels[0].hotelCity = "NEW YORK"; hotels[0].hotelState = "NY"; hotels[0].hotelZip = "10019"; hotels[0].hotelId = "51543"; hotels[0].hotelLat = "40.7686";; hotels[0].hotelLong = "-73.992645";; hotels[1] = new hotelData(); hotels[1].hotelName = "KOEPPEL"; hotels[1].hotelPhone = ""; hotels[1].hotelSalesPhone = ""; hotels[1].hotelPhone = 'Phone: 718-721-9100
'; hotels[1].hotelStreet = "57-01 NORTHERN BLVD."; hotels[1].hotelCity = "WOODSIDE"; hotels[1].hotelState = "NY"; hotels[1].hotelZip = "11377"; hotels[1].hotelId = "51582"; hotels[1].hotelLat = "40.75362";; hotels[1].hotelLong = "-73.90366";; var mykey = "AlvQ9gNhp7oNuvjhkalD4OWVs_9LvGHg0ZLG9cWwRdAUbsy-ZIW1N9uVSU0V4X-8"; var map = null; var pins = null; var i = null; var boxes = new Array(); var currentBox = null; var mapOptions = { credentials: mykey, enableSearchLogo: false, showMapTypeSelector: false, enableClickableLogo: false } .....html code .....
因此,所需的csv输出将类似于上述数据的行:
MANHATTAN,,,Phone: 888-350-6432 ... KOEPPEL,,,Phone: 718-721-9100 ...
我应该使用代码生成工具直接解析上面的语句来获取数据吗?哪种是将数千个Javascript文件中包含的数据转换为csv表格格式的最有效的Python方法?
更新
理想情况下,我希望解决方案将JavaScript语句解析为Python对象,然后将其存储到CSV以最大限度地独立于输入脚本代码的排序和格式化
答案 0 :(得分:1)
我建议使用正则表达式挑选所有“hotel [#]。...”行,然后将所有结果添加到字典中。然后,使用字典输出到CSV文件。以下应该有效:
import re
import csv
src_text = your_javascript_text
p = re.compile(r'hotels\[(?P<hotelid>\d+)\].(?P<attr>\w+) = ("|\')(?P<attr_val>.*?)("|\');', re.DOTALL)
hotels = {}
fieldnames = []
for result in [m.groupdict() for m in p.finditer(src_text)]:
if int(result['hotelid']) not in hotels:
hotels[int(result['hotelid'])] = {}
if result['attr'] not in fieldnames:
fieldnames.append(result['attr'])
hotels[int(result['hotelid'])][result['attr']] = result['attr_val']
output = open('hotels.csv','wb')
csv_writer = csv.DictWriter(output, delimiter=',', fieldnames=fieldnames, quoting=csv.QUOTE_ALL)
csv_writer.writerow(dict((f,f) for f in fieldnames))
for hotel in hotels.items():
csv_writer.writerow(hotel[1])
你现在有一个带有属性的酒店字典,按照Javascript中的ID分组,以及输出文件“hotels.csv”(带有标题行和正确的转义)。我确实做过像命名小组这样的事情,但实际上并不是必需的,但却发现它更具自我评论性。
应该注意的是,如果在Javascript中提供相同的组两次,比如hotelPhone,则最后一个是唯一存储的。
在处理此类问题时,您和您的判断需要多少耐受性和卫生。您可能需要修改正则表达式以处理示例,而不是提供小样本(即,捕获组中的更改,限制与行开头的匹配等);或转义换行符,如电话号码中的那些;或删除某些文本(例如电话号码中的“电话:”)。我们没有真正的方法来了解这一点,所以请记住这一点。
干杯!
答案 1 :(得分:0)
如果这是你必须经常做的事情,并且你想让这个过程完全自动化,我认为最简单的方法是使用Python解析文件,然后使用csv Python module写入csv。
您的代码可能看起来像这样:
with open("datafile.txt") as f:
hotel_data = []
for line in f:
# Let's make sure the line not empty
if line:
if "new hotelData();" in line:
if hotel_data:
write_to_csv(hotel_data)
hotel_data = []
else:
# Data, still has ending quote and semi colon
data = line.split("= ")[1]
# Remove ending quote and semi colon
data = data[:-2]
hotel_data.append(data)
def write_to_csv(hotel_data):
with open('hotels.csv', 'wb') as csvfile:
spamwriter = csv.writer(csvfile, delimiter=',',
quotechar='""', quoting=csv.QUOTE_MINIMAL)
spamwriter.writerow(hotel_data)
请注意,我没有测试过此代码,它只是为了帮助您并指出正确的方向,它不是完整的解决方案。
答案 2 :(得分:0)
如果每个酒店都在您的文件中声明了所有字段(即,如果所有酒店都有相同数量的行,即使其中一些是空的),您可以尝试使用简单的正则表达式来提取包围的每个值引号(“xxx”),然后按编号对它们进行分组(例如,将每5个字段分组为一行,然后添加换行符。)
一个可行的简单正则表达式是["'][^"']*["']
(编辑:这是因为我看到一些文件(即电话)使用单引号,其余的使用引号)。
要进行搜索,请使用findall
:
compPattern = re.compile(pattern)
results = compPattern.findall(compPattern)