Python - 网页抓取;字典数据结构
Python - webscraping; dictionary data structure
我需要抓取该网站 (http://setkab.go.id/profil-kabinet/#) 并生成一个 Excel 文件,其中第 1 列为 headers "Cabinet names",第 1 列为 "Era" 2. 这意味着每个内阁名称(例如 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"]])
但是,这将创建一个 Excel 文件,其中第 1 列和第 2 列分别包含 headers "Era" 和 "Cabinet names"。它无法将每个内阁名称放在 separate 行中。例如,它在第 1 列中有 'Era Revolusi Fisik',并在第 2 列中列出 所有 个机柜一起。
我的猜测是我需要以某种方式切换 key-value 对,以便每个 Cabinet 成为一个键并且它的时代成为它的价值 - 因为目前它是相反的。但我已经尝试过但没有成功。有什么帮助吗?谢谢!
据我所知,您用于写入的 cabinets[a]["cbnm"]
变量只是一个很长的 Unicode
所以当您执行 writer.writerow([a.encode("utf-8"), cabinets[a]["cbnm"]])
时,实际发生的是您将纪元写入第一列和下一列单个单元格中的整个 Unicode(即使你的字符串中有 \n
它也不会阻止它被写入单个单元格(csv
实际上认为你希望 unicode 仅在一个单元格中,因此它在 cabinets[a]["cbnm"]
值前后放置 "
以确保它实际上在一个单元格中)),您应该如何将每个柜子值写入另一行是对每个所需的行分别使用 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 行。
希望对您有所帮助!
我需要抓取该网站 (http://setkab.go.id/profil-kabinet/#) 并生成一个 Excel 文件,其中第 1 列为 headers "Cabinet names",第 1 列为 "Era" 2. 这意味着每个内阁名称(例如 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"]])
但是,这将创建一个 Excel 文件,其中第 1 列和第 2 列分别包含 headers "Era" 和 "Cabinet names"。它无法将每个内阁名称放在 separate 行中。例如,它在第 1 列中有 'Era Revolusi Fisik',并在第 2 列中列出 所有 个机柜一起。
我的猜测是我需要以某种方式切换 key-value 对,以便每个 Cabinet 成为一个键并且它的时代成为它的价值 - 因为目前它是相反的。但我已经尝试过但没有成功。有什么帮助吗?谢谢!
据我所知,您用于写入的 cabinets[a]["cbnm"]
变量只是一个很长的 Unicode
所以当您执行 writer.writerow([a.encode("utf-8"), cabinets[a]["cbnm"]])
时,实际发生的是您将纪元写入第一列和下一列单个单元格中的整个 Unicode(即使你的字符串中有 \n
它也不会阻止它被写入单个单元格(csv
实际上认为你希望 unicode 仅在一个单元格中,因此它在 cabinets[a]["cbnm"]
值前后放置 "
以确保它实际上在一个单元格中)),您应该如何将每个柜子值写入另一行是对每个所需的行分别使用 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 行。
希望对您有所帮助!