想用装饰器给这个函数计算运行时间,为什么一直不对啊,刚学,下面的错误也看不懂,谢谢各位
from time import *
def time_master(func):
def time_(*args,**kwargs):
print("开始调用程序")
start=time()
func(*args,**kwargs)
stop=time()
print("结束调用,共用时{:.5f}".format(stop-start))
return time_
@time_master
def rabbit(m):
if m<4:
return m
else:
return rabbit(m-3)+rabbit(m-1)
print(rabbit(5))
错误显示
开始调用程序
开始调用程序
结束调用,共用时0.00000
开始调用程序
开始调用程序
结束调用,共用时0.00000
开始调用程序
结束调用,共用时0.00000
Traceback (most recent call last):
File "C:\Users\13113\Desktop\递归.py", line 40, in <module>
print(rabbit(5))
^^^^^^^^^
File "C:\Users\13113\Desktop\递归.py", line 29, in time_
func(*args,**kwargs)
File "C:\Users\13113\Desktop\递归.py", line 38, in rabbit
return rabbit(m-3)+rabbit(m-1)
^^^^^^^^^^^
File "C:\Users\13113\Desktop\递归.py", line 29, in time_
func(*args,**kwargs)
File "C:\Users\13113\Desktop\递归.py", line 38, in rabbit
return rabbit(m-3)+rabbit(m-1)
~~~~~~~~~~~^~~~~~~~~~~~
TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'
进程已结束,退出代码1
代码修改如下, 增加 return,返回函数的执行结果
import time
from time import *
def time_master(func):
def time_(*args, **kwargs):
print("开始调用程序")
start = time()
res = func(*args, **kwargs)
stop = time()
print("结束调用,共用时{:.10f}".format(stop - start))
return res
return time_
@time_master
def rabbit(m):
sleep(0.01)
if m < 4:
return m
else:
return rabbit(m - 3) + rabbit(m - 1)
print(rabbit(5))
大部分的数据都是直接写在静态文件上的,静态文件这里通常指的一定时间内不会变化的,不需要与后台进行交互的网页。
1.首先确认抓取的数据是否存在于响应文件中
2.分析页面结构,观察URL地址规律
1)查看网页元素的布局,整体结构预览,常用控制台来分析
2)查看在浏览网页(比如翻页)时元素结构是否发生变化
3)查看页面跳转时URL地址是否变化(判断是否发生请求转发或重定向),如果有则去JS代码中找变化的原因
3.开始编写代码进行数据抓取
4.开始写自己的第一个爬虫程序
Python爬虫入门,最简单的爬虫代码,网站如何判断是人为的操作还是爬虫程序的操作,为url参数中的中文参数进行编码,基于百度搜索的爬虫程序
做完上面的案例后,可以再做一个案例练练手。Python爬虫小程序,爬取百度贴吧网页文件,新手练手的好案例
5.多级页面爬取思路
上面两个案例都是爬取一级页面的,一级页面指的是打开某个网页,仅仅对该网页上的内容做数据爬取,而二级页面就是在一级页面的基础上,你点击一个内容,这个内容往往是一个连接,它带你来到了另一个页面,这就是二级页面。在做爬虫时一般是先下载一级页面,这个页面没有我们要爬的数据,但是它包含了存储我们要的数据的网站的链接,收集所有链接后,我们拥有了所有的二级页面,也就拥有了所有数据,这时候你再到二级页面去爬数据即可。有二级页面也有三级页面四级页面,但是原理都是一样的。
我们再来看看如何爬取二级页面的内容
Python爬虫,4567电影网电影信息爬取,二级页面处理方案
这一部分的数据不是存在响应内容中,而是存在Ajax的XML文件或者JS文件中,而且它随着你的操作而动态变化。
1.如果发现想要的内容不再响应文件中,大可能性是使用Ajax动态生成的
2.F12进入控制台抓包,刷新页面或执行某些行为,查看XHR异步加载的数据包内容
1)GET请求:查看Request Headers请求头,查看请求头是如何做的,是否需要伪装请求头。
查看Query String Paramters,查看请求参数,这些参数多包含在URL中
2)Post请求:查看Request Headers请求头,查看请求头是如何做的,是否需要伪装请求头。
查看FormData表单数据,看post发送请求时封装了哪些数据,这些数据哪些是动态的哪些是静态的,动态再进一步分析如何生成(主要通过分析JS代码)
3.观察查询参数或者Form表单数据规律,如果需要进行进一步抓包分析处理,应当去分析JS文件
4.使用request.get().json()获取json数据,利用列表或字典的方法提取数据
1.将待爬取的URL放入队列中
需要使用到的模块有:from queue import Queue
2.多个线程从队列中取出地址,调用requests模块获取文件
需要用到的模块有:from threading import Thread
3.在进行I/O读写的时候注意加锁
需要用到的模块有:from threading import Lock
4.调取队列url地址的两种写法
当队列值为空时,线程再去做请求会陷入阻塞,所以要为队列做判空操作或者加抛异常
方式一:判断队列是否为空,避免线程堵塞
while True:
if not q.empty():
url=q.get()
else:
break
方式二:超时抛异常
try:
url=q.get(block=True,timeout=5)
....
except Exception as e:
break
5.多线程争抢共同文件时的操作
多线程写入文件时不加线程锁会导致一系列问题
方法如下:
from threading import Lock
lock=Lock()
lock.acquire() #加锁
代码块
local.relase() #释放
案例:
Python多线程爬虫,腾讯招聘网职位爬取程序,Ajax异步数据爬取模板
此内容会在将来补上..
pythoy一般用于解析页面的模块用re、lxml+xpath、json,以下是用法
1.re
re通过正则表达式来获取想要得到的内容,核心在于如何编写正则表达式
python正则表达式re模块入门,贪婪匹配和非贪婪匹配,案例:猫眼电影TOP100信息提取
2.lxml+xpath
lxml+xpath是通过编写xpath,然后使用lxml来解析xpath进行匹配,需要知道xpath的规则(教程):
Python常用插件类举,lxml+Xpath实现爬虫,使用Xpath爬取链家二手房源信息
3.ajax/json
json一般是ajax动态数据,请求得到ajax响应内容后,将它json化,再进一步处理,如存库,存缓存
Python多线程爬虫,腾讯招聘网职位爬取程序,Ajax异步数据爬取模板
4.pyexecjs
要计算函数的运行时间,可以使用装饰器来实现。下面是解决该问题的步骤:
calculate_time
,该函数接受一个函数作为参数,并返回一个新的函数。wrapper
,用于包装原始函数。wrapper
函数内部,记录函数开始执行的时间。@calculate_time
装饰器。下面是具体的代码实现:
import time
def calculate_time(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
run_time = end_time - start_time
print(f"函数 {func.__name__} 运行时间为:{run_time} 秒")
return result
return wrapper
@calculate_time
def get_data(url):
# 函数的具体实现
pass
def main():
for i in range(1, 2):
url = "https://www.csflhjw.com/zhenghun/9.html?page={}".format(i)
html_data = get_data(url)
if __name__ == '__main__':
main()
document.save('demo.docx')
将上述代码插入到原始代码中,即可实现计算函数运行时间的功能。当 get_data
函数被调用时,装饰器 calculate_time
会自动计算函数的运行时间并打印出来。
应该是 time.now(), time()就是创建一个对象, 当然都是0了
才发现这个是计算函数每次运行时间啊...有佬知道这种递归函数怎么改成计算总时间的吗(还是装饰器)