2

基本的に、以下のコードはテーブルの最初の 5 項目をスクレイピングします。フィールドの 1 つは別の href であり、その href をクリックすると、収集して元のアイテムに追加したい詳細情報が表示されます。そのため、次のビットをスクレイピングし、完成したアイテムをに戻す必要があるparse半実装アイテムを渡すことになっていますparse_next_pageitemparse

以下のコードを実行すると、で収集された情報のみが返されます。parse を に変更するreturn itemsreturn request、3 つの「もの」すべてを含む完了したアイテムが得られますが、5 つすべてではなく、1 つの行しか得られません。見てください。

class ThingSpider(BaseSpider):
name = "thing"
allowed_domains = ["somepage.com"]
start_urls = [
"http://www.somepage.com"
]

def parse(self, response):
    hxs = HtmlXPathSelector(response)
    items = []

    for x in range (1,6):
        item = ScrapyItem()
        str_selector = '//tr[@name="row{0}"]'.format(x)
        item['thing1'] = hxs.select(str_selector")]/a/text()').extract()
        item['thing2'] = hxs.select(str_selector")]/a/@href').extract()
        print 'hello'
        request = Request("www.nextpage.com", callback=self.parse_next_page,meta={'item':item})
        print 'hello2'
        request.meta['item'] = item
        items.append(item)      

    return items


def parse_next_page(self, response):
    print 'stuff'
    hxs = HtmlXPathSelector(response)
    item = response.meta['item']
    item['thing3'] = hxs.select('//div/ul/li[1]/span[2]/text()').extract()
    return item
4

3 に答える 3

0

SSLとFiddlerについて申し訳ありませんが、それらはあなたのためのものではありませんでした。私はここで2つの答えを混ぜました..:pさて、あなたのコードに来てください、あなたは言いました

以下のコードを実行すると、解析で収集された情報のみが返されます

これは、「thing1」と「thing2」が入力された5つのアイテムのリストを返すためです。ここでアイテムを返すと、以下に示すように、scrapyエンジンがリクエストをコールバック「parse_next_page」に送信しません。

for x in range (1,6):
    item = ScrapyItem()
    str_selector = '//tr[@name="row{0}"]'.format(x)
    item['thing1'] = hxs.select(str_selector")]/a/text()').extract()
    item['thing2'] = hxs.select(str_selector")]/a/@href').extract()
    print 'hello'
    request = Request("www.nextpage.com", callback=self.parse_next_page,meta={'item':item})
    print 'hello2'
    request.meta['item'] = item
    items.append(item)      

return items

それからあなたは言った...

If I change the return items to return request I get a completed item with all 3 "things" but I only get 1 of the rows, not all 5. 

これは、ループの外側で「return request」を使用していて、最初の4ではなく、ループで作成された最後のリクエストのみを実行するためにも当てはまります。したがって、「リクエストのリスト」を作成してループの外側に戻るか、「yieldrequest」を内側で使用します。ループ..私が同じケースを自分でテストしたので、これは間違いなく機能するはずです。解析内でアイテムを返すと、「thing3」は取得されません。

いずれか1つの解決策を適用するだけで、スパイダーはミサイルのように動作するはずです。

于 2012-09-06T09:30:00.110 に答える
0

ああ.. yarr.. コードをこれに変更..

def parse(self, response):
hxs = HtmlXPathSelector(response)
items = []

for x in range (1,6):
    item = ScrapyItem()
    str_selector = '//tr[@name="row{0}"]'.format(x)
    item['thing1'] = hxs.select(str_selector")]/a/text()').extract()
    item['thing2'] = hxs.select(str_selector")]/a/@href').extract()
    print 'hello'
    request = Request("www.nextpage.com", callback=self.parse_next_page,meta={'item':item})
    print 'hello2'
    yield request
    #donot return or yield item here.. only yield request return item in the callback.


def parse_next_page(self, response):
    print 'stuff'
    hxs = HtmlXPathSelector(response)
    item = response.meta['item']
    item['thing3'] = hxs.select('//div/ul/li[1]/span[2]/text()').extract()
    return item

私は今、それはかなり明確だと思います...

于 2012-09-06T15:21:39.463 に答える
0

pyOpenSSLをインストールします。フィドラーが「https:\*」リクエストで問題を引き起こすこともあります。実行中の場合はフィドラーを閉じ、スパイダーを再度実行します。解析メソッドでジェネレーターを使用しており、「yeild」を使用してリクエストをスクレイピースケジューラーに返していないというコードにある別の問題。こうすればいいのに……。

def parse(self, response):
    hxs = HtmlXPathSelector(response)
    items = []

for x in range (1,6):
    item = ScrapyItem()
    str_selector = '//tr[@name="row{0}"]'.format(x)
    item['thing1'] = hxs.select(str_selector")]/a/text()').extract()
    item['thing2'] = hxs.select(str_selector")]/a/@href').extract()
    print 'hello'
    request = Request("www.nextpage.com",callback=self.parse_next_page,meta{'item':item})
    if request:
         yield request
    else:
         yield item
于 2012-09-05T13:22:21.210 に答える