我使用beautifulstonesoup和python从Google解析XML提要,效果很好。我也在创建一个csv并将其上传到Google Docs,这也很好。问题是当我遇到xml中的空文本属性时,解析器就会停止。现在不是问题,因为所有属性都有数据,但是第一次没有,它会破坏。
代码:
import atom
import gdata.auth
import gdata.contacts
import gdata.contacts.client
import gdata.docs.service
import gdata.docs.data
from BeautifulSoup import BeautifulStoneSoup as Soup
import csv
email = 'admin@domain.com'
password = 'password'
domain = 'domain.com'
ms_client = gdata.docs.service.DocsService()
gd_client = gdata.contacts.client.ContactsClient(domain=domain)
gd_client.ClientLogin(email, password, 'profileFeedAPI')
ms_client.ClientLogin(email, password, 'peopleCSVupload')
profiles_feed = gd_client.GetProfilesFeed('https://www.google.com/m8/feeds/profiles/domain/domain.com/full?max-results=300')
soup = Soup(str(profiles_feed), selfClosingTags=['ns0:category','ns3:status', 'ns0:link','ns1:email'])
a = soup.findAll('ns0:entry')
f = open('C:\\people.csv', 'wb')
writer = csv.writer(f, quoting=csv.QUOTE_NONE, escapechar =' ')
for entry in a:
writer.writerow([entry.find('ns1:familyname').text + ',' + entry.find('ns1:givenname').text + ',' + entry.find('ns1:fullname').text + ',' + entry.find('ns1:orgtitle').text + ',' + entry.find('ns1:orgdepartment').text + ',' + entry.find('ns1:orgname').text + ',' + entry.find('ns1:email',primary=True)['address']])
f.close()
ms = gdata.data.MediaSource(file_path="C:\\people.csv", content_type=gdata.docs.service.SUPPORTED_FILETYPES['CSV'])
csv_entry = ms_client.Upload(ms, "People File")
我知道我可以这样做:
for entry in a:
if entry.find('ns1:orgtitle') != None:
print entry.find('ns1:orgtitle').text
elif entry.find('ns1:orgtitle') == None:
print('')
if entry.find('ns1:familyname') != None:
print entry.find('ns1:familyname').text
elif entry.find('ns1:familyname') == None:
print('')
etc...
但它很长,我不知道如何将数据集中在一行上。任何帮助,非常感谢。
答案 0 :(得分:6)
你可以像这样包装这个:
def findnonempty(entry, arg):
result = entry.find(arg):
if result:
return result.text
else:
return ""
你可以一个接一个地进行7次调用,也可以使用map(),比如
tags = ['ns1:familyname', 'ns1:givenname', ... ] # your tags
s = map(lambda tag: findnonempty(entry, tag), tags)
"".join(s)
答案 1 :(得分:1)
起初我不明白为什么你认为它会破坏...你没有“冒犯”的数据片段。 BeautifulSoup很乐意返回一个空字符串。
在你的“必须滚动到那里看到它”行的结尾处,你终于明白你(正如你在你的介绍中所说的那样)寻找一个属性。
entry.find('ns1:email',primary=True)['address']
空属性不会像空文本节点一样无声地返回(例如entry.find('ns1:familyname').text
)。
永远不要害怕,只需用['address']
替换.get('address','')
符号,如果为空则返回空字符串而不是抛出KeyError
答案 2 :(得分:0)
将值获取和打印封装到函数中很容易。
def find(entry, spec, default=None):
value = entry.find(spec)
return default if value is None else value.text
def findandprint(entry, spec, default=None, newline=True):
value = find(entry, spec, default)
if value is not None: # if we still don't have a value even after
print value, # considering default, don't print anything
if newline:
print
然后你可以:
for entry in a:
findandprint(entry, 'ns1:orgtitle', default="")
findandprint(entry, 'ns1:familyname', default="")
如果你有很多属性,并且想要处理它们,那么也要迭代它们:
for entry in a:
for attribute in ('ns1:orgtitle', 'ns1:familyname', ...):
findandprint(entry, attribute, default="")