Ошибка с Python и XML

Я получаю сообщение об ошибке при попытке получить значение из моего XML. Я получаю «Строки Unicode с объявлением кодировки не поддерживаются. Используйте ввод байтов или фрагменты XML без объявления».

Вот мой код:

import requests
import lxml.etree
from requests.auth import HTTPBasicAuth

r= requests.get("https://somelinkhere/folder/?parameter=abc", auth=HTTPBasicAuth('username', 'password'))
print r.text

root = lxml.etree.fromstring(r.text)
textelem = root.find("opensearch:totalResults")
print textelem.text

Я получаю эту ошибку:

Traceback (most recent call last):
  File "tickets2.py", line 8, in <module>
    root = lxml.etree.fromstring(r.text)
  File "src/lxml/lxml.etree.pyx", line 3213, in lxml.etree.fromstring (src/lxml/lxml.etree.c:82934)
  File "src/lxml/parser.pxi", line 1814, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:124471)
ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.

Вот как выглядит XML, где я пытаюсь получить файл в последней строке.

<feed xmlns="http://www.w3.org/2005/Atom" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:apple-wallpapers="http://www.apple.com/ilife/wallpapers" xmlns:g-custom="http://base.google.com/cns/1.0" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:georss="http://www.georss.org/georss/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:cc="http://web.resource.org/cc/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:g-core="http://base.google.com/ns/1.0">
  <title>Feed from some link here</title>
  <link rel="self" href="https://somelinkhere/folder/?parameter=abc" />
  <link rel="first" href="https://somelinkhere/folder/?parameter=abc" />
  <id>https://somelinkhere/folder/?parameter=abc</id>
  <updated>2018-03-06T17:48:09Z</updated>
  <dc:creator>company.com</dc:creator>
  <dc:date>2018-03-06T17:48:09Z</dc:date>
  <opensearch:totalResults>4</opensearch:totalResults>

Я пробовал различные изменения по ссылкам типа https://twigstechtips.blogspot.com/2013/06/python-lxml-strings-with-encoding.html и http://makble.com/how-to-parse-xml-with-python.-and-lxml, но я продолжаю сталкиваться с той же ошибкой.


person Dan    schedule 06.03.2018    source источник
comment
Возможно, вместо этого попробуйте lxml.etree.fromstring(r.content).   -  person Daniel Haley    schedule 06.03.2018


Ответы (1)


Вместо r.text, который угадывает кодировку текста и декодирует его, попробуйте использовать r.content, который обращается к телу ответа как к байтам. (См. http://docs.python-requests.org/en/latest/user/quickstart/#response-content.)

Вы также можете использовать r.raw. См. разбор XML-файла получает UnicodeEncodeError (ElementTree)/ValueError (lxml) для получения дополнительной информации.

Как только эта проблема будет устранена, у вас возникнет проблема с пространством имен. Элемент, который вы пытаетесь найти (opensearch:totalResults), имеет префикс opensearch, связанный с uri http://a9.com/-/spec/opensearch/1.1/.

Вы можете найти элемент, объединив uri пространства имен и локальное имя (нотация Кларка):

{http://a9.com/-/spec/opensearch/1.1/}totalResults

Дополнительную информацию см. на странице http://lxml.de/tutorial.html#namespaces.

Вот пример с обоими реализованными изменениями:

os = "{http://a9.com/-/spec/opensearch/1.1/}"

root = lxml.etree.fromstring(r.content)
textelem = root.find(os + "totalResults")
print textelem.text
person Daniel Haley    schedule 06.03.2018
comment
Это было потрясающе. Та последняя часть, которую вы отправили, сработала как шарм. Большое Вам спасибо. - person Dan; 07.03.2018