1

一部の Web サイトをスクレイピングするために使用したい Scrapy プロジェクトがあります。すべての情報を MySQL データベースに保存しようとすると、タイトルのエラーが表示されます。私はどこでも読んで、おそらくアイテム[]リストに関連する「リスト」の問題であることがわかりました...このエラーの意味とコードを修正する必要がある場所を理解してください。知りたいので理由も教えてください。どうもありがとう。

スパイダー コード:

from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.contrib.spiders.crawl import Rule, CrawlSpider
from scrapy.selector import HtmlXPathSelector


from gscrape.items import GscrapeItem

class GuideSpider(CrawlSpider):
    name = "Dplay"
    allowed_domains = ['www.example.com']
    start_urls = [
        "http://www.examplea.com/forums/forumdisplay.php?f=108&order=desc&page=1"
    ]
    rules = (
        Rule(SgmlLinkExtractor(allow=("forumdisplay.php.*f=108.*page=")), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        hxs = HtmlXPathSelector(response)
        items = []
        sites = hxs.select('//div')
        for site in sites:
            item = GscrapeItem()
            item['title'] = site.select('a[@class="threadcolor"]/text()').extract()
            item['guide_url'] = site.select('a[@class="threadcolor"]/@href').extract()
            item['subject'] = site.select('./text()[1]').extract()
            items.append(item)
        return items

パイプライン コード:

from scrapy.exceptions import DropItem
from string import join
from scrapy import log
from twisted.enterprise import adbapi

import MySQLdb.cursors

class GscrapePipeline(object):

    def process_item(self, item, spider):
        if item['guide_url']:
                item['guide_url'] = "http://www.example.com/forums/" + join(item['guide_url'])
                return item
        else:
            raise DropItem()

class MySQLStorePipeline(object):

    def __init__(self):
        # @@@ hardcoded db settings
        # TODO: make settings configurable through settings
        self.dbpool = adbapi.ConnectionPool('MySQLdb',
            db='prova',
            host='127.0.0.1',
            user='root',
            passwd='',
            cursorclass=MySQLdb.cursors.DictCursor,
            charset='utf8',
            use_unicode=True
        )

    def process_item(self, spider, item):
        # run db query in thread pool
        query = self.dbpool.runInteraction(self._conditional_insert, item)
        query.addErrback(self.handle_error)

        return item

    def _conditional_insert(self, tx, item):
    # create record if doesn't exist.
    # all this block run on it's own thread
        tx.execute("select * from prova where guide_url = %s", item['guide_url'])
        result = tx.fetchone()
        if result:
            log.msg("Item already stored in db: %s" % item, level=log.DEBUG)
        else:
            tx.execute(\
            "insert into prova (title, guide_url, subject) "
            "values (%s, %s, %s)",
            (item['title'],
             item['guide_url'],
             item['subject']
                ))
            log.msg("Item stored in db: %s" % item, level=log.DEBUG)

    def handle_error(self, e):
        log.err(e)

エラー: exceptions.TypeError: 'GuideSpider' object is not subscriptable (47 行目) pipelines.py

4

1 に答える 1

2

ドキュメントによると:

process_item(item, spider)

私はあなたのパイプラインで意味します:

def process_item(self, spider, item):

パラメータの順序が間違っています_conditional_insert。これは、アイテムではなくスパイダーに渡すことを意味します。

デバッガーについて学びましょう。ipdbをインストールし、47 行目 (問題のある行の前) に次のように入力します。

import ipdb; ipdb.set_trace()

プログラムがブレークポイントに到達すると、変数の値を確認したり、メソッドを手動で呼び出したり、バックトレースを確認したりできます。

于 2012-09-15T10:45:45.870 に答える