1

parse_items私はスパイダーにこのコードを持っています

 def parse_items(self, response):

        hxs = HtmlXPathSelector(response)
        sites = hxs.select("//li[@class='mod-result-entry  ']")
        items = []


        for site in sites[:2]:
            item = MyItem()
            item['title'] = myfilter(site.select('dl/a').select("string()").extract())
            item['company'] = myfilter(site.select('dl/h2/em').select("string()").extract())
            items.append(item)
        return items

今、Django モデルを使用してアイテムをデータベースに保存したいと考えています。私がこのように使用するだけでうまく機能している1つの方法

item = MYapp.MyDjangoItem()
item.title = myfilter(site.select('dl/a').select("string()").extract())
item.save()

今、これはうまくいっています

今、私はそれがデータベースに保存するための良い方法であることを知りたいです.

スクレイピーで記述されたアイテムパイプラインが必要な理由を意味します。これには何か利点がありますか。

Fir e,g これは私のパイプラインです

class MyPipeline(object):

    def __init__(self):
        self.ids_seen = set()

    def process_item(self, item, spider):
       Myitem = Myapp.DjamgoItem()
       Myitem.title = item['title']
       MyItem.save()

それでいいですか

また、私のコードはこのパイプラインをどのように呼び出しますか。私はこれと混同しています

4

1 に答える 1

1

パイプラインは、一般的な値をサニタイズするのに役立ちます。これは、オブジェクトのタイプが 1 つしかない場合に特に便利です。パイプラインを介して django モデル インスタンスを保存することは問題ありません。スクレイピー ドキュメントの例では、パイプラインに JsonWriter を追加することで同じことを行います。(そのための組み込み機能があるため、実際には不要です)

考えが口に出ていた:

ただし、複数のオブジェクトを作成している場合は、おそらく処理を区別したいと思うでしょう。スパイダーは引数として process_item 関数に渡されるため、これは簡単ですが (imo)、かなり冗長になる傾向があります。

class MyPipeline(object):
    def process_item(self, item, spider):
       if spider == 'A':
           if item.somefield:
               #... etc
       elif spider == 'B':
           #... etc

個人的には、Django のフォーム クリーニングの背後にあるアイデアが気に入っています (「clean_」を前に付けたフィールド名で既存の関数をチェックする)。スクレイピーで同様の機能を実現するために、Item クラスを拡張しました。

class ExtendedItem(Item):
    def _process(self):
        [getattr(self, func)() for func in dir(self) if func.split('_')[-1] in self.fields and callable(getattr(self, func))]

したがって、次のようなことができます。

class Book(ExtendedItem):
    title = Field()

    def _process_title(self):
        title = self['title'].lower()
        self.update(title=title)

この場合、パイプラインを使用して item._process() を呼び出すことができます。

免責事項

少し前にgithub.comでこのアイデアを提案しました。おそらくより良い実装があります(コード単位)。

于 2012-12-11T09:51:13.873 に答える