在使用beautifulsoup4(根据需要安装了lxml)以xml(word/document.xml)的形式解析.docx文件内容时,我遇到了一个问题.这部分来自xml:
...
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
...
Run Code Online (Sandbox Code Playgroud)
成为这个:
...
<graphic>
<graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic>
...
Run Code Online (Sandbox Code Playgroud)
即使我只是解析文件并保存它,没有任何修改.像这样:
from bs4 import BeautifulSoup
soup = BeautifulSoup(open(filepath_in), 'xml')
with open(filepath_out, "w+") as fd:
fd.write(str(soup))
Run Code Online (Sandbox Code Playgroud)
或者从python控制台解析xml.
对我来说,它看起来像这样声明的命名空间,不在根文档节点中,被解析器吃掉.
这是一个错误或功能吗?有没有办法在使用beautifulesoup4解析时保留这些?或者我需要切换到其他东西吗?
更新1:如果使用一些正则表达式和文本替换,我将这些命名空间声明添加到document根节点,然后beautifulsoup解析它就好了.但是我仍然感兴趣,如果在解析之前可以在不修改xml的情况下解决这个问题.
更新2:在使用beutifulsoup之后,我发现只在第一次出现时才解析名称空间声明.意味着如果tag声明了namespace,那么如果它的子节点具有名称空间声明,则不会对它们进行解析.下面是带有输出的代码示例来说明这一点.
来自bs4进口BeautifulSoup
xmls = []
xmls.append("""<name1:tag xmlns:name1="namespace1" xmlns:name2="namespace2">
<name2:intag>
text
</name2:intag>
</name1:tag>
""")
xmls.append("""<tag>
<name2:intag xmlns:name2="namespace2">
text
</name2:intag>
</tag>
""")
xmls.append("""<name1:tag xmlns:name1="namespace1">
<name2:intag xmlns:name2="namespace2">
text
</name2:intag>
</name1:tag>
""")
for i, xml in enumerate(xmls):
print "============== xml {} ==============".format(i)
soup = BeautifulSoup(xml, …Run Code Online (Sandbox Code Playgroud) 我正在通过sqlalchemy在postgresql数据库上工作.我需要使用postgresql"date"列类型处理BC日期(它支持BC日期http://www.postgresql.org/docs/9.2/static/datatype-datetime.html).但是虽然我可以以字符串的形式插入BC日期(例如'2000-01-01 BC'),但我无法检索它们.试图从数据库中获取BC日期引发值错误:年份超出范围.起初我认为原因是它的类型Date中的sqlalchemy使用python datetime.date模块,它不支持BC日期,但我不完全确定.我试图找到一种方法将数据库中的"日期"类型映射到自定义python类(绕过datetime.date模块的使用)但我还没有成功(我找到了在sqlalchemy中为各种处理步骤添加逻辑的方法,像result_processor或bind_expression与column_expression,但我没有设法让它工作).
这是重现问题的例子.
from sqlalchemy import create_engine, Column, Integer, String, Date
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('postgresql://database:database@localhost:5432/sqlalchemy_test', echo=True)
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
date = Column(Date)
def __repr__(self):
return "<User(name='%s', date='%s')>" % (self.name, self.date)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# remove objects from previous launches
session.query(User).delete()
import datetime
a_date = datetime.date.today()
# Insert valid date in datetime.date format, it works. …Run Code Online (Sandbox Code Playgroud)