将数据从xml文件检索到mysql数据库

时间:2018-05-03 11:29:20

标签: python xml-parsing mysql-python elementtree

我必须从xml文件中检索数据,并且必须进入数据库。运行我的python文件时没有错误,但数据没有进入数据库。我无法找到我出错的地方。如果有人能帮助我,将会非常有帮助。

这是我的python代码,

from xml.etree import ElementTree
import mysql.connector

dom = ElementTree.parse('profile.xml')

ticker = dom.findall('TICKER')
name = dom.findall('NAME')
address = dom.findall('ADDRESS')
phone = dom.findall('PHONE')
website = dom.findall('WEBSITE')
sector = dom.findall('SECTOR')
industry = dom.findall('INDUSTRY')
full_time = dom.findall('FULL_TIME')
bus_summ = dom.findall('BUS_SUMM')

ticker_list = [t.text for t in ticker]
name_list = [t.text for t in name]
add_list = [t.text for t in address]
phn_list = [t.text for t in phone]
site_list = [t.text for t in website]
sec_list = [t.text for t in sector]
ind_list = [t.text for t in industry]
emp_list = [t.text for t in full_time]
sum_list = [t.text for t in bus_summ]

db = mysql.connector.Connect(host = 'localhost', user = 'root', password ='root' , database = 'nldb_project')
cur = db.cursor()
query = "INSERT INTO profiles(`prof_ticker`,`name`,`address`,`phonenum`,`website`,`sector`,`industry`,full_time`,`bus_summ`) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)"

sqltuples = [(t,n,a,p,s,sec,i,e,su) for t,n,a,p,s,sec,i,e,su in zip(ticker_list,name_list,add_list,phn_list,site_list,sec_list,ind_list,emp_list,sum_list)]
cur.executemany(query,sqltuples)

我正在使用python 3.6.5版本。

这是我的xml代码,

<?xml version="1.0"?>
<collection shelf = 'profile'>
<INFO>
    <TICKER>AAPL</TICKER>
    <NAME> Apple Inc.</NAME>
    <ADDRESS>1 Infinite Loop;Cupertino, CA 95014;United State</ADDRESS>
    <PHONE>408-996-1010</PHONE>
    <WEBSITE>http://www.apple.com</WEBSITE>
    <SECTOR>Technology</SECTOR>
    <INDUSTRY>Consumer Electronics</INDUSTRY>
    <FULL_TIME>100,000</FULL_TIME>
    <BUS_SUMM>Apple</BUS_SUMM>
    <SOURCE>https://finance.yahoo.com/quote/AAPL/profile?p=AAPL</SOURCE> 
</INFO>
<INFO>
    <TICKER>T</TICKER>
    <NAME> AT and T Inc.</NAME>
    <ADDRESS>208 South Akard Street;Dallas, TX 75202;United States</ADDRESS>
    <PHONE>210-821-4105</PHONE>
    <WEBSITE>http://www.att.com</WEBSITE>
    <SECTOR>Communication Services</SECTOR>
    <INDUSTRY> Telecom Services</INDUSTRY>
    <FULL_TIME>254,000</FULL_TIME>
    <BUS_SUMM>at and t</BUS_SUMM>
    <SOURCE>https://finance.yahoo.com/quote/T/profile?p=T</SOURCE>
</INFO>
<INFO>
    <TICKER>IBM</TICKER>
    <NAME>International Business Machines Corporation</NAME>
    <ADDRESS>1 New Orchard Road;Armonk, NY 10504;United States</ADDRESS>
    <PHONE>914-499-1900</PHONE>
    <WEBSITE>http://www.ibm.com</WEBSITE>
    <SECTOR>Technology</SECTOR>
    <INDUSTRY> Information Technology Services</INDUSTRY>
    <FULL_TIME>366,600</FULL_TIME>
    <BUS_SUMM>ibm</BUS_SUMM>
    <SOURCE>https://finance.yahoo.com/quote/IBM/profile?p=IBM</SOURCE>
</INFO>
<INFO>
    <TICKER>TWTR</TICKER>
    <NAME>Twitter,Inc.</NAME>
    <ADDRESS>1355 Market Street;Suite 900;San Francisco, CA 94103;United States</ADDRESS>
    <PHONE>415-222-9670</PHONE>
    <WEBSITE>http://www.twitter.com</WEBSITE>
    <SECTOR>Technology</SECTOR>
    <INDUSTRY>Internet Content Information</INDUSTRY>
    <FULL_TIME>3,372</FULL_TIME>
    <BUS_SUMM>twitter</BUS_SUMM>
    <SOURCE>https://finance.yahoo.com/quote/TWTR/profile?p=TWTR</SOURCE>
