I am trying to dump the data from an array into the csv file but it gives the following error: AttributeError: 'NavigableString' object has no attribute 'keys' in python. The array has the data when I try to print it, but while trying to create a csv file it throws error.
This is the code I wrote:
import requests
import csv
from bs4 import BeautifulSoup as bs
global newsitems
def loadRSS():
url="https://rss.nytimes.com/services/xml/rss/nyt/Africa.xml"
resp=requests.get(url)
with open('topnewsfeed.xml','wb') as f:
f.write(resp.content)
def extractData():
infile = open("topnewsfeed.xml","r",encoding='utf-8')
contents = infile.read()
soup = bs(contents,'xml')
guids= soup.find_all('guid')
titles = soup.find_all('title')
pubDates= soup.find_all('pubDate')
descs= soup.find_all('description')
links= soup.find_all('link')
newsitems=[]
for (guid,title,pubDate,desc,link) in zip(guids,titles,pubDates,descs,links):
newsitems.append(guid.string)
newsitems.append(title.string)
newsitems.append(pubDate.string)
newsitems.append(desc.string)
newsitems.append(link.string)
return newsitems
def savetoCSV(array,filename):
fields=['Guid','Title','PubDate','Description','Link']
with open(filename,'w') as csvfile:
writer=csv.DictWriter(csvfile,fieldnames=fields)
writer.writeheader()
writer.writerows(array)
def run():
loadRSS()
newsitems=extractData()
savetoCSV(newsitems,'topnews.csv')
run()
CodePudding user response:
writerows of DictWriter expects a sequence of dicts (with fieldnames as keys mapping to values), not a sequence of NavigableString objects, which is what newsitems is.
Instead of making a sequence of navigable strings:
for (guid,title,pubDate,desc,link) in zip(guids,titles,pubDates,descs,links):
newsitems.append(guid.string)
newsitems.append(title.string)
newsitems.append(pubDate.string)
newsitems.append(desc.string)
newsitems.append(link.string)
Make a list of dictionaries, as is expected by writerows
. The keys in the dict should match your CSV field ('Guid','Title','PubDate','Description','Link'
)
for (guid,title,pubDate,desc,link) in zip(guids,titles,pubDates,descs,links):
newsitems.append({
'Guid': guid.string,
'Title': title.string,
'PubDate': pubDate.string,
'Description': desc.string,
'Link': link.string
}
)