相关模块:thread
相关函数:start_new_thread(调用的函数,函数里的参数)
#coding=utf-8
2018.1.8\import thread
import time
def fun1():
print "Hello World %s"%time.ctime()
def main():
thread.start_new_thread(fun1,())
thread.start_new_thread(fun1,())
time.sleep(2)
if __name__=="__main__":
main()
这里有几个点要提,thread调用的时间函数是在thread下所有的函数执行完成后才调用time.sleep(),如果在if下再次调用main(),那自然就是2s以后才会出现打印的信息;
#coding=utf-8
import thread
import time
import subprocess
def check_ping():
cmd="ping -c 2 -w 1 127.0.0.1"
check=subprocess.Popen(cmd,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
data=check.stdout.read()
print data
if __name__=="__main__":
check_ping()
subprocess是一个大类,里面有相关进程ping的函数,ping -c后面是ping的次数,-w后面是跟的时间间隔,时间之后就是目标地址,Popen和PIPE是subprocess下面的函数。
在Windows下ping会有一点问题
image
但是在Linux(ubuntu)下可以成功ping通
image
Python标准库
Python多线程
如果要检查主机是否存活,只需要在获取数据后检测ttl字段是否在数据中即可。
if "ttl" in data:
print "up"
知道了怎么ping一台主机并检查其是否存活,接下来就要检测一个C段上存活的主机数。\
这里以百度为例,先ping一下百度的ip地址:
image\
这里百度的ip就为:115.239.210.27
#coding=utf-8
import thread
import time
import subprocess
def check_ping(ip):
cmd="ping -c 2 -w 1 "+ip
check=subprocess.Popen(cmd,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
data=check.stdout.read()
if "ttl" in data:
print "%s is up"%(ip)
def main():
for i in range(1,255):
ip="115.239.210."+str(i)
thread.start_new_thread(check_ping,(ip,))
time.sleep(0.1)
#注意,使用多线程一定要使用time.sleep(),不然会出错
#check_ping(ip)
#如果直接调用函数而没有用多线程,是看不到效果的
if __name__=="__main__":
main()
至此,对thread模块有了一个初步的了解,但是thread模块有一个缺点,它不能控制线程数,所以下面要引入threading模块。
def fun1(key):
print "Hello %s:%s"%(key,time.ctime())
def main():
threads=[]
keys=['test1','test2','test3']
thread_cnt=len(keys)
for i in range(thread_cnt):
t=threading.Thread(target=fun1,args=(keys[i],))
threads.append(t)
print "test of t :%s"%t
image
打印出来的结果如图,t是thread下的线程。然后将线程加入到数组当中。
下面是完整的代码:
#coding=utf-8
import threading
import time
import subprocess
def fun1(key):
print "Hello %s:%s"%(key,time.ctime())
def main():
threads=[]
keys=['test1','test2','test3']
thread_cnt=len(keys)
for i in range(thread_cnt):
t=threading.Thread(target=fun1,args=(keys[i],))
threads.append(t)
for i in range(thread_cnt):
threads[i].start()
#启动线程
for i in range(thread_cnt):
threads[i].join()
#将多个线程合并为一个线程
if __name__=="__main__":
main()
扩展,如果同时使用多线程调用多个函数,代码如下:
#coding=utf-8
import threading
import time
import subprocess
def fun1(key):
print "Hello %s:%s"%(key,time.ctime())
def fun2(key):
print "Welcome %s:%s"%(key,time.ctime())
def main():
threads=[]
threads_=[]
keys=['test1','test2','test3']
thread_cnt=len(keys)
for i in range(thread_cnt):
t=threading.Thread(target=fun1,args=(keys[i],))
t_=threading.Thread(target=fun2,args=(keys[i],))
threads.append(t)
threads_.append(t_)
for i in range(thread_cnt):
threads[i].start()
threads_[i].start()
for i in range(thread_cnt):
threads[i].join()
threads_[i].join()
if __name__=="__main__":
main()
\
执行结果如图所示,一个进程紧随另一个进程,如果要先单独执行完一个进程,则把start和join分开写即可。
#coding=utf-8
import threading
import time
import requests
def fun1():
start_time=time.time()
r=requests.get(url="http://www.baidu.com")
cnt_time=time.time()-start_time
print "Status:%s--%s--%s--%s"%(r.status_code,start_time,cnt_time,time.strftime('%H:%M:%S'))
def main():
threads=[]
thread_cnt=5
for i in range(thread_cnt):
t=threading.Thread(target=fun1,args=())
threads.append(t)
for i in range(thread_cnt):
threads[i].start()
for i in range(thread_cnt):
threads[i].join()
if __name__=="__main__":
main()
运行结果如下所示:
\
由于这样打印的时间不太准确,所以使用系统自带的打印功能,代码修改后如下:
#coding=utf-8
import threading
import time
import requests
import sys
def fun1():
start_time=time.time()
r=requests.get(url="http://www.baidu.com")
cnt_time=time.time()-start_time
sys.stdout.write("Status:%s--%s--%s--%s\n"%(r.status_code,start_time,cnt_time,time.strftime('%H:%M:%S')))
def main():
threads=[]
thread_cnt=5
for i in range(thread_cnt):
t=threading.Thread(target=fun1,args=())
threads.append(t)
for i in range(thread_cnt):
threads[i].start()
for i in range(thread_cnt):
threads[i].join()
if __name__=="__main__":
main()
打印结果如下
image
Que模块的使用方法:
1.q=queue.put()把东西放进q里面;
2.q.get()相当于取出模块里的内容;
3.q.qsize()为当前队列的长度;
#coding=utf-8
import threading
import Queue
import subprocess
import sys
class DoRun(threading.Thread):
def __init__(self,queue):
threading.Thread.__init__(self)
self._queue=queue
def run(self):
while not self._queue.empty():
ip=self._queue.get()
cmd="ping -c 2 -w 1 %s"%(ip)
t=subprocess.Popen(cmd,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
data=t.stdout.read()
if "ttl" in data:
sys.stdout.write("%s is alive\n"%ip)
def main():
threads=[]
threads_cnt=20
q=Queue.Queue()
for i in range(1,255):
q.put("115.239.210."+str(i))
for i in range(threads_cnt):
threads.append(DoRun(q))
for i in range(threads_cnt):
threads[i].start()
for i in range(threads_cnt):
threads[i].join()
if __name__=="__main__":
main()
运行结果如下图所示:
image
关于类中self._queue进行相关解释:
用下划线作为变量名和方法名前缀和后缀来表示类的特殊成员。
* _xxx:这样的对象叫做保护成员,不能用”from module import “,只有类对象和子类对象能访问这些成员。
* xxx:系统定义的特殊成员。
* _xxx:类中私有成员,只有类对象自己能访问,子类对象也不能访问到这个成员,但在对象外部可以通过对象名.类名__xxx*这样的特殊方式访问。
关于DuRun类里面的run函数,为什么没有直接调用就可以就行调用了?
\
这里相当于重写了类里面的run函数;
最后给出一段帮助理解Python面向对象理解的代码:
#类定义
class people:
#定义基本属性
name = ''
age = 0
#定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
#定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s is speaking: I am %d years old" %(self.name,self.age))
p = people('tom',10,30)
p.speak()
代码引用于Python面向对象笔记CSDN博客
自己动手,丰衣足食,这里自己写了一个Python爬虫(没有使用多线程的版本)来爬取swust研究生院页面上的所有图片。
在学习的过程中遇到的问题:首先我是准备把i春秋上Web安全这一页上所有的课程图片爬下来的,i春秋设置了反爬虫机制,要带上headers,OK,带上以后重爬,遗憾的是爬下来的图片依然无法显示,反爬虫的机制很强…这里改爬本校研究生页面咯,代码如下:
#coding=utf-8
import urllib
import urllib2
import re
def get_page(url):
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0"}
page = urllib2.Request(url=url,headers=headers)
resp=urllib2.urlopen(page)
html = resp.read()
return html
def get_image(html):
reg =['src="(http.+?\.png)".*?alt','src="(http.+?\.jpg)".*?alt']
length=len(reg)
x = 0
for i in range(length):
imgre = re.compile(reg[i])
imglist = re.findall(imgre,html)
print imglist
for imgurl in imglist:
urllib.urlretrieve(imgurl,"E:/test_crawler/%s.jpg" % x)
#urllib下的urlretrieve()方法的基本用法是,urllib.urlretrieve(图片链接,“图片路径以及名称”)
x+=1
print "All done."
html = get_page("http://gs.swust.edu.cn")
get_image(html)
Python爬虫折腾了三天终于折腾出点东西来,还是很欣慰的,下一步争取使用多线程来实现爬虫。
#coding=utf-8
import urllib
import urllib2
import re
import Queue
import threading
class crawler_producer(threading.Thread):
def __init__(self,queue,reg):
threading.Thread.__init__(self)
self._queue=queue
self.reg=reg
def get_page(self):
url="http://gs.swust.edu.cn"
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0"}
page = urllib2.Request(url=url,headers=headers)
resp=urllib2.urlopen(page)
html = resp.read()
return html
def run(self):
global flag
reg =self.reg
length=len(reg)
x = 0
html=self.get_page()
for i in range(length):
imgre = re.compile(reg[i])
imglist = re.findall(imgre,html)
#print imglist
for imgurl in imglist:
urllib.urlretrieve(imgurl,"E:/test_crawler/%s.jpg" % x)
x+=1
def main():
threads=[]
q=Queue.Queue()
reg=['src="(http.+?\.png)".*?alt','src="(http.+?\.jpg)".*?alt']
threads_cnt=10
for i in range(len(reg)):
q.put(reg[i])
for i in range(threads_cnt):
threads.append(crawler_producer(q,reg))
for i in range(threads_cnt):
threads[i].start()
for i in range(threads_cnt):
threads[i].join()
if __name__=="__main__":
main()
print "All done."