2017-10-24 17 views
0

いくつかのEUサイトからデータを盗み、response.xpath()への私の呼び出しがテキストを壊すことがあることがわかりました。たとえば、"& amp;" &#164などのhtmlエンティティと、壊れたバイト(\x92または\xc3など)に翻訳されています。 xpathメソッド(lxml libを使用)を呼び出す前に、いくつかの実用的な解決法を見つけました。ミドルウェアのscrapy Responseオブジェクトを変更することはできますか?

body_str = str(response.body, response._body_declared_encoding()) 
unescaped_body = html.unescape(body_str) 
response = response.replace(body=unescaped_body) 

応答を処理するためにコールバックの開始時にこのようなコードがすぐに呼び出されると、うまく機能しているようです。

私が今やろうとしていることは要求ごとに、または別のクモなどにこのアプローチを使用するように、スパイダーミドルウェアにこのコードを移動することですしかし、問題は、このコードは

内のレスポンスオブジェクトを変更しないということです
def process_spider_input(self, response, spider): 

response = response.replace(...)は、他の場所では使用されていない新しいローカル変数レスポンスを作成します。 私の質問はタイトルです:スパイダーミドルウェア内のレスポンスオブジェクトを変更することはできますか?

答えて

0

process_responseメソッドでDownloader Middlewareを使用し、Responseオブジェクトを返す方が良いと言います。

... 
def process_response(self, request, response, spider): 
    ... 
    body_str = str(response.body, response._body_declared_encoding()) 
    unescaped_body = html.unescape(body_str) 
    new_response = response.replace(body=unescaped_body) 
    return new_response 
+0

ありがとうございます。あなたは正しいですし、Downloader MiddlewareはResponseオブジェクトを置き換えるのに完璧です。 Unfortuanlly私の特定の解決策は、ミドルウェアでは '_body_declared_encoding()'(返り値なし)を使うことができず、response.bodyは生のままでgzipedバイトオブジェクトである可能性があるため動作しませんでした。私はこれについてもっと学び、新しい解決策を見つけようとします。多くのおかげで再びあなたの質問に私の答えを引き起こす –

関連する問題