【问题标题】:Need help exporting data to JSON file需要帮助将数据导出到 JSON 文件
【发布时间】:2015-01-22 00:45:30
【问题描述】:

我只是在 Python 中进行编码和编码。目前我正在开发一个网络爬虫。 我需要将数据保存到 JSON 文件中,以便将其导出到 MongoDB。

import requests
import json
from bs4 import BeautifulSoup 

url= ["http://www.alternate.nl/html/product/listing.html?filter_5=&filter_4=&filter_3=&filter_2=&filter_1=&size=500&lk=9435&tk=7&navId=11626#listingResult"] 

amd = requests.get(url[0])
soupamd = BeautifulSoup(amd.content) 

prodname = [] 
adinfo = [] 
formfactor = []
socket = [] 
grafisch = []
prijs = []

a_data = soupamd.find_all("div", {"class": "listRow"}) 
for item in a_data: 
    try:
        prodname.insert(len(prodname),item.find_all("span", {"class": "name"})[0].text)
        adinfo.insert(len(adinfo), item.find_all("span", {"class": "additional"})[0].text)
        formfactor.insert(len(formfactor), item.find_all("span", {"class": "info"})[0].text)
        grafisch.insert(len(grafisch), item.find_all("span", {"class": "info"})[1].text)
        socket.insert(len(socket), item.find_all("span", {"class": "info"})[2].text)
        prijs.insert(len(prijs), item.find_all("span", {"class": "price right right10"})[0].text)
    except: 
        pass

我被困在这部分。我想将保存在数组中的数据导出到 JSON 文件。这就是我现在拥有的:

file = open("mobos.json", "w")

for  i = 0:  
    try: 
        output = {"productnaam": [prodname[i]],
        "info" : [adinfo[i]], 
        "formfactor" : [formfactor[i]],
        "grafisch" : [grafisch[i]],
        "socket" : [socket[i]], 
        "prijs" : [prijs[i]]} 
        i + 1
        json.dump(output, file)
        if i == 500: 
            break
    except: 
        pass 

file.close()

所以我想创建一个这样的字典格式:

{"productname" : [prodname[0]], "info" : [adinfo[0]], "formfactor" : [formfactor[0]] .......}
{"productname" : [prodname[1]], "info" : [adinfo[1]], "formfactor" : [formfactor[1]] .......}
{"productname" : [prodname[2]], "info" : [adinfo[2]], "formfactor" : [formfactor[2]] .......} etc.

【问题讨论】:

  • 您可能想再次阅读有关循环和列表的 Python 教程。不要使用listobject.insert(len(listobject), ...),例如使用listobject.append(..),为什么不将所有信息添加到一个列表(例如字典),然后只循环一个列表?可以使用for item in listobject:,不需要索引。
  • 而你真的不想在没有特定例外的情况下使用try...except;不要那样掩盖你的错误。

标签: python json mongodb beautifulsoup web-crawler


【解决方案1】:

首先在 one 列表中创建字典,然后将该列表保存到 JSON 文件中,这样您就有 one 有效的 JSON 对象:

soupamd = BeautifulSoup(amd.content) 
products = []

for item in soupamd.select("div.listRow"):
    prodname = item.find("span", class_="name")
    adinfo = item.find("span", class_="additional")
    formfactor, grafisch, socket = item.find_all("span", class_="info")[:3]
    prijs = item.find("span", class_="price")
    products.append({
        'prodname': prodname.text.strip(),
        'adinfo': adinfo.text.strip(),
        'formfactor': formfactor.text.strip(),
        'grafisch': grafisch.text.strip(),
        'socket': socket.text.strip(),
        'prijs': prijs.text.strip(),
    })

with open("mobos.json", "w") as outfile:
    json.dump(products, outfile)

如果你真的想生成单独的 JSON 对象,每行一个,在中间写下换行符,这样你至少可以再次找到这些对象(否则解析将是一个野兽):

with open("mobos.json", "w") as outfile:
    for product in products:
        json.dump(products, outfile)
        outfile.write('\n')

因为我们现在有 一个 对象列表,所以使用 for 循环遍历该列表要简单得多。

与您的代码的其他一些差异:

  • 使用list.append() 而不是list.insert();当任务有标准方法时,就不需要这种冗长的代码。
  • 如果您只寻找一个匹配项,请使用element.find() 而不是element.find_all()
  • 你真的想避免使用blanket exception handling;你会掩盖比你想要的更多的东西。仅捕获特定异常。
  • 我使用str.strip() 删除了通常在HTML 文档中添加的额外空格;您还可以添加一个额外的 ' '.join(textvalue.split()) 来删除内部换行符并折叠空格,但这个特定网页似乎不需要这种措施。

【讨论】:

  • 感谢您的帮助!我的输出中有一些 unicode 字符集。像这个:\u20ac。有没有办法删除/替换它?
  • @henkownz:你所有的输出都是 Unicode;你的意思是你有非ASCII字符。 :-) 你有U+20AC EURO SIGN,正确地转义为 JSON 数据,你确定要摆脱这些吗?您始终可以使用显式替换 (str.replace()) 删除这些字符,或使用 str.translate() 删除多个字符。或者您可以使用 unidecode 将任何非 ASCII 内容替换为最接近的 ASCII 等价物。
【解决方案2】:

由于 OP 想要一个带有类字典对象的 JSON,并且没有指定它们应该在 JSON 中的列表中,因此此代码可能会更好:

outFile = open("mobos.json", mode='wt')
for item in soupamd.select("div.listRow"):
    prodname = item.find("span", class_="name")
    adinfo = item.find("span", class_="additional")
    formfactor, grafisch, socket = item.find_all("span", class_="info")[:3]
    prijs = item.find("span", class_="price")
    tempDict = {
        'prodname': prodname.text.strip(),
        'adinfo': adinfo.text.strip(),
        'formfactor': formfactor.text.strip(),
        'grafisch': grafisch.text.strip(),
        'socket': socket.text.strip(),
        'prijs': prijs.text.strip(),
    }
    json.dump(tempDict, outFile)
outFile.close()

无需编写新行,因为json.dump 会自动处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多