Scrapy不通过请求回调从项目中的Scraped Link返回附加信息

时间:2012-09-05 07:39:14

标签: python xpath scrapy

基本上下面的代码会刮掉表格的前5项。其中一个字段是另一个href,点击该href提供了我想要收集的更多信息并添加到原始项目。因此parse应该将半填充项目传递给parse_next_page,然后抓取下一位,并将完成的item返回parse

运行以下代码只会返回parse中收集的信息 如果我将return items更改为return request,我会收到一个包含所有3个“内容”的已完成项目,但我只获得1个行,而不是全部5个行。 我确定它简单,我只是看不到它。

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

3 个答案:

答案 0 :(得分:0)

安装pyOpenSSL,有时fiddler也会为“https:\ *”请求创建问题。如果跑步关闭提琴手再次运行蜘蛛。您的代码中的另一个问题是您在解析方法中使用生成器而不使用'yeild'将请求返回到scrapy调度程序。你应该这样做......

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

答案 1 :(得分:0)

很抱歉SSL和Fiddler的东西......它们不适合你。我在这里混合了两个答案..:p 现在来看你的代码,你说

  

运行以下代码只会返回在解析中收集的信息

这是正确的,因为你要返回一个包含5个项目的列表,其中填充了'thing1'和'thing2'返回项目,这不会导致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.所以要么创建一个'请求列表'并返回循环外部或使用'yield请求'在循环内..这应该工作肯定,因为我自己测试过同样的情况。返回解析内的项目将不会检索'thing3'。

只需应用任何一种解决方案,你的蜘蛛应该像导弹一样运行....

答案 2 :(得分: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

我觉得现在很清楚......