【问题标题】:Scrapy Request callbacks not firingScrapy请求回调未触发
【发布时间】:2015-02-25 11:29:12
【问题描述】:

我正在使用 scrapy 0.24 从网站上抓取数据。但是,我无法从我的回调方法parse_summary 发出任何请求。

class ExampleSpider(scrapy.Spider):
    name = "tfrrs"
    allowed_domains = ["example.org"]
    start_urls = (
        'http://www.example.org/results_search.html?page=0&sport=track&title=1&go=1',
    )

    def __init__(self, *args, **kwargs):
        super(TfrrsSpider, self).__init__(*args, **kwargs)
        self.start_urls = ['http://www.example.org/results_search.html?page=0&sport=track'&title=1&go=1',]
            pass

    # works without issue
    def parse(self, response):
        races = response.xpath("//table[@width='100%']").xpath(".//a[starts-with(@href, 'http://www.tfrrs.org/results/')]/@href").extract()
        callback = self.parse_trackfieldsummary
        for race in races:
            yield scrapy.Request(race, callback=self.parse_summary)
        pass

    # works without issue
    def parse_summary(self, response):
        baseurl = 'http://www.example.org/results/'
        results = response.xpath("//div[@class='data']").xpath('.//a[@style="margin-left: 20px;"]/@href').extract()
        for result in results:
            print(baseurl+result)  # shows that url is correct everytime
            yield scrapy.Request(baseurl+result, callback=self.parse_compiled)

    # is never fired or shown in terminal
    def parse_compiled(self, response): 
        print('test')
        results = response.xpath("//table[@style='width: 935px;']")
        print(results)

当我故意在parse_summary 中发出请求失败(由于域错误等)时,我能够在提示中看到错误,但是当我使用正确的 url 时,就好像我什至没有调用它。我还在parse 方法中测试了parse_summary 中请求的url,它们按预期工作。是什么导致它们没有在parse_summary 方法中被解雇但在parse method 中成功?提前感谢您的帮助。

编辑

对我的Spider 进行一些更改后,我仍然得到相同的结果。但是,如果我使用一个全新的项目,它会起作用。所以我猜这与我的项目设置有关。

这是我的项目设置(raceretrieval 是我的项目名称):

BOT_NAME = 'raceretrieval'
DOWNLOAD_DELAY= 1
CONCURRENT_REQUESTS = 100
SPIDER_MODULES = ['raceretrieval.spiders']
NEWSPIDER_MODULE = 'raceretrieval.spiders'
ITEM_PIPELINES = {
        'raceretrieval.pipelines.RaceValidationPipeline':1,
        'raceretrieval.pipelines.RaceDistanceValidationPipeline':2,
#        'raceretrieval.pipelines.RaceUploadPipeline':9999
    }

如果我注释掉 both DOWNLOAD_DELAY= 1CONCURRENT_REQUESTS = 100,蜘蛛会按预期工作。为什么会这样?我不明白他们会如何影响这一点。

【问题讨论】:

  • 在 Reuques 中添加 dont_filter=True 是否有效?顺便说一句,绝对网址:urlparse.urljoin(response.url, result) 可能会好一点。
  • 您分享的代码需要一些改进。拼写错误很少,您使用 2 个不同的网址(example.org tfrrs.org)并且缺少方法(parse_trackfieldsummary)。

标签: python python-2.7 callback web-scraping scrapy


【解决方案1】:

我纠正了一些错别字并正确设置了允许的域,并且 parse_summary 似乎工作正常。 Url 被提取出来,并且 parse_compile 结果正确显示在终端中。

输出如下:

2014-12-29 12:19:05+0100 [example] DEBUG: Crawled (200) <GET
http://www.tfrrs.org/results/36288_f.html> (referer:
http://www.tfrrs.org/results/36288.html) <200
http://www.tfrrs.org/results/36288_f.html> 
[<Selector xpath="//table[@style='width: 935px;']" data=u'<table width="0" border="0" cellspacing='>, <Selector xpath="//table[@style='width: 935px;']" data=u'<table width="0" border="0" cellspacing='> .....

这里是更正的代码:

class ExampleSpider(scrapy.Spider):
    name = "example"
    allowed_domains = ["tfrrs.org"]
    start_urls = (
    'http://www.tfrrs.org/results_search.html?page=0&sport=track&title=1&go=1',
    )

def __init__(self, *args, **kwargs):
    super(ExampleSpider, self).__init__(*args, **kwargs)
    self.start_urls = ['http://www.tfrrs.org/results_search.html?page=0&sport=track&title=1&go=1',]


# works without issue
def parse(self, response):
    races = response.xpath("//table[@width='100%']").xpath(".//a[starts-with(@href, 'http://www.tfrrs.org/results/')]/@href").extract()
    #callback = self.parse_trackfieldsummary
    for race in races:
        yield scrapy.Request(race, callback=self.parse_summary)
    pass

# works without issue
def parse_summary(self, response):
    baseurl = 'http://www.tfrrs.org/results/'
    results = response.xpath("//div[@class='data']").xpath('.//a[@style="margin-left: 20px;"]/@href').extract()
    for result in results:
        #print(baseurl+result)  # shows that url is correct everytime
        yield scrapy.Request(baseurl+result, callback=self.parse_compiled)

# is never fired or shown in terminal
def parse_compiled(self, response): 
    print(response)
    results = response.xpath("//table[@style='width: 935px;']")
    print(results)

【讨论】:

  • 我刚刚尝试使用您更正版本中的 sn-ps 进行更正。我无法让它工作,所以我尝试用您更正的版本完全替换它(也失败了)。所以我创建了一个全新的项目并使用了你的代码。这完全按计划工作。我正在添加我的settings,可能是我的设置有误?
  • 我使用了您的 download_delay 和 concurrent_request 配置,它一直运行良好。我的scrapy版本是0.24.4。那么项目管道呢?
  • 由于终端缺乏反馈,我认为管道从未执行过。我添加了一些行以打印到管道中的终端,但它们没有打印到它。这可能只是我的安装所特有的,因为您没有遇到这些问题。
  • @aberna 我为此苦苦挣扎,在我的情况下是allowed_domains
【解决方案2】:

这些应该可以解决您遇到的问题

find / -type d -name "__pycache__" -delete 2>/dev/null

find / -name '*.pyc' -delete

find / -name '*.egg'

编辑:

如果这不能解决问题,那么问题实际上可能是下载延迟实际上是在积压最后一个请求,最终将在很长一段时间内产生 ^^

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    • 2016-11-21
    • 1970-01-01
    • 2016-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多