【问题标题】:Scrapy not working with return and yield togetherScrapy 不能同时使用 return 和 yield
【发布时间】:2012-12-16 11:34:17
【问题描述】:

这是我的代码

def parse(self, response):
    soup = BeautifulSoup(response.body)
    hxs = HtmlXPathSelector(response)
    sites = hxs.select('//div[@class="row"]')
    items = []

    for site in sites[:5]:
        item = TestItem()
        item['username'] = "test5"
        request =  Request("http://www.example.org/profile.php",  callback = self.parseUserProfile)
        request.meta['item'] = item
        **yield item**

    mylinks= soup.find_all("a", text="Next")
    if mylinks:
        nextlink = mylinks[0].get('href')
        yield Request(urljoin(response.url, nextlink), callback=self.parse)

def parseUserProfile(self, response):
    item = response.meta['item']
    item['image_urls'] = "test3"
    return item

现在我的上述工作但我没有得到item['image_urls'] = "test3"的价值

它是空的

现在如果使用return request 而不是yield item

然后得到cannot use return with generator的错误

如果我删除这一行

yield Request(urljoin(response.url, nextlink), callback=self.parse) 然后我的代码工作正常,我可以得到image_urls,但我无法点击链接

那么有什么方法可以让我使用return requestyield together 来获取item_urls

【问题讨论】:

  • 如果你使用yield,你就可以让你的函数成为一个生成器,这就是你的错误告诉你的。 itemparseUserProfile 中定义在哪里?是类变量吗?
  • @Blender 我忘了在这里添加,我是从元响应中获取的。所以我应该怎么做才能解决我的问题。我在我的问题中添加了
  • 对于我的 Scrapy 应用程序,我一直只在回调函数中使用 yield 语句,一切正常。您是否尝试在parseUserProfile 中将return item 替换为yield item
  • 我尝试从解析中删除 yield item 并在 parseUserProfile 中用 yield item 替换返回项,然后数据库中没有保存任何内容。蜘蛛运行良好但scrapy没有得到任何物品
  • 这是一个关于生成器的 python 错误——你不能同时产生和返回项目(或请求)。选择一个,要么使用生成器,要么不使用。您可以从 scrapy 中的回调返回任何 python 序列。至于你的蜘蛛,听起来你想从 parse 中产生请求,它们的回调设置为 self.parseUserProfile(不是 self.parse),并且该回调完成了项目中的数据。

标签: python scrapy


【解决方案1】:

我不太了解您的问题,但我在您的代码中发现了一个问题:

def parseUserProfile(self, response):
    item = response.meta['item']
    item['image_urls'] = "test3"
    return item

解析回调返回值应该是序列,所以你应该做return [item]或将你的回调转换成一个生成器:

def parseUserProfile(self, response):
    item = response.meta['item']
    item['image_urls'] = "test3"
    yield item

【讨论】:

  • 我已经尝试过 evrything ,那个 yield 项也可以工作,但我的问题是我返回 items 并让下一个链接遵循的逻辑是相同的功能。所以要么我应该在页面上解析return item,要么我应该返回request 以抓取下一个链接。在 crawlspider 中,规则事物会自动跟踪他们从链接提取器获得的链接链接,但在 basespider 中,我必须手动获取链接并手动跟踪它们。这就是我遇到的问题
【解决方案2】:

您似乎遇到了机械故障。而不是:

for site in sites[:5]:
    item = TestItem()
    item['username'] = "test5"
    request =  Request("http://www.example.org/profile.php",  callback = self.parseUserProfile)
    request.meta['item'] = item
    **yield item**

你需要:

for site in sites[:5]:
    item = TestItem()
    item['username'] = "test5"
    request =  Request("http://www.example.org/profile.php",  callback = self.parseUserProfile)
    request.meta['item'] = item
    yield request

【讨论】:

  • 我没有收到scrapy退回的任何物品。我只在数据库中获得一个条目。我没有收到任何错误,爬虫运行正常,但scrapy 没有得到除第一个项目之外的任何项目。我们非常接近解决这个问题,因为我没有收到任何错误。我什至尝试将产量项目放在 parseuserprofile 中,但它再次不返回任何项目
  • 唯一正确返回项目的是return request,但我不能使用第二个产量。
  • 并在parseUserProfile 中输入yield item
  • 我已经尝试过了,但我没有收到任何返回的项目。
  • 你必须调试。将一些打印或pdb.set_trace 放入回调中以查看是否调用了任何内容。
猜你喜欢
  • 2012-03-26
  • 1970-01-01
  • 2011-01-04
  • 2017-07-07
  • 1970-01-01
  • 2023-03-21
  • 2020-05-30
  • 2020-02-18
  • 2017-11-26
相关资源
最近更新 更多