python - 维基百科爬虫的 cron 作业和任务队列的应用程序引擎 DeadlineExceededError

标签 python google-app-engine cron wikipedia

我正在尝试在谷歌应用引擎上构建一个维基百科链接爬虫。我想在数据存储中存储索引。但我遇到了 cron 作业和任务队列的 DeadlineExceededError。

对于 cron 作业,我有以下代码:

def buildTree(self):

<pre><code> start=time.time() self.log.info(" Start Time: %f" % start) nobranches=TreeNode.all() for tree in nobranches: if tree.branches==[]: self.addBranches(tree) time.sleep(1) if (time.time()-start) > 10 : break self.log.info("Time Eclipsed: %f" % (time.time()-start)) self.log.info(" End Time:%f" % time.clock()) </code></pre>

我不明白为什么 for 循环在 10 秒后没有中断。它在开发服务器上执行。服务器上的 time.time() 肯定有问题。还有其他功能我可以使用吗?

对于任务队列,我有以下代码:
def addNewBranch(self, keyword, level=0):

<pre><code> self.log.debug("Add Tree") self.addBranches(keyword) t=TreeNode.gql("WHERE name=:1", keyword).get() branches=t.nodes if level < 3: for branch in branches: if branch.branches == []: taskqueue.add(url="/addTree/%s" % branch.name) self.log.debug("url:%s" % "/addTree/%s" % branch.name) </code></pre>

日志显示它们都遇到了 DeadlineExceededError。后台处理时间不应超过页面请求的 30 秒。有没有办法解决异常?

这是 addBranch() 的代码

<p>def addBranches(self, keyword): </p> <pre><code> tree=TreeNode.gql("WHERE name=:1", keyword).get() if tree is None: tree=TreeNode(name=keyword) self.log.debug("in addBranches arguments: tree %s", tree.name) t=urllib2.quote(tree.name.encode('utf8')) s="http://en.wikipedia.org/w/api.php?action=query&titles=%s&prop=links&pllimit=500&format=xml" % t self.log.debug(s) try: usock = urllib2.urlopen(s) except : self.log.error( "Could not retrieve doc: %s" % tree.name) usock=None if usock is not None: try: xmldoc=minidom.parse(usock) except Exception , error: self.log.error("Parse Error: %s" % error) return None usock.close() try: pyNode= xmldoc.getElementsByTagName('pl') self.log.debug("Nodes to be added: %d" % pyNode.length) except Exception, e: pyNode=None self.log.error("Getting Nodes Error: %s" % e) return None newNodes=[] if pyNode is not None: for child in pyNode: node=None node= TreeNode.gql("WHERE name=:1", child.attributes["title"].value).get() if node is None: newNodes.append(TreeNode(name=child.attributes["title"].value)) else: tree.branches.append(node.key()) db.put(newNodes) for node in newNodes: tree.branches.append(node.key()) self.log.debug("Node Added: %s" % node.name) tree.put() return tree.branches </code></pre>

最佳答案

我在 GAE 上的日期时间方面取得了巨大成功。

from datetime import datetime, timedelta
time_start = datetime.now()
time_taken = datetime.now() - time_start

time_taken 将是一个时间增量。您可以将其与具有您感兴趣的持续时间的另一个时间增量进行比较。

ten_seconds = timedelta(seconds=10)
if time_taken > ten_seconds:
    ....do something quick.

听起来使用 mapreduce 或任务队列会为您提供更好的服务。两者对于处理大量记录都很有趣。

您拥有的代码的更简洁模式是仅获取一些记录。

nobranches=TreeNode.all().fetch(100)

此代码只会提取 100 条记录。如果您已满 100 个,完成后,您可以在队列中添加另一个项目以启动更多项目。

-- 基于关于需要没有 Twig 的树的评论 --

我在那里没有看到你的模型,但如果我试图创建一个没有分支的所有树的列表并处理它们,我会:仅获取 100 个左右 block 中的树的键。然后,我将使用 In 查询获取属于这些树的所有分支。按树键排序。扫描分支列表,第一次找到树的 key 时,从列表中拉出 key 树。完成后,您将获得“无分支”树键的列表。安排其中每一项进行处理。

一个更简单的版本是在树上使用 MapReduce。对于每棵树,找到与其 ID 匹配的一个分支。如果不能,请标记该树以进行后续处理。默认情况下,此函数将拉取具有 8 个并发工作线程的批量树(我认为是 25 个)。而且,它在内部管理作业队列,因此您不必担心超时。

关于python - 维基百科爬虫的 cron 作业和任务队列的应用程序引擎 DeadlineExceededError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3919337/

相关文章:

bash - 如何自动运行 crons?

javascript - 如果未指定文件上传,Google Apps 脚本中会出现错误

python - 使用spark ML 2.2.0中的sklearn-python模型进行预测

python - 如何使用 Odoo 中的方法设置默认值?

python - 使用 Selenium 的 Python API - 如何获取表中的行数?

java - 用 Java 编写的 Google Appengine 应用程序可以访问 Python+Numpy+Scipy?

python - 将 Blob 从一个 AppEngine 应用程序复制到另一个

php - Cronjob 但适用于 jQuery/Javascript

c# - 如何调用函数但不等待完成 - ASP.NET

python - 如何在kivy python中使用滚动条