2

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

运行下面的代码仅返回收集的信息parse 如果我将其更改return itemsreturn 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
4

3 回答 3

0

对 SSL 和 Fiddler 的事情感到抱歉。它们不是为你准备的。我在这里混合了两个答案.. :p 现在来看你的代码,你说

运行下面的代码只返回 parse 中收集的信息

这是正确的,因为您返回一个包含 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. 

这也是正确的,因为您在循环外使用“返回请求”,它只执行在循环中创建的最后一个请求,而不是前 4 个。所以要么制作一个“请求列表”并在循环外返回,要么在里面使用“屈服请求”循环..这肯定可以工作,因为我自己测试过同样的情况。返回解析中的项目将不会检索“thing3”。

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

于 2012-09-06T09:30:00.110 回答
0

安装pyOpenSSL,有时 fiddler 也会为 "https:\*" 请求产生问题。如果正在运行,请关闭提琴手并再次运行蜘蛛。代码中的另一个问题是,您在 parse 方法中使用了生成器,而不是使用 '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
于 2012-09-05T13:22:21.210 回答
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

我想现在它很清楚...

于 2012-09-06T15:21:39.463 回答