Python - webscraping;字典数据结构

时间:2016-07-12 10:22:49

标签: python-2.7 dictionary web-scraping beautifulsoup key-value

我需要抓取这个网站(http://setkab.go.id/profil-kabinet/#)并生成一个Excel文件,其第1列包含“Cabinet names”标题,第2列包含“Era”标题。这意味着每个文件柜名称(例如Kabinet Presidensil,Kabinet) Sjahrir I)应该拥有自己的行 - 以及它各自的时代(例如Era Revolusi Fisik,Era Republik Indonesia Serikat)。

这是我最接近的:

import requests
from bs4 import BeautifulSoup

response = requests.get('http://setkab.go.id/profil-kabinet/#')
soup = BeautifulSoup(response.text, 'html.parser')

eras = soup.find_all('div', attrs={'class':"wpb_accordion_section group"})

setkab = {}
for element in eras: 
    setkab[element.a.get_text()] = {}

for element in eras:
    cabname = element.find('div',attrs={'class':'wpb_wrapper'}).get_text()
    setkab[element.a.get_text()]['cbnm'] = cabname

for item in setkab.keys():
    print item + setkab[item]['cbnm']

import os, csv
os.chdir("/Users/mxcodes/Code")

with open("setkabfinal.csv", "w") as toWrite:
    writer = csv.writer(toWrite, delimiter=",")
    writer.writerow(["Era", "Cabinet name"])
    for a in setkab.keys():
        writer.writerow([a.encode("utf-8"), setkab[a]["cbnm"]])

但是,这会分别在第1列和第2列中创建一个带有标题“Era”和“Cabinet names”的Excel文件。它无法将每个Cabinet名称放在单独的行中。例如,它在第1列中有“Era Revolusi Fisik”,并在第2列中列出所有一起一起

我的猜测是,我需要以某种方式切换键值对,以便每个内阁成为一个键,它的时代成为它的价值 - 因为目前它是另一种方式。但我尝试过但未能这样做。有帮助吗?谢谢!

1 个答案:

答案 0 :(得分:0)

从我所看到的情况来看,用于写作的cabinets[a]["cbnm"]变量只是一个很长的Unicode所以当你writer.writerow([a.encode("utf-8"), cabinets[a]["cbnm"]])时,实际发生的事情就是你在第一时间写下这个时代列和下一列中单个单元格中的整个Unicode(即使您的字符串中有\n,它也不会阻止它在单个单元格中被写入(csv实际上认为您需要unicode只在一个单元格中,所以它在"值之前和之后放置cabinets[a]["cbnm"]以确保它实际上在一个单元格中)),你应该怎么做才能在另一行写入每个cabinet值是为每个所需的行分别使用writerow方法。 例如,这段代码对我来说很好:

cabinets = setkab 
with open("cabinets.csv", "w") as toWrite:
    writer = csv.writer(toWrite, delimiter=",")
    writer.writerow(["Era", "Cabinet name"])
    for a in setkab.keys():
        writer.writerow([a.encode("utf-8")])  #write the era column
        cabinets_list = [i for i in cabinets[a]["cbnm"].split('\n') if i != '']  #get all the values that are separated by newline chars (if they aren't empty strings)
        for i in cabinets_list: writer.writerow([a.encode("utf-8"),i])   #write every value separately in the CABINET NAME row

你可以看到我只改变了最后3行。

我希望这会对你有所帮助!