24

これをスクレイピーで行う方法について質問があります。アイテムのリスト ページをクロールするスパイダーがあります。アイテムを含むリスティング ページが見つかるたびに、アイテム データを抽出してアイテムを生成するために呼び出される parse_item() コールバックがあります。これまでのところ、すべてがうまく機能しています。

ただし、各アイテムには、他のデータの中でも、そのアイテムの詳細を含む URL があります。その URL をたどり、別のアイテム フィールド (url_contents) に、そのアイテムの URL のフェッチされたコンテンツを格納したいと考えています。

2 つのリンク (リスト リンクと 1 つの特定のアイテム リンク) は異なるタイミングで呼び出され、コールバックが異なる方法でたどられるため、それを達成するためのコードを整理する方法がわかりませんが、同じアイテム処理でそれらを関連付ける必要があります。 .

これまでの私のコードは次のようになります。

class MySpider(CrawlSpider):
    name = "example.com"
    allowed_domains = ["example.com"]
    start_urls = [
        "http://www.example.com/?q=example",
    ]

    rules = (
        Rule(SgmlLinkExtractor(allow=('example\.com', 'start='), deny=('sort='), restrict_xpaths = '//div[@class="pagination"]'), callback='parse_item'),
        Rule(SgmlLinkExtractor(allow=('item\/detail', )), follow = False),
    )


    def parse_item(self, response):
        main_selector = HtmlXPathSelector(response)
        xpath = '//h2[@class="title"]'

        sub_selectors = main_selector.select(xpath)

        for sel in sub_selectors:
            item = ExampleItem()
            l = ExampleLoader(item = item, selector = sel)
            l.add_xpath('title', 'a[@title]/@title')
            ......
            yield l.load_item()
4

2 に答える 2

21

いくつかのテストと検討の後、私は自分に合ったこのソリューションを見つけました。アイデアは、アイテムのリストを表示する最初のルールだけを使用し、非常に重要なことですが、そのルールに follow=True を追加することです。

parse_item() では、アイテムの代わりにリクエストを生成する必要がありますが、アイテムをロードした後です。商品詳細URLへのリクエストです。そして、ロードされたアイテムをそのリクエスト コールバックに送信する必要があります。あなたは応答であなたの仕事をします、そしてあなたがアイテムを譲る場所があります。

したがって、parse_item() の仕上げは次のようになります。

itemloaded = l.load_item()

# fill url contents
url = sel.select(item_url_xpath).extract()[0]
request = Request(url, callback = lambda r: self.parse_url_contents(r))
request.meta['item'] = itemloaded

yield request

parse_url_contents() は次のようになります。

def parse_url_contents(self, response):
    item = response.request.meta['item']
    item['url_contents'] = response.body
    yield item

誰かが別の (より良い) アプローチを持っている場合は、お知らせください。

ステファン

于 2011-05-01T20:28:50.283 に答える
2

私はまったく同じ問題を抱えています.2日間誰もあなたの質問に答えていないという事実から、唯一の解決策はparse_item関数内からそのURLを手動でたどることだと思います.

私はScrapyを初めて使用するので、それを試してみませんが(可能だと確信していますが)、私の解決策は、BeatifulSoupを使用urllibして2番目のページを手動でロードし、その情報を自分で抽出して保存することですアイテムの一部として。はい、Scrapy が通常の解析を行うよりもはるかに手間がかかりますが、最小限の手間で作業を完了できるはずです。

于 2011-05-01T18:35:18.117 に答える