目前我的网络抓取工具正在收集所有数据并将它们全部放入字典中,如下所示:
def save_data_to_json(data, json_file_name):
print 'Saving data into json file...'
with open(json_file_name, 'a') as outfile:
json.dump(data, outfile, sort_keys = True, indent = 4, ensure_ascii = False)
def gather_data(page_url, soup, all_data):
#return if this page doesn't contain data
if (soup.find('h4') == None) or (soup.find('span') == None):
return
company_name = soup.h4.span.text
table_body = soup.tbody
table_rows = table_body.find_all('tr')
company_data = {}
for tr in table_rows:
td = tr.find_all('td')
row = [str(i.text) for i in td]
if len(row) != 2:
continue
company_data[row[0]] = row[1]
all_data[str(company_name)] = company_data
#I want to save data here, but saving now instead of later messed up json formatting
#save_data_to_json(all_data, json_file_name)
执行此操作时,我必须读取每个链接中的所有数据并将其转储到此数据字典中。有没有办法将每个页面的每个数据集写入一个json格式的文件,一次设置一个字典以节省内存?由于额外的花括号,尝试使json格式全部搞砸了。我只想一起输出一个json文件。
答案 0 :(得分:0)
考虑使用jsonlines 它是json的变体,更适合于"流媒体"读或写。 基本上,每一行都应该是一个有效的json文档。
基本的python json库通常就足够了(你读了一行文本,解析了这个特定的行),或者你可以使用帮助库,例如:https://jsonlines.readthedocs.io/en/latest/
答案 1 :(得分:0)
我同意Barmar,当您将JSON内容放入文件时,您必须做出明确的安排。比如传递一些特殊的文本识别,你可以从中找到你的JSON结束的地方
答案 2 :(得分:0)
首先,如果你想保存一些内存而不是使用批量 - 限制每个批量包含的实体数量,当它达到这个限制时,将它保存到Json(我将展示示例)。
接下来,您可以将多个词典保存到单个Json中,只需为每个词典转到不同的行。
def gather_data(page_url, soup, all_data, file_path):
#return if this page doesn't contain data
max_per_bulk_ = 10000
if (soup.find('h4') == None) or (soup.find('span') == None):
return
company_name = soup.h4.span.text
table_body = soup.tbody
table_rows = table_body.find_all('tr')
company_data = {}
f = open(file_path, 'a')
bulk_ = []
for tr in table_rows:
td = tr.find_all('td')
row = [str(i.text) for i in td]
if len(row) != 2:
continue
company_data[row[0]] = row[1]
all_data[str(company_name)] = company_data
if len(bulk_) > max_per_bulk_:
with open(file_path, 'a') as f:
for entity in bulk_:
j = json.dump(entity)
f.write(j)
f.write('\n')
bulk_ = []
if bulk_:
with open(file_path, 'a') as f:
for entity in bulk_:
j = json.dump(entity)
f.write(j)
f.write('\n')