① 如何用Python实现目录遍历
1. 基本实现
[root@localhost ~]# cat dirfile.py
import os
path='/tmp'
for dirpath,dirnames,filenames in os.walk(path):
for file in filenames:
fullpath=os.path.join(dirpath,file)
print fullpath
执行结果如下:
[root@localhost ~]# python dirfile.py
/tmp/yum.log
/tmp/pulse-3QSA3BbwpQ49/pid
/tmp/pulse-3QSA3BbwpQ49/native
/tmp/毁雀.esd-0/socket
2. 在上兄陵例的基础上传递羡余戚参数
import os,sys
path=sys.argv[1]
for dirpath,dirnames,filenames in os.walk(path):
for file in filenames:
fullpath=os.path.join(dirpath,file)
② Python 如何遍历服务器上所有同一类型的文件
例如:在C:\TDDOWNLOAD目录下有a.txt、b.txt两个文件,另有\sub1子文件夹,C:\TDDOWNLOAD\sub1下又有c.txt、d.txt两个文件。
1. os.walk
os.walk()返回一个三元素的tuple:当前路径、子文件夹名称、文件列表。
>>> import os
>>> def fun( path ):
... for root, dirs, files in os.walk( path ):
... for fn in files:
... print root, fn
...
>>> fun( r'C:\TDDOWNLOAD' )
C:\TDDOWNLOAD a.txt
C:\TDDOWNLOAD b.txt
C:\TDDOWNLOAD\sub1 c.txt
C:\TDDOWNLOAD\sub1 d.txt
>>>
2. glob.glob
glob.glob()只接受一个参数,这个参数既代有路径,又代有匹配模式,返回值为一个列表。注意,glob.glob()无法直接穿透子文件夹,需要自己处理:
>>> def fun( path ):
... for fn in glob.glob( path + os.sep + '*' ): # '*'代表匹配所有文件
... if os.path.isdir( fn ): # 如果结果为文件夹
... fun( fn ) # 递归
... else:
... print fn
...
>>> fun( r'C:\TDDOWNLOAD' )
C:\TDDOWNLOAD\a.txt
C:\TDDOWNLOAD\b.txt
C:\TDDOWNLOAD\sub1\c.txt
C:\TDDOWNLOAD\sub1\d.txt
>>>
'*'为匹配模式,代表匹配所有文件,只有这样才能将子文件夹查出来,以便递归深入,探查下一层的文件。
③ 纯 Python 写一个 Web 框架,就是这么简单
造轮子是最好的一种学习方式,本文尝试从0开始造个Python Web框架的轮子,我称它为 ToyWebF 。
本文操作环境为:MacOS,文中涉及的命令,请根据自己的系统进行替换。
ToyWebF的简单特性:
下面我们来实现这些特性。
首先,我们需要安装gunicorn,回忆一下Flask框架,该框架有内置的Web服务器,但不稳定,所以上线时通常会替换成uWSGI或gunicorn,这里不搞这个内置Web服务,直接使用gunicorn。
我们创建新的目录与Python虚拟环境,在该虚拟环境中安装gunicorn
在啥都没有的情况下,构建最简单的Web服务,在ToyWebF目录下,创建app.py与api.py文件,写入下面代码。
运行 gunicorn app:app 访问 http://127.0.0.1:8000 ,可以看见 Hello, World! ,但现在请求体中的参数在environ变量中,难以解析,我们返回的response也是bytes形式。
我们可以使用webob库,将environ中的数据转为Request对象,将需要返回的数据转为Response对象,处理起来更加直观方便,直接通过pip安装一下。
然后修改一下API类的 __call__方法 ,代码如下。
上述代码中,通过webob库的Request类将environ对象(请求的环境信息)转为容易处理的request,随后调用handle_request方法对request进行处理,处理的结果,通过response对象返回。
handle_request方法在ToyWebF中非常重要,它会匹配出某个路由对应的处理方法,然后调用该方法处理请求并将处理的结果返回,在解析handle_request前,需要先讨论路由注册实现,代码如下。
其实就是将路由和方法存到self.routes字典中,可以通过route装饰器的形式将路由和方法关联,也可以通过add_route方法关联,在app.py中使用一下。
因为url中可以存在变量,如 @app.route("/hello/{name}") ,所以在匹配时,需要进行解析,可以使用正则匹配的方式进行匹配,parse这个第三方库已经帮我们实现了相应的正则匹配逻辑,pip安装使用一下则可。
这里定义find_handler方法来实现对self.routes的遍历。
了解了路由与方法关联的原理后,就可以实现handle_request方法,该方法主要的路径就是根据路由调度对应的方法,代码如下。
在该方法中,首先实例化webob库的Response对象,然后通过self.find_handler方法获取此次请求路由对应的方法和对应的参数,比如。
它将返回hello方法对象和name参数,如果是 /hello/二两 ,那么name就是二两。
因为route装饰器可能装饰器的类对象,比如。
此时self.find_handler方法返回的hanler就是个类,但我们希望调用的是类中的get、post、delete等方法,所以需要一个简单的判断逻辑,通过inspect.isclass方法判断handler如果是类对象,那么就通过getattr方法获取类对象实例的中对应的请求方法。
如果类对象中没有该方法属性,则抛出该请求类型不被允许的错误,如果不是类对象或类对象中存在该方法属性,则直接调用则可。
此外,如果方法的路由并没有注册到self.routes中,即404的情况,定义了defalut_response方法返回其中内容,代码如下。
如果handle_request方法中调度的过程出现问题,则直接raise将错误抛出。
至此,一个最简单的web服务就编写完成了。
回顾Flask,Flask可以支持HTML、CSS、JavaScript等静态文件,利用模板语言,可以构建出简单但美观的Web应用,我们让TopWebF也支持这一功能,最终实现图中的网站,完美兼容静态文件。
Flask使用了jinja2作为其html模板引擎,ToyWebF同样使用jinja2,jinja2其实实现一种简单的DSL(领域内语言),让我们可以在HTML中通过特殊的语法改变HTML的结构,该项目非常值得研究学习。
首先 pip install jinja2 ,然后就可以使用它了,在ToyWebF项目目录中创建templates目录,以该目录作为默认的HTML文件根目录,代码如下。
首先利用jinja2的FileSystemLoader类将file system中的某个文件夹作为loader,然后初始化Environment。
在使用的过程中(即调用template方法),通过get_template方法获得具体的某个模板并通过render方法将对应的内容传递给模板中的变量。
这里我们不写前端代码,直接去互联网中下载模板,这里下载了Bootstrap提供的免费模板,可以自行去 https://startbootstrap.com/themes/freelancer/ 下载,下载完后,你会获得index.html以及对应的css、jss、img等文件,将index.html移动到ToyWebF/templates中并简单修改了一下,添加一些变量。
然后在app.py文件中为index.html定义路由以及需要的参数。
至此html文件的支持就完成了,但此时的html无法正常载入css和js,导致页面布局非常丑陋且交互无法使用。
接着就让ToyWebF支持css、js,首先在ToyWebF目录下创建static文件夹用于存放css、js或img等静态文件,随后直接将前面下载的模板,其中的静态文件复制到static中则可。
通过whitenoise第三方库,可以通过简单的几行代码让web框架支持css和js,不需要依赖nginx等服务,首先 pip install whitenoise ,随后修改API类的 __init__ 方法,代码如下。
其实就是通过WhiteNoise将self.wsgi_app方法包裹起来,在调用API的 __call__ 方法时,直接调用self.whitenoise。
此时,如果请求web服务获取css、js等静态资源,WhiteNoise会获取其内容并返回给client,它在背后会匹配静态资源在系统中对应的文件并将其读取返回。
至此,一开始的网页效果就实现好了。
web服务如果出现500时,默认会返回 internal server error ,这显得比较丑,为了让框架使用者可以自定义500时返回的错误,需要添加一些代码。
首先API初始化时,初始self.exception_handler对象并定义对应的方法添加自定义的错误
在handler_request方法进行请求调度时,调度的方法执行逻辑时报500,此时不再默认将错误抛出,而是先判断是否有自定义错误处理。
在app.py中,自定义错误返回方法,如下。
custom_exception_handler方法只返回自定义的一段话,你完全可以替换成美观的template。
我们可以实验性定义一个路由来看效果。
Web服务的中间件也可以理解成钩子,即在请求前可以对请求做一些处理或者返回Response前对Response做一下处理。
为了支持中间件,在TopWebF目录下创建middleware.py文件,在编写代码前,思考一下如何实现?
回顾一下现在请求的调度逻辑。
1.通过routes装饰器关联路由和方法 2.通过API.whitenoise处理 3.如果是请求API接口,那么会将参数传递给API.wsgi_app 4.API.wsgi_app最终会调用API.handle_request方法获取路由对应的方法并调用该方法执行相应的逻辑
如果希望在request前以及response后做相应的操作,那么其实就需要让逻辑在API.handle_request前后执行,看一下代码。
其中add方法会实例化Middleware对象,该对象会将当前的API类实例包裹起来。
Middleware.handle_request方法其实就是在self.app.handle_request前调用self.process_request方法处理request前的数据以及调用self.process_response处理response后的数据,而核心的调度逻辑,依旧交由API.handle_request方法进行处理。
这里的代码可能会让人感到疑惑, __call__ 方法和handle_request方法中都有self.app.handle_request(request),但其调用对象似乎不同?这个问题暂时放一下,先继续完善代码,然后再回来解释。
接着在api.py中为API创建middleware属性以及添加新中间件的方法。
随后,在app.py中,自定义一个简单的中间件,然后调用add_middleware方法将其添加。
定义好中间件后,在请求调度时,就需要使用中间件,为了兼容静态文件的情况,需要对css、js、ing文件的请求路径做一下兼容,在其路径中加上/static前缀
紧接着,修改API的 __call__ ,兼容中间件和静态文件,代码如下。
至此,中间件的逻辑就完成了。
但代码中依旧有疑惑,Middleware类中的 __call__ 方法和handle_request方法其调用的self.app到底是谁?
为了方便理解,这里一步步拆解。
如果没有添加新的中间件,那么请求的调度逻辑如下。
在没有添加中间件的情况下,self.app其实就是API本身,所以 middleware.__call__ 中的self.app.handle_request就是调用API.handle_request。
如果添加了新的中间件,如上述代码中添加了名为SimpleCustomMiddleware的中间件,此时的请求调度逻辑如下。
因为注册中间件时,Middleware.add方法替换了原始Middleware实例中的app对象,将其替换成了SimpleCustomMiddleware,而SimpleCustomMiddleware也有app对象,SimpleCustomMiddleware中的app对象,才是API类实例。
在请求调度的过程中,就会触发Middleware类的handle_request方法,该方法就会执行中间件相应的逻辑去处理request和response中的数据。
当然,你可以通过Middleware.add方法添加多个中间件,这就会构成栈式调用的效果,代码如下。
启动web服务后,其执行效果如下。
④ Python 遍历
a=[[1,2,3,4,-1],[21,23,34,45,1],[3,4,34,2,1]]
cl_num=-1
foriinrange(len(a)-1):
this_line=a[i][cl_num]
next_line=a[i+1][cl_num]
issame=(this_line==next_line)
ifissame:
print('第{0}行第{1}列与第{2}行第{1}列相等'.format(str(i),str(cl_num),str(i+1)))
else:
print('第{0}行第{1}列与第{2}行第{1}列不相等'.format(str(i),str(cl_num),str(i+1)))
#第0行第-1列与第1行第-1列不相等
#第1行第-1列与第2行第-1列相等
此为按你要求,比较相邻行的最后一列的值。
下次去stackoverflow上查答案或提问吧。
⑤ Python爬虫开发工程师
Python爬虫开发工程师,从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止。如果把整个互联网当成一个网站,那么网络蜘蛛就可以用这个原理把互联网上所有的网页都抓取下来。
网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),枝好是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁,自动索引,模拟程序或者蠕虫。爬虫就是自动遍历一个网站的网页,并把内容都下载下来
网络爬虫另外一些不常使用的名字还有蚂蚁,自动索引,模拟程序或者蠕虫。随着网络的迅速发展,万维网成为大量信息的载体,如何有效地提取并利用这些信息成为一个巨大的挑战。搜索引擎(SearchEngine),例如传统的通用搜索引擎AltaVista,Yahoo!和Google等,作为一个辅助人们检索信息的工具成为用户访问万维网的入口和指南。但是,这些通用性搜索引擎也存在着一定的局限性,如:
(1)不同领域、不同背景的用户往往具有不同的检索目的和需求,通用搜索引擎所返回的结果包含大量用户不关心的网页。
(2)通用搜索引擎的目标是尽芦数可能大的网络覆盖率,有限的搜索引擎服务器资源与无限的网络数据资源之间的矛盾将进一步加深。
(3)万维网数据形式的丰富和网络技术的不断发展,图片、数据库、音频、视频多媒体等不同数据大量出现,通用搜索引擎往往猛哗铅对这些信息含量密集且具有一定结构的数据无能为力,不能很好地发现和获取。
(4)通用搜索引擎大多提供基于关键字的检索,难以支持根据语义信息提出的查询。
为了解决上述问题,定向抓取相关网页资源的聚焦爬虫应运而生。聚焦爬虫是一个自动下载网页的程序,它根据既定的抓取目标,有选择的访问万维网上的网页与相关的链接,获取所需要的信息。与通用爬虫(general?purposewebcrawler)不同,聚焦爬虫并不追求大的覆盖,而将目标定为抓取与某一特定主题内容相关的网页,为面向主题的用户查询准备数据资源。
⑥ python怎样遍历.py的内容
列表的遍历
方法一:通过for循环
li = [i for i in range(10)]
for i in li:
print(i)
方法二:通过while循环
# 虽然for循环已经很好用了,但是在有些情况下,使用while循环可以更灵活
# 只需要将判断条件设置为小于列表长度,即可完成列表通过while循环的遍历
li = [i for i in range(10)]
i = 0
while i < len(li):
print(li[i])
i += 1
方法三:配合enumerate使用,同时获取列表的索引
li = [i + 1 for i in range(10)]
# 此时,i为一个元组,元组的第一个元素为索引,第二个元素为原列表的元素
# 因此,在遍历列表的同时,需要同时获取坐标的情况下,可以配合enumerate()一起使用
for i in enumerate(li):
print(i)
字典的遍历
字典的遍历和列表有一些不同,因为字典有键和值两个关键部分。默认的遍历情况,是遍历字典的键,当然,可以通过字典的键取得值,也可以直接遍历值,或者直接遍历键和值。
方法一:直接使用for循环
直接使用for循环对一个字典进行遍历,默认取得的是字典的键
dt = {i: i + 1 for i in range(10)}
for i in dt:
print("字典的键:", i) # 字典的键
print("字典的值:", dt[i]) # 字典的值
方法二:遍历dict.keys()
这种方法与方法一的效果其实是一样的,同样是获取字典的键
dt = {i: i + 1 for i in range(10)}
for i in dt.keys():
print("字典的键:", i) # 字典的键
print("字典的值:", dt[i]) # 字典的值
方法三:遍历dict.values()
这种方法与方法一和二很不相同,因为它只获取了字典的值
dt = {i: i + 1 for i in range(10)}
# 这是很特殊的方法,因为它没有获取字典的键
for i in dt.values():
print("字典的值:", i) # 此时i不再是字典的键,而是值
方法四:遍历dict.items()
这种方法一般来说要更好,因为它同时获取到了字典的键和值,而且性能上要高于先获取键,再通过键获取对应的值
dt = {i: i + 1 for i in range(10)}
for i in dt.items():
print("字典的键值对:", i)
print("字典的键:", i[0])
print("字典的值:", i[1])
总结
1,列表的遍历比较简单,除了配合enumerate()使用,可以同步获取索引以外,并没有特别值得纠结的。
2,字典的遍历方法比较多,其中第四种是能适用于一切情况的,前两种也可以适用于一切情况,但是如果你同时需要获取键和值,性能不如第四种要好。第三种比较特别,除非你真的只需要字典的值,否则它在多数情况下是不能够满足需求的。
⑦ python+selenium怎么遍历一个网页中class相同的值
获取标签内容
使用element.attribute()方法获取dom元素的谨睁凳内容,如:
dr = driver.find_element_by_id('tooltip')
dr.get_attribute('data-original-title') #获取tooltip的内容
dr.text #获取该链接的text
获取标签属性
link=dr.find_element_by_id('tooltip')
link.value_of_css_property('color') #获取tooltip的CSS属性color的属性值
link.find_element_by_tag_name('h3').value_of_css_property('font') #获取h3的CSS属性font的属性值
获取标签状态
是否显示:使用element.is_displayed()方法
是否存在:使用find_element_by_xxx()方法,捕获其抛出的异常, 如果存在异常的话则可以确定该元素不存在
text_field=dr.find_element_by_name('user').is_enabled()
#直接用element.is_enabled()方法判断button,返回值为true,因为祥旅button是使用CSS方法判断是否有效这并不是真正的早并方法,需要判断其class中是否有值为disabled来判断是否真正处于disabled的状态
dr.find_element_by_class_name('btn').is_enabled()
是否被选中:一般判断表单元素,如radio或checkbox是否被选中,使用element.is_selected()方法
radio.is_selected() #判断是否被选中
try:
dr.find_element_by_id('none')
except:
print 'element does not exist'
是否有效:即是否为灰化状态,使用element.is_enabled()状态
print text_field.is_displayed() #判断是否显示
⑧ python几种遍历复杂网站的方法原理是什么
python网络爬虫原理
互联网网页可以看成是一张超大图,每个网页是衫历一个节点,网页中指向其他网页的链接是边。那么,可以这样实现全网网页收集:以某一个网页为起点,下载并处理该网页,解析里面的链接,所得的URL加入下载队列。这个过程其实就是图的遍历过并塌蚂程,可以是深度优先或者广度优先遍历,取决于下载队列如何维护。简单地,网络爬虫可以由以绝埋下部分组成: 1、下载模块
⑨ 如何遍历所有的请求处理程序使用Python程序请求头
http-server能提供的环链唤境变量是有限的,一般是基于标准的cgi接口棚瞎凯实现,这样就难免会去除一些不常用到的信息。如果神大想获取完整头信息只能自己实现,或者是使用python实现的http-server。如webpy中就可以通过web.ctx.env访问header信息。
⑩ python中列表的遍历
没有优雅的方法解决,只有不要使用print语句,如楼上所说,或者使用python3.X中的print函数(通过
from __future__ import print_function使能print函数形式)
其实,在python2.X手册中对print语句描述说:(python2.7.2官方帮助文档)
一个空格会被自动打印在每个对象前,
除非:(1)还没有输出写到标准输出中
(2)当最后一个写到标准输出的是一个除了空格‘ ’的空白字符
(3)当最后写到标准输出的不是一个print语句。
所以在apple、banana等每个字符前都有一个空格。(apple的a前也有空格呢!)
一个好的解决办法是使用python3.X中的print函数。
通过在文件前面加上:
from __future__ import print_function
就手拆可以使用print的函数形式了。
print函数的语法:
print([object, ...][, sep=' '][, end='\n'][, file=sys.stdout])
默认下,毕运枣若没有指定sep,则使用空格。没指定end,则使用换悄桥行符。没指定输出文件则输出到标准输出。
例如:print('hello','world',sep='-',end='#')输出:
hello-world#
所以,你的程序可改为:
from __future__ import print_function
list = ["apple", "banana", "grape", "orange"]
for x in range(len(list)):
print('list[%d]:'%x,end='')
for y in range(len(list[x])):
print(list[x][y],sep='',end='')
print('')
至于: 'list[%d]:'%x 这里的百分号,是一个对字符串的操作符。百分号使得百分号前面的字符串中
的%d被百分号后的x的值替换掉。