2014-11-24 75 views
1

我只需进入编码和Python编码。目前我正在研究webcrawler。 我需要将我的数据保存到JSON文件,以便将其导出到MongoDB中。需要帮助将数据导出到JSON文件

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. 
+1

您可能想要阅读关于循环再次和列表的Python教程。不要使用'listobject.insert(len(listobject),...)',例如使用'listobject.append(..)',为什么不把所有的信息添加到**一个**列表中(作为字典,例如),然后只是循环超过一个列表?你可以在'listobject:'中使用'item并且不需要索引。 – 2014-11-24 10:31:55

+0

你真的*不想使用'try ... except'而没有特殊的例外;不要掩盖你的错误。 – 2014-11-24 10:32:51

回答

2

创建词典,首先,在一个列表,然后保存一个清单一个JSON文件,你可以一个有效的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对象,邻每行NE,写之间,你至少可以再次找到这些对象换行符(解析将是另有一个兽):

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())来删除内部换行符和压缩空白,但是这个特定的网页似乎并不需要这种措施。
+0

感谢您的帮助!我的输出中有一些unicode字符集。像这样:\ u20ac。有没有办法删除/替换? – henktenk 2014-11-24 11:37:23

+0

@henkownz:你所有的输出都是Unicode的;你的意思是你有非ASCII字符。 :-)你有[U + 20AC EURO SIGN](http://codepoints.net/U+20ac),正确地转义为JSON数据,你确定要摆脱那些?你总是可以使用显式替换('str.replace()')来移除它们,或者使用'str.translate()'去除多个字符。或者,您可以使用['unidecode'](https://pypi.python.org/pypi/Unidecode)将任何非ASCII码替换为最接近的ASCII码。 – 2014-11-24 11:57:35