优化Python脚本以解析xml

时间:2015-07-29 09:04:31

标签: python mysql xml optimization beautifulsoup

我正在使用Python和Beautifulsoup解析美国专利XML文件(从Google patent dumps下载);解析后的数据将导出到MYSQL数据库。

每年的数据包含近200-300K专利 - 这意味着解析200-300K xml文件。

我正在运行python脚本的服务器功能非常强大--16个内核,160个内存等等,但仍需要将近3天的时间来解析一年的数据。 enter image description here enter image description here

我从2年开始学习和使用python - 所以我可以完成任务但不知道如何以最有效的方式完成它。我正在读它。

如何优化以下脚本以提高效率?

非常感谢任何指导。

以下是代码:

from bs4 import BeautifulSoup
import pandas as pd
from pandas.core.frame import DataFrame
import MySQLdb as db
import os

cnxn = db.connect('xx.xx.xx.xx','xxxxx','xxxxx','xxxx',charset='utf8',use_unicode=True)

def separated_xml(infile):
    file = open(infile, "r")
    buffer = [file.readline()]
    for line in file:
        if line.startswith("<?xml "):
            yield "".join(buffer)
            buffer = []
        buffer.append(line)
    yield "".join(buffer)
    file.close()

def get_data(soup):
    df = pd.DataFrame(columns = ['doc_id','patcit_num','patcit_document_id_country', 'patcit_document_id_doc_number','patcit_document_id_kind','patcit_document_id_name','patcit_document_id_date','category'])
    if soup.findAll('us-citation'):
        cit = soup.findAll('us-citation')
    else:
        cit = soup.findAll('citation')
    doc_id = soup.findAll('publication-reference')[0].find('doc-number').text
    for x in cit:
        try:
            patcit_num = x.find('patcit')['num']
        except:
            patcit_num = None
        try:
            patcit_document_id_country = x.find('country').text
        except:
            patcit_document_id_country = None   
        try:     
            patcit_document_id_doc_number = x.find('doc-number').text
        except: 
            patcit_document_id_doc_number = None
        try:
            patcit_document_id_kind = x.find('kind').text
        except:
            patcit_document_id_kind = None
        try:
            patcit_document_id_name = x.find('name').text
        except:
            patcit_document_id_name = None
        try: 
            patcit_document_id_date = x.find('date').text
        except:
            patcit_document_id_date = None
        try:
            category = x.find('category').text
        except:
            category = None
        print doc_id
        val = {'doc_id':doc_id,'patcit_num':patcit_num, 'patcit_document_id_country':patcit_document_id_country,'patcit_document_id_doc_number':patcit_document_id_doc_number, 'patcit_document_id_kind':patcit_document_id_kind,'patcit_document_id_name':patcit_document_id_name,'patcit_document_id_date':patcit_document_id_date,'category':category}    
        df = df.append(val, ignore_index=True)
    df.to_sql(name = 'table_name', con = cnxn, flavor='mysql', if_exists='append')
    print '1 doc exported'

i=0

l = os.listdir('/path/')
for item in l:
    f = '/path/'+item
    print 'Currently parsing - ',item
    for xml_string in separated_xml(f):
        soup = BeautifulSoup(xml_string,'xml')
        if soup.find('us-patent-grant'):
            print item, i, xml_string[177:204]          
            get_data(soup)
        else:
            print item, i, xml_string[177:204],'***********************************soup not found********************************************'
        i+=1
print 'DONE!!!'

1 个答案:

答案 0 :(得分:2)

这是一个tutorial on multi-threading,因为目前该代码将在1个线程上运行,1个核心。

删除所有try / except语句并正确处理代码。例外是昂贵的。

运行profiler以查找阻塞点,并对这些阻塞点进行多线程处理或找到更少次数的方法。