2013-06-05 2 views
1

Это работает для меня:Python TypeError при использовании xml.etree.ElemenTree и просит

 

import xml.etree.ElementTree as ET 
from urllib2 import urlopen 

url = 'http://example.com' 
# this url points to a `xml` page 
tree = ET.parse(urlopen(url)) 
 

Однако, когда я переключаюсь на requests, что-то было не так:

 

import requests 
import xml.etree.ElementTree as ET 
url = 'http://example.com' 
# this url points to a `xml` page 
tree = ET.parse(requests.get(url)) 
 

Ошибка Trackback предъявляется ниже:

 

--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
in() 
----> 1 tree = ET.parse(requests.get(url, proxies={'http': '192.168.235.36:7788'})) 

/usr/lib/python2.7/xml/etree/ElementTree.py in parse(source, parser) 
    1180 def parse(source, parser=None): 
    1181  tree = ElementTree() 
-> 1182  tree.parse(source, parser) 
    1183  return tree 
    1184 

/usr/lib/python2.7/xml/etree/ElementTree.py in parse(self, source, parser) 
    645   close_source = False 
    646   if not hasattr(source, "read"): 
--> 647    source = open(source, "rb") 
    648    close_source = True 
    649   try: 

TypeError: coercing to Unicode: need string or buffer, Response found 

 

Итак, мой вопрос: Ва неправильно с requests в моей ситуации и как я могу заставить его работать ET с requests?

ответ

3

Вы передаете в requestsобъект акустический отклик на ElementTree; вы хотите передать в raw file object вместо:

r = requests.get(url, stream=True) 
ET.parse(r.raw) 

.raw возвращает «файл типа» сокет объекта, из которого ElementTree.parse() будет читать, так же, как он будет читать из urllib2 ответа (который сам по себе является файл- подобный объект).

Конкретный пример:

>>> r = requests.get('http://www.enetpulse.com/wp-content/uploads/sample_xml_feed_enetpulse_soccer.xml', stream=True) 
>>> tree = ET.parse(r.raw) 
>>> tree 
<xml.etree.ElementTree.ElementTree object at 0x109dadc50> 
>>> tree.getroot().tag 
'spocosy' 

Если у вас есть сжатый URL, то сокеты (как urllib2) возвращает сжатые данные недекодированная; в этом случае вы можете использовать ET.fromstring() метод на binary response content:

r = requests.get(url) 
ET.fromstring(r.content) 
+0

Я пытался это сделать раньше, но не работал. Я получил это обратно: 'ParseError: элемент не найден: строка 1, столбец 0 ' – holys

+0

Мои извинения, для текущего API требуется, чтобы вы использовали 'stream = True', чтобы исходные чтения работали правильно, в противном случае данные загружаются с раннего времени. Повторите попытку с обновленным ответом. –

+0

Это не работает как есть, так как 'запросы' уже считывали данные, поступающие из сокета в конце первой строки. Передача 'stream = True' в качестве аргумента запроса обязательна – michaelmeyer

0

Вы не загружаете ElementTree текст ответа, но объект сам по себе, поэтому вы получаете ошибку типа: need string or buffer, Response found. Сделайте это вместо того, чтобы:

r = requests.get(url) 
tree = ET.fromstring(r.text) 
+1

Это не будет работать по двум причинам: 'r.text' является (декодируется) результат Unicode, вы всегда должны анализировать XML как не-декодируется data и 'ET.parse()' хочет имя файла или файл-подобный объект. 'ET.parse()' будет видеть результат 'r.text' как имя файла и передать его' open() '. –

+0

Я знаю, поэтому я отредактировал свой ответ :-) – michaelmeyer

+1

Вы все еще используете 'r.text' вместо' r.content', хотя .. –

Смежные вопросы