web-dev-qa-db-ja.com

lxmlとリクエストを使用したHTMLスクレイピングでUnicodeエラーが発生する

提供されているようなHTMLスクレイパーを使用しようとしています ここ 。彼らが提供した例では問題なく動作します。ただし、 webpage で使用しようとすると、このエラーが発生します--Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.グーグルを試しましたが、解決策が見つかりませんでした。助けていただければ幸いです。 Pythonを使用してHTMLとしてコピーする方法があるかどうか知りたいのですが。

編集:

from lxml import html
import requests
page = requests.get('http://cancer.sanger.ac.uk/cosmic/gene/analysis?ln=PTEN&ln1=PTEN&start=130&end=140&coords=bp%3AAA&sn=&ss=&hn=&sh=&id=15#')
tree = html.fromstring(page.text)

ありがとうございました。

21
user3783999

簡単な答え:page.contentではなくpage.textを使用してください。

から http://lxml.de/parsing.html#python-unicode-strings

lxml.etreeのパーサーはUnicode文字列をすぐに処理できます...ただし、これには、Unicode文字列自体が競合するエンコーディングを指定していないため、実際のエンコーディングについて嘘をついている必要があります

から http://docs.python-requests.org/en/latest/user/quickstart/#response-content

リクエストは、サーバーからのコンテンツを[r.textとして]自動的にデコードします。 ...応答本文にバイトとして[r.contentとして]アクセスすることもできます。

ご覧のとおり、requests.textlxml.etreeの両方がutf-8をUnicodeにデコードしたいと考えています。しかし、requests.textにデコードを行わせると、xmlファイル内のencodingステートメントは嘘になります。

それでは、requests.contentにデコードを行わせないようにしましょう。そうすれば、lxmlは一貫してデコードされていないファイルを受け取ります。

52
Robᵩ