使用请求和 ElementTree 解析 XML
Parsing XML with requests and ElementTree
我正在尝试从科学数据库中检索数据。我有一个使用 urllib 和 ElementTree 的工作脚本,但我想使用更新的模块,所以我尝试用请求重写它。
不幸的是,由于 unicode 的 TypeError,ElementTree 不想再解析 XML。所以我尝试了 BeautifulSoup ,这在某种程度上有效,但在访问嵌套标签时遇到了问题。回到 ElementTree——它也是内置的。
对于以下代码,我得到 "TypeError: coercing to Unicode: need string or buffer, Response found"。如果我将“.text”或“.content”添加到带有 et.parsing 的行,则不会发生错误,而是打印而不是解析整个站点内容。
for entry in input_list:
xml = requests.Session().get(url.xml)
if xml.status_code == 200:
try:
tree = et.parse(xml)
root = getroot.tree()
for record in root.iter(base + 'placeholder').text:
var1 = record
break
print(var1)
except TypeError:
print('error on parsing')
else:
xml.raise_for_status()
编辑:
输出应如下所示:
登录号、名称、蛋白质推荐名称、主要基因名称、NCBI 分类学、生物科学、序列、长度
例如:
P0AES4,GYRA_ECOLI,DNA 促旋酶亚基 A,gyrA,83333,大肠杆菌(菌株 K12),MSDLAREITP...,875
您的问题始于 正确命名事物:
xml = requests.Session().get(url.xml)
requests.get()
不 return XML。它 return 是一个 响应 。
resp = requests.Session().get(url.xml)
并且此响应可能包含 文本(即字符串):
print(resp.text)
而这个字符串可能是 XML,ElementTree 可以将其转换为树:
tree = ET.fromstring(resp.text)
然后我们可以使用它来获取信息:
tree.find('entry')
which returns None,因为在这种情况下 XML 在命名空间中 (xmlns="..."),而该命名空间是 http://uniprot.org/uniprot
.必须提到的是,当我们搜索元素时:
tree.find('{http://uniprot.org/uniprot}entry')
写起来很笨拙。所以我们做一个缩写:
xml_ns = {
'up': 'http://uniprot.org/uniprot'
}
并改用它:
tree.find('up:entry', xml_ns)
现在打印
<Element '{http://uniprot.org/uniprot}entry' at 0x03C0AD80>
利用所有这些,我们得到:
import requests
import xml.etree.ElementTree as ET
xml_url = 'https://www.uniprot.org/uniprot/P0AES4.xml'
xml_ns = {
'up': 'http://uniprot.org/uniprot'
}
resp = requests.get(xml_url)
tree = ET.fromstring(resp.text)
def get_text(node):
return node.text if node is not None else None
for entry in tree.findall('./up:entry', xml_ns):
data = {
'accession': get_text( entry.find('./up:accession', xml_ns) )
# find and add more items
}
print(data)
打印
{'accession': 'P0AES4'}
我正在尝试从科学数据库中检索数据。我有一个使用 urllib 和 ElementTree 的工作脚本,但我想使用更新的模块,所以我尝试用请求重写它。
不幸的是,由于 unicode 的 TypeError,ElementTree 不想再解析 XML。所以我尝试了 BeautifulSoup ,这在某种程度上有效,但在访问嵌套标签时遇到了问题。回到 ElementTree——它也是内置的。
对于以下代码,我得到 "TypeError: coercing to Unicode: need string or buffer, Response found"。如果我将“.text”或“.content”添加到带有 et.parsing 的行,则不会发生错误,而是打印而不是解析整个站点内容。
for entry in input_list:
xml = requests.Session().get(url.xml)
if xml.status_code == 200:
try:
tree = et.parse(xml)
root = getroot.tree()
for record in root.iter(base + 'placeholder').text:
var1 = record
break
print(var1)
except TypeError:
print('error on parsing')
else:
xml.raise_for_status()
编辑:
输出应如下所示:
登录号、名称、蛋白质推荐名称、主要基因名称、NCBI 分类学、生物科学、序列、长度
例如:
P0AES4,GYRA_ECOLI,DNA 促旋酶亚基 A,gyrA,83333,大肠杆菌(菌株 K12),MSDLAREITP...,875
您的问题始于 正确命名事物:
xml = requests.Session().get(url.xml)
requests.get()
不 return XML。它 return 是一个 响应 。
resp = requests.Session().get(url.xml)
并且此响应可能包含 文本(即字符串):
print(resp.text)
而这个字符串可能是 XML,ElementTree 可以将其转换为树:
tree = ET.fromstring(resp.text)
然后我们可以使用它来获取信息:
tree.find('entry')
which returns None,因为在这种情况下 XML 在命名空间中 (xmlns="..."),而该命名空间是 http://uniprot.org/uniprot
.必须提到的是,当我们搜索元素时:
tree.find('{http://uniprot.org/uniprot}entry')
写起来很笨拙。所以我们做一个缩写:
xml_ns = {
'up': 'http://uniprot.org/uniprot'
}
并改用它:
tree.find('up:entry', xml_ns)
现在打印
<Element '{http://uniprot.org/uniprot}entry' at 0x03C0AD80>
利用所有这些,我们得到:
import requests
import xml.etree.ElementTree as ET
xml_url = 'https://www.uniprot.org/uniprot/P0AES4.xml'
xml_ns = {
'up': 'http://uniprot.org/uniprot'
}
resp = requests.get(xml_url)
tree = ET.fromstring(resp.text)
def get_text(node):
return node.text if node is not None else None
for entry in tree.findall('./up:entry', xml_ns):
data = {
'accession': get_text( entry.find('./up:accession', xml_ns) )
# find and add more items
}
print(data)
打印
{'accession': 'P0AES4'}