4

私は Web スクレイピングが初めてで、Python で記述されたスクレイピング フレームワークであるScrapyの実験を始めたばかりです。私の目標は、メッセージ アーカイブを取得するための API やその他の手段を提供していない古い Yahoo グループをスクレイピングすることです。Yahoo グループは、アーカイブを表示する前にログインする必要があるように設定されています。

私が達成する必要がある手順は次のとおりです。

  1. ヤフーにログイン
  2. 最初のメッセージの URL にアクセスしてスクレイピングする
  3. 次のメッセージなどに対して手順 2 を繰り返します。

上記を達成するために、スクレイピースパイダーのラフアウトを開始しました。これが、これまでのところです。私が観察したいのは、ログインが機能し、最初のメッセージを取得できることだけです。これだけの作業が完了したら、残りを終了します。

class Sg101Spider(BaseSpider):
    name = "sg101"
    msg_id = 1              # current message to retrieve
    max_msg_id = 21399      # last message to retrieve

    def start_requests(self):
        return [FormRequest(LOGIN_URL,
            formdata={'login': LOGIN, 'passwd': PASSWORD},
            callback=self.logged_in)]

    def logged_in(self, response):
        if response.url == 'http://my.yahoo.com':
            self.log("Successfully logged in. Now requesting 1st message.")
            return Request(MSG_URL % self.msg_id, callback=self.parse_msg,
                    errback=self.error)
        else:
            self.log("Login failed.")

    def parse_msg(self, response):
        self.log("Got message!")
        print response.body

    def error(self, failure):
        self.log("I haz an error")

ただし、スパイダーを実行すると、スパイダーがログインして最初のメッセージのリクエストを発行することがわかります。ただし、scrapy からのデバッグ出力に表示されるのは 3 つのリダイレクトだけで、最終的に最初に要求した URL に到達します。しかし、scrapy は私のparse_msg()コールバックを呼び出さず、クロールは停止します。スクレイピー出力のスニペットは次のとおりです。

2011-02-03 19:50:10-0600 [sg101] INFO: Spider opened
2011-02-03 19:50:10-0600 [sg101] DEBUG: Redirecting (302) to <GET https://login.yahoo.com/config/verify?.done=http%3a//my.yahoo.com> from <POST https://login.yahoo.com/config/login>
2011-02-03 19:50:10-0600 [sg101] DEBUG: Redirecting (meta refresh) to <GET http://my.yahoo.com> from <GET https://login.yahoo.com/config/verify?.done=http%3a//my.yahoo.com>
2011-02-03 19:50:12-0600 [sg101] DEBUG: Crawled (200) <GET http://my.yahoo.com> (referer: None)
2011-02-03 19:50:12-0600 [sg101] DEBUG: Successfully logged in. Now requesting 1st message.
2011-02-03 19:50:12-0600 [sg101] DEBUG: Redirecting (302) to <GET http://launch.groups.yahoo.com/group/MyYahooGroup/auth?done=http%3A%2F%2Flaunch.groups.yahoo.com%2Fgroup%2FMyYahooGroup%2Fmessage%2F1> from <GET http://launch.groups.yahoo.com/group/MyYahooGroup/message/1>
2011-02-03 19:50:12-0600 [sg101] DEBUG: Redirecting (302) to <GET http://launch.groups.yahoo.com/group/MyYahooGroup/auth?check=G&done=http%3A%2F%2Flaunch%2Egroups%2Eyahoo%2Ecom%2Fgroup%2FMyYahooGroup%2Fmessage%2F1> from <GET http://launch.groups.yahoo.com/group/MyYahooGroup/auth?done=http%3A%2F%2Flaunch.groups.yahoo.com%2Fgroup%2FMyYahooGroup%2Fmessage%2F1>
2011-02-03 19:50:13-0600 [sg101] DEBUG: Redirecting (302) to <GET http://launch.groups.yahoo.com/group/MyYahooGroup/message/1> from <GET http://launch.groups.yahoo.com/group/MyYahooGroup/auth?check=G&done=http%3A%2F%2Flaunch%2Egroups%2Eyahoo%2Ecom%2Fgroup%2FMyYahooGroup%2Fmessage%2F1>
2011-02-03 19:50:13-0600 [sg101] INFO: Closing spider (finished)
2011-02-03 19:50:13-0600 [sg101] INFO: Spider closed (finished)

私はこれを理解することができません。Yahoo がスパイダーをリダイレクトしているように見えますが (認証チェックのためでしょうか?)、最初にアクセスしたかった URL に戻ってきたようです。しかし、scrapy はコールバックを呼び出さず、データをスクレイピングしたり、クロールを継続したりする機会がありません。

何が起こっているのか、および/またはこれをさらにデバッグする方法について誰か考えがありますか? ありがとう!

4

1 に答える 1

5

Yahoo は承認チェックのためにリダイレクトしていると思いますが、最終的には、本当に取得したかったページにリダイレクトされます。しかし、Scrapy はすでにこのリクエストを認識しており、ループに入りたくないので停止します。私の場合、解決策dont_filter=Trueは Request コンストラクターに追加することです。これは、Scrapy に重複するリクエストを除外しないように指示します。私の場合は、クロールする URL が事前にわかっているので、これで問題ありません。

def logged_in(self, response):
    if response.url == 'http://my.yahoo.com':
        self.log("Successfully logged in. Now requesting message page.",
                level=log.INFO)
        return Request(MSG_URL % self.msg_id, callback=self.parse_msg,
                errback=self.error, dont_filter=True)
    else:
        self.log("Login failed.", level=log.CRITICAL)
于 2011-02-04T04:43:47.047 に答える