5

CareerBuilderAPIにGETリクエストを送信します。

import requests

url = "http://api.careerbuilder.com/v1/jobsearch"
payload = {'DeveloperKey': 'MY_DEVLOPER_KEY',
           'JobTitle': 'Biologist'}
r = requests.get(url, params=payload)
xml = r.text

そして、次のようなXMLを取得します。しかし、私はそれを解析するのに苦労しています。

いずれかを使用lxml

>>> from lxml import etree
>>> print etree.fromstring(xml)

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    print etree.fromstring(xml)
  File "lxml.etree.pyx", line 2992, in lxml.etree.fromstring (src\lxml\lxml.etree.c:62311)
  File "parser.pxi", line 1585, in lxml.etree._parseMemoryDocument (src\lxml\lxml.etree.c:91625)
ValueError: Unicode strings with encoding declaration are not supported.

またElementTree:

Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    print ET.fromstring(xml)
  File "C:\Python27\lib\xml\etree\ElementTree.py", line 1301, in XML
    parser.feed(text)
  File "C:\Python27\lib\xml\etree\ElementTree.py", line 1641, in feed
    self._parser.Parse(data, 0)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 3717: ordinal not in range(128)

したがって、XMLファイルは

<?xml version="1.0" encoding="UTF-8"?>

許可されていない文字が含まれている印象があります。このファイルをまたはで解析するにはどうすればよいですlxmlElementTree

4

3 に答える 3

16

デコードされたUnicode値を使用しています。代わりにr.raw生の応答データを使用してください。

r = requests.get(url, params=payload, stream=True)
r.raw.decode_content = True
etree.parse(r.raw)

応答からデータを直接読み取ります。stream=Trueのオプションに注意してください.get()

フラグを設定するr.raw.decode_content = Trueと、応答がgzipまたはdeflate圧縮されている場合でも、rawソケットが解凍されたコンテンツを確実に提供します。

応答をストリーミングする必要はありません小さいXMLドキュメントの場合は、デコードされていない応答本文であるresponse.content属性を使用するのが適切です。

r = requests.get(url, params=payload)
xml = etree.fromstring(r.content)

XMLパーサーは、XML形式自体がそれらのバイトをUnicodeテキストにデコードする方法を指示するため、常にバイトを入力として期待します。

于 2013-03-25T18:27:00.370 に答える
5

修正!

私がそれをすべて間違えた方法を以下に示します。基本的に、このメソッドを使用すると.text、結果はユニコードでエンコードされた文字列になります。これを使用すると、lxmlで次の例外が発生します

ValueError:エンコーディング宣言付きのUnicode文字列はサポートされていません。宣言なしでバイト入力またはXMLフラグメントを使用してください。

これは基本的に@martijn-pietersが正しかったことを意味し、によって返される生の応答を使用する必要があります.content

間違った答え(しかし誰かにとって興味深いかもしれません)

興味のある方のために。このエラーが発生する理由は、Response.textドキュメントで説明されているように、リクエストによって誤った推測が行われたためだと思います。

応答の内容(Unicode)。

Response.encodingがNoneの場合、エンコーディングはchardetを使用して推測されます。

応答コンテンツのエンコーディングは、レターのRFC 2616に従って、HTTPヘッダーのみに基づいて決定されます。HTTP以外の知識を利用してエンコーディングをより正確に推測できる場合は、このプロパティにアクセスする前にr.encodingを適切に設定する必要があります。

r.textしたがって、これに続いて、エンコードを明示的に設定することにより、リクエストが応答コンテンツを正しくエンコードすることを確認することもできます。r.encoding = 'UTF-8'

このアプローチは、lxmlで解析する前に、受信した応答が実際に正しいエンコーディングであるという別の検証を追加します。

于 2014-09-14T06:35:08.970 に答える
0

質問はすでに答えを得ていることを理解してください。私はPython3でこの同様の問題に直面し、Python2でも正常に機能しました。私の解決策は次のとおりです。str_xml.encode()それxml = etree.fromstring(str_xml)から、タグと属性の解析と抽出。

于 2020-11-02T11:55:07.487 に答える