爬虫技术抓取网站数据python,python爬虫数据采集
大蟒异步采集,网页爬虫编写一步一步学大蟒
大蟒异步采集对于大量的数据采集除了多线程,就只有异步来实现了
上一篇文章里我写了有关多线程的实现,对于异步的由于本人对大蟒的学习还不是很深入还不能自己写出来,刚好看到一个篇使用扭曲的异步采集的文章,就搬过来给大家分享一下。
使用扭曲的的异步批处理:演练
示例1:只是一个定义列表
从扭曲的互联网导入反应器
从twisted.web.client导入获取页面
从twisted.internet.defer导入延迟列表
定义列表回调(结果):
打印结果
定义完成(ign):
反应器。停止()
定义测试():
D1=获取页面( http://www。谷歌。com’)
d2=getPage(http://yahoo.com )
dl=DeferredList([d1,d2])
dl.addCallback(listCallback)
dl。增加回调(完成)
测试()
reactor.run()这是您将看到的最简单的延迟列表实例之一。获取两个延期(获取页面函数返回一个延期)并使用它们创建一个延期的列表。在列表中添加回调,用柠檬装饰。
示例2:简单的结果操作
从扭曲的互联网导入反应器
从twisted.web.client导入获取页面
从twisted.internet.defer导入延迟列表
定义列表回调(结果):
对于问题成功,结果中的内容:
"打印"成功?%s %是一个成功
"打印"内容长度:% s"% len(内容)
定义完成(ign):
反应器。停止()
定义测试():
D1=获取页面( http://www。谷歌。com’)
d2=getPage(http://yahoo.com )
dl=DeferredList([d1,d2])
dl.addCallback(listCallback)
dl。增加回调(完成)
测试()
reactor.run()在这个例子中,我们通过对结果进行一些处理,让事情变得更有趣一些。要做到这一点,只需记住,当延迟的操作完成时,回调会传递结果。如果我们查找延迟列表的应用程序接口文档,我们会看到它返回一个(成功,结果)元组的列表,其中成功是一个布尔值,结果是放入列表中的延期的的结果(记住,我们这里有两层延期!).
示例3:页面回调
从扭曲的互联网导入反应器
从twisted.web.client导入获取页面
从twisted.internet.defer导入延迟列表
定义页面回调(结果):
返回len(结果)
定义列表回调(结果):
打印结果
定义完成(ign):
反应器。停止()
定义测试():
D1=获取页面( http://www。谷歌。com’)
d1.addCallback(pageCallback)
d2=getPage(http://yahoo.com )
d2.addCallback(pageCallback)
dl=DeferredList([d1,d2])
dl.addCallback(listCallback)
dl.addCallback(完成)
测试()
reactor.run()在这里,我们稍微混合一下。我们不是一次处理所有结果(在延迟列表回调中),而是在页面回调触发时处理它们。我们这里的处理只是一个简单的例子,用来获取获取页面延迟结果的长度:给定统一资源定位器处页面的超文本标记语言内容。
示例4:具有更多结构的结果
从扭曲的互联网导入反应器
从twisted.web.client导入获取页面
从twisted.internet.defer导入延迟列表
定义页面回调(结果):
数据={
长度:len(结果),
内容:结果[:10],
返回数据
定义列表回调(结果):
对于发布成功,结果中的数据:
如果成功:
对服务器的"打印"调用成功,数据为%s %字符串(数据)
定义完成(ign):
反应器。停止()
定义测试():
D1=获取页面( http://www。谷歌。com’)
d1.addCallback(pageCallback)
d2=getPage(http://yahoo.com )
d2.addCallback(pageCallback)
dl=DeferredList([d1,d2])
dl.addCallback(listCallback)
dl。增加回调(完成)
测试()
reactor.run()上一个例子的后续,这里我们把感兴趣的数据放入一个字典中。我们最终没有从字典中提取任何数据;我们只是把它字符串化并打印到标准输出。
示例5:向回调传递值
从扭曲的互联网导入反应器
从twisted.web.client导入获取页面
从twisted.internet.defer导入延迟列表
定义页面回调(结果,网址):
数据={
长度:len(结果),
内容:结果[:10],
url: url,
返回数据
def getPageData(url):
d=获取页面(网址)
addCallback(页面回调,网址)
返回d
定义列表回调(结果):
对于发布成功,结果中的数据:
如果成功:
对%s的打印调用成功,数据为%s % (data[url],str(data))
定义完成(ign):
反应器。停止()
定义测试():
D1=获取页面数据( http://www。谷歌。com’)
d2=getPageData(http://yahoo.com )
dl=DeferredList([d1,d2])
dl.addCallback(listCallback)
dl。增加回调(完成)
测试()
reactor.run()玩了这么多之后,我们开始问自己更严肃的问题,比如:"我想决定哪些值出现在我的回调中"或者"有些信息在这里可用,在那里不可用。我怎么去那里?"这就是如何把你想要的参数传递给你的回调函数。它们会在结果出来后被加上(正如你从函数签名中看到的)。
在这个例子中,我们需要创建自己的延迟返回函数,这个函数包装了获取页面函数,这样我们也可以将统一资源定位器传递给回调函数。
示例6:添加一些错误检查
从扭曲的互联网导入反应器
从twisted.web.client导入获取页面
从twisted.internet.defer导入延迟列表
URL=[
http://yahoo.com,
http://www.google.com,
http://www.google.com/MicrosoftRules.html,
http://bogusdomain.com,
定义页面回调(结果,网址):
数据={
长度:len(结果),
内容:结果[:10],
url: url,
返回数据
def pageErrback(错误,网址):
返回{
msg: error.getErrorMessage(),
错误:错误,
url: url,
def getPageData(url):
d=getPage(url,超时=5)
addCallback(页面回调,网址)
d.addErrback(pageErrback,url)
返回d
定义列表回调(结果):
对于忽略,结果中的数据:
if data.has_key(err ):
对%s的"打印"调用失败,返回数据%s % (data[url],str(data))
否则:
对%s的打印调用成功,数据为%s % (data[url],str(data))
定义完成(ign):
反应器。停止()
定义测试():
延期=[]
对于全球资源定位器(Uniform Resource Locator)中的网址:
d=获取页面数据(网址)
推迟编辑。追加(d)
dl=延迟列表(延迟,consumeErrors=1)
dl.addCallback(listCallback)
dl。增加回调(完成)
测试()
reactor.run()随着我们越来越接近构建真正的应用程序,我们开始关心诸如捕捉/预测错误之类的事情。我们没有在延迟列表中添加任何错误,但是我们在页面回调中添加了一个错误。我们添加了更多的URL,并将它们放在一个列表中,以减轻重复代码的痛苦。正如您所看到的,两个统一资源定位器应该返回错误:一个是404,另一个应该是一个没有解析的域(我们将这视为超时)。
示例7:使用推迟的载体进行批处理
从扭曲的互联网导入反应器
从twisted.web.client导入获取页面
从扭曲的互联网导入延迟
maxRun=1
URL=[
http://twistedmatrix.com,
http://twisted软件基金会。组织,
http://yahoo.com,
http://www.google.com,
定义列表回调(结果):
对于问题成功,导致结果:
打印镜头(结果)
定义完成(ign):
反应器。停止()
定义测试():
延期=[]
sem=延期。延迟信号(maxRun)
对于全球资源定位器(Uniform Resource Locator)中的网址:
d=sem.run(getPage,url)
推迟编辑。追加(d)
dl=延期。延期列表(延期)
dl.addCallback(listCallback)
dl。增加回调(完成)
测试()
reactor.run()最后两个例子是更高级的用例。一旦反应堆启动,准备好的延期装置就开始"点火"——它们的"工作"开始运行。如果我们的列表中有500个延期呢?嗯,他们都开始处理。可以想象,这是一种针对友好服务运行意外磁盘操作系统的简单方法。不酷。
对于这种情况,我们想要的是一次只运行这么多延迟的方法。这是延迟信号量的一个很好的用途。当我重复运行上面的例子时,大约2.5秒后返回四个页面的内容长度。将示例重写为只使用延迟列表(没有延迟信号量),大约1.2秒后返回内容长度。额外的时间是由于我(为了这个例子)一次只强制运行一个延迟,显然这不是您想要为高度并发的任务所做的
请注意,在不更改代码并且只将maxRun设置为四的情况下,获取内容长度的时间大致相同,平均为1.3秒(使用延迟信号量时,开销会多一点)。
最后一个微妙的注意事项(期待下一个例子):对于循环一次创建所有的延迟;延迟信号量只是限制了一次运行的信号量。
示例8:使用合作者进行节流
从扭曲的互联网导入反应器
从twisted.web.client导入获取页面
从扭曲的互联网导入延迟,任务
maxRun=2
URL=[
http://twistedmatrix.com,
http://twisted软件基金会。组织,
http://yahoo.com,
http://www.google.com,
定义页面回调(结果):
打印镜头(结果)
回送结果
def doWork():
对于全球资源定位器(Uniform Resource Locator)中的网址:
d=获取页面(网址)
addCallback(页面回调)
产量d
定义完成(ign):
反应器。停止()
定义测试():
延期=[]
coop=任务。合作者()
work=doWork()
对于xrange(最大行程)中的我:
d=coop.coiterate(工作)
推迟编辑。追加(d)
dl=延期。延期列表(延期)
dl.addCallback(完成)
测试()
reactor.run()原文出自http://欧比万。博格斯波特。com/2008/06/async-batching-with-twisted-walk through超文本标记语言
虽然现在很多人都说扭曲的人如其名,写的代码实在是太扭曲了,非正常人所能接受,虽然这个简单的例子看上去还好;每次写扭曲的的程序整个人都扭曲了,累得不得了,文档等于没有,必须得看源码才知道怎么整。不过我最近也想学习下这个框架,它对网络编程提供了很大的帮助,省去了很多的麻烦!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。