3

Scrapy と Python (Django プロジェクトの一部として) を使用して、ドイツ語のコンテンツを含むサイトをスクレイピングしています。Scrapylibxml2セレクターのバックエンドとしてインストールしました。

'Hüftsitz'セレクターを介して単語 (サイトでの表示方法)を抽出すると、次のようになります: u'H\ufffd\ufffdftsitz'(Scrapy XPath セレクターは Unicode 文字列を返します)。

これを にエンコードするUTF-8と、次のようになります'H\xef\xbf\xbd\xef\xbf\xbdftsitz'。そして、それを印刷すると、'H??ftsitz'どちらが正しくないかがわかります。なぜこれが起こっているのか疑問に思っています。

character-setサイトの は に設定されていますUTF-8sys.getdefaultencodingに設定した Python シェルで上記をテストしていUTF-8ます。UTF-8XPath セレクターからのデータが文字セットを使用して MySQL データベースに書き込まれる Django アプリケーションを使用すると、同じ動作が見られます。

ここで明らかなことを見落としていますか?手がかりや助けをいただければ幸いです。

4

3 に答える 3

3

ジョンとスティーブン、ご回答ありがとうございます。あなたの答えは私に別の考え方をさせ、それが問題の原因と有効な解決策を見つけることにつながりました.

次のテストコードを使用していました。

import urllib
import urllib2
from scrapy.selector import HtmlXPathSelector
from scrapy.http import HtmlResponse

URL = "http://jackjones.bestsellershop.com/DE/jeans/clark-vintage-jos-217-sup/37246/37256"

url_handler = urllib2.build_opener()
urllib2.install_opener(url_handler)

handle = url_handler.open(URL)
response = handle.read()
handle.close()

html_response = HtmlResponse(URL).replace(body=response) # Problematic line
hxs = HtmlXPathSelector(html_response)

desc = hxs.select('//span[@id="attribute-content"]/text()')
desc_text = desc.extract()[0]
print desc_text
print desc_text.encode('utf-8')

Scrapy シェル内で、記述データを抽出したところ、問題なく出力されました。pdbプロンプトで、抽出されたデータに置換文字が表示されていたため、コードに何か問題があるのではないかと疑う理由がありました。

Response クラスの Scrapy ドキュメントを調べ、上記のコードを次のように調整しました。

import urllib
import urllib2
from scrapy.selector import HtmlXPathSelector
from scrapy.http import HtmlResponse

URL = "http://jackjones.bestsellershop.com/DE/jeans/clark-vintage-jos-217-sup/37246/37256"

url_handler = urllib2.build_opener()
urllib2.install_opener(url_handler)

handle = url_handler.open(URL)
response = handle.read()
handle.close()

#html_response = HtmlResponse(URL).replace(body=response)
html_response = HtmlResponse(URL, body=response)
hxs = HtmlXPathSelector(html_response)

desc = hxs.select('//span[@id="attribute-content"]/text()')
desc_text = desc.extract()[0]
print desc_text
print desc_text.encode('utf-8')

html_response = HtmlResponse(URL).replace(body=response)私が行った変更は、行をに置き換えることでしたhtml_response = HtmlResponse(URL, body=response)replace()この方法は、エンコーディングの観点から何らかの形で特殊文字をマングリングしていたと理解しています。

メソッドが正確に何をreplace()間違っていたのか、詳細を教えてくれる人がいれば、その努力に感謝します。

もう一度ありがとう。

于 2011-04-12T06:52:31.790 に答える
3

u'\ufffd' は 「Unicode 置換文字」で、通常は黒い三角形の中にクエスチョン マークとして表示されます。ウムラウトではありません。したがって、問題は上流のどこかにあるはずです。Web ページのヘッダーが示すエンコーディングが返されていることを確認し、それが実際に何を示しているかを確認します。

Unicode 置換文字は通常、不正な文字または認識されない文字の代わりとして挿入されます。これはいくつかの原因で発生する可能性がありますが、最も可能性が高いのは、エンコーディングが主張されているものではないことです。

于 2011-04-11T21:50:27.920 に答える
1

U+FFFD は、その場合に得られる置換文字でありsome_bytes.decode('some-encoding', 'replace')、一部の部分文字列はsome_bytesデコードできません。

それらの 2 つがあります: u'H\ufffd\ufffdftsitz'... これは、u-umlaut が 2 バイトとして表され、それぞれがデコードに失敗したことを示しています。ほとんどの場合、サイトは UTF-8 でエンコードされていますが、ソフトウェアはそれを ASCII としてデコードしようとしています。通常、ASCII としてデコードしようとするのは、予期しない Unicode への変換が発生し、デフォルトのエンコードとして ASCII が使用される場合です。'replace'ただし、その場合、引数が使用されることは期待できません。コードがエンコーディングを取り込んでいて、「例外を発生させない」ということは「動作する」ということと同じ意味だと考える人によって書かれている可能性が高いです。

質問を編集して URL を提供し、生成される最小限のコードを表示しますu'H\ufffd\ufffdftsitz'

于 2011-04-11T22:02:27.677 に答える