</INFO>
<INFO>
    <TICKER>TSLA</TICKER>
    <NAME>Tesla,Inc.</NAME>
    <ADDRESS>3500 Deer Creek Road;Palo Alto, CA 94304;United States</ADDRESS>
    <PHONE>650-681-5000</PHONE>
    <WEBSITE>http://www.tesla.com</WEBSITE>
    <SECTOR>Consumer Cyclical</SECTOR>
    <INDUSTRY>Auto Manufacturers</INDUSTRY>
    <FULL_TIME>37,543</FULL_TIME>
    <BUS_SUMM>tesla</BUS_SUMM>
    <SOURCE>https://finance.yahoo.com/quote/TSLA/profile?p=TSLA</SOURCE>
</INFO>
<INFO>
    <TICKER>PYPL</TICKER>
    <NAME>PayPal Holdings, Inc.</NAME>
    <ADDRESS>2211 North First Street;San Jose, CA 95131;United States</ADDRESS>
    <PHONE>408-967-1000</PHONE>
    <WEBSITE>http://www.paypal.com</WEBSITE>
    <SECTOR>Financial Services</SECTOR>
    <INDUSTRY>Credit Services</INDUSTRY>
    <FULL_TIME>18,700</FULL_TIME>
    <BUS_SUMM>paypal</BUS_SUMM>
    <SOURCE>https://finance.yahoo.com/quote/PYPL/profile?p=PYPL</SOURCE>
</INFO>
</collection>

2 个答案:

答案 0 :(得分:1)

您的问题背后的原因

你有18个列表都是空的,这就是你在插入后没有看到对数据库有任何影响的原因。

  

我无法找到我出错的地方。

您的问题源于对如何使用findall()的误解:

  

Element.findall()仅查找标记为直接的元素   当前元素的孩子。

所以让我以ticker为例:

ticker = dom.findall('TICKER')

什么是dom?它只是指向XML树的根元素,collection,在您的情况下:

>>> dom
<Element 'collection' at 0x7f5e24a42e10>

现在问问自己:哪些是收集的直接元素?您会看到有6个INFO直接子元素,绝对没有TICKER元素。

>>> infos = dom.findall('INFO')
>>> len(infos)
6

因此,当您运行ticker = dom.findall('TICKER')时,您只是在寻找名为TICKER的集合的直接子项,并且由于没有人,您的列表ticker为空。

>>> ticker = dom.findall('TICKER')
>>> ticker
[]

所以稍后在你的代码中,当你运行它时:ticker_list = [t.text for t in ticker]你只是循环一个空列表,你什么都没有,我的意思是:

>>> ticker_list = [t.text for t in tickers]
>>> ticker_list
[]

现在将此推理应用于剩下的8个第一个列表,并在代码的第二部分中显示相应的8个列表。

如何解决问题?

如何解决您的问题呢?好吧,如果您理解我上面解释的内容,那么您已经解决了一半问题。让我们这样做:

将XML文件加载到dom后,初始化您需要的9个空列表:

>>> ticker_list = []
>>> name_list = []
>>> add_list = []
>>> phn_list = []
>>> site_list = []
>>> sec_list = []
>>> ind_list = []
>>> emp_list = []
>>> sum_list = []

然后在考虑其层次结构以及findall()的工作原理后循环遍历数据。例如,让我们关注ticker_list

>>> dom
<Element 'collection' at 0x7f5e24a42e10>
>>> infos = dom.findall('INFO')
>>> for info in infos:
...     tickers = info.findall('TICKER')
...     for ticker in tickers:
...             ticker_list.append(ticker.text)
... 
>>> ticker_list
['AAPL', 'T', 'IBM', 'TWTR', 'TSLA', 'PYPL']

现在对您要查找的其余8个列表执行相同的逻辑:

>>> infos = dom.findall('INFO')
>>> for info in infos:
...     tickers = info.findall('TICKER')
...     for ticker in tickers:
...             ticker_list.append(ticker.text)
...     names = info.findall('NAME')
...     for name in names:
...             name_list.append(name.text)
...     adds = info.findall('ADDRESS')
...     for add in adds:
...             add_list.append(add.text)
...     phns = info.findall('PHONE')
...     for phn in phns:
...             phn_list.append(phn.text)
...     sites = info.findall('WEBSITE')
...     for site in sites:
...             site_list.append(site.text)
...     secs = info.findall('SECTOR')
...     for sec in secs:
...             sec_list.append(sec.text)
...     inds = info.findall('INDUSTRY')
...     for ind in inds:
...             ind_list.append(ind.text)
...     emps = info.findall('FULL_TIME')
...     for emp in emps:
...             emp_list.append(emp.text)
...     sums = info.findall('BUS_SUMM')
...     for sum in sums:
...             sum_list.append(sum.text)

现在您的列表中包含数据,您的插入应该可以成功运行。

额外注意事项:

当然,iter会比使用findall()

更简化代码

答案 1 :(得分:0)

默认情况下,连接到数据库会开始一个新事务。如果禁用自动提交(通常默认情况下),则应提交确认所做的任何更改,或者回滚以丢弃它们。

只需添加

db.commit()

代码和代码提交更改。

可能还有其他错误,如果您提供profile.xml进行测试会更好。至少,查询中缺少其中一个字段的引用。