python多线程

目录

    • python可以用来干什么
    • 爬虫示例
    • Python多线程
        • 进程与线程
        • 开启线程

python可以用来干什么

  • 目录扫描:Web+多线程(requests+threading+Queue),后台、敏感文件(svn|upload)、敏感目录(phpmyadmin)。
  • 信息搜集:Web+数据库,中间件(Tomcat | Jboss)、C段Web信息、搜集特点程序。例如:搜索某个论坛上的所有邮箱,再进行攻击。
  • 信息匹配&SQL注入:Web+正则,抓取信息(用户名|邮箱)、SQL注入。
  • 反弹shell:通过添加代码获取Shell及网络信息。

爬虫示例

因为本文不是在于爬虫,算是对于学习爬虫的一个梳理 。
1.最简单的形式

import urllib.request
#python3.x是导入urllib2

response=urllib.request.urlopen('http://www.baidu.com')
print (response.read())

也是最核心的语句

2.构造request
urlopen的函数原型是 (python3.x)

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None) 
一般我们只需要用到url, data, timeout 这3个参数,所以我就干脆记成

urllib.request.urlopen(url, data=None, [timeout, ])

url: 需要打开的网址
data:需要提交的数据
timeout:设置网站的访问超时时间(好像单位是s)
data 和timeout参数可忽略。

>>> import urllib.request
>>> req=urllib.request.Request("http://www.baidu.com/")
>>> res=urllib.request.urlopen(req)
>>> print(res.read())

运行结果和上面是一样的,但是中间多了一个request对象。

3.get/post传递数据

get请求:和我们平时在浏览器中一样,在原来的url的基础上带上参数构造新的url访问即可。这里不做示例。
post请求:
上文说到的urlopen()函数中的data参数主要是在这里发挥作用
以登录某网站为例

import urllib.request
import urllib.parse

data = {"usename":"XXXX","passsword":"XXXX"}
data = parse.urlencode(data).encode('utf-8')  # 提交类型不能为str,需要为byte类型
req = urllib.request.Request("http://....")
res = urllib.urlopen(req,data)
print(res.read())

还有一种简单的发送get/post请求的方法

import requests

url = 'http://www.baidu.com/'
headers = {"User-Agent":"test request headers"}
params = {"key":"1"}
data = {'key1':'value1','key2':'value2'}

#get请求
res = requests.get(url)
#带参数和headers的get请求
res = requests.get(url,headers=headers,params=params) 

#post请求
res = requests.post(url,data=data)
#带headers
res = requests.post(url,headers=headers,data=data)

print(res.text)

Python多线程

进程与线程

由于单线程效率低,这里引入了多线程编程。
计算机的核心是CPU,它承担了所有的计算任务,它就像一座工厂,时刻运行着。假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务。
**进程就好比工厂的车间,它代表CPU所能处理的单个任务。**任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。一个车间里,可以有很多工人。他们协同完成一个任务。线程就好比车间里的工人,一个进程可以包括多个线程。

  • 线程可以被抢占(中断)。
  • 在其他线程正在运行时,线程可以暂时搁置(也称为睡眠) – 这就是线程的退让。

开启线程

Python3 线程中常用的两个模块为:

  • _thread
  • threading(推荐使用)

Python3 将 thread 重命名为 “_thread”。
Python中使用线程有两种方式:函数或者用类来包装线程对象。

1.函数式:调用 _thread 模块中的start_new_thread()函数来产生新线程。语法如下:

_thread.start_new_thread ( function, args[, kwargs] )
args - 传递给线程函数的参数,他必须是个tuple类型。
kwargs - 可选参数。

示例:

import _thread
import time

 def fun():
	print("Hello world!%s" %  time.ctime())

 def main():
	_thread.start_new_thread(fun,())#无参数
	_thread.start_new_thread(fun,())
	time.sleep(2)
	#使用这个方法时,一定要加time.sleep()函数,否则每个线程都可能不执行
	print("over")

	
 if __name__ == '__main__':
	main()

在这里插入图片描述
这个方法有个缺点是遇到较复杂的问题时,线程数不易控制。

2.我们可以通过直接从 threading.Thread 继承创建一个新的子类,并实例化后调用 start() 方法启动新线程,

import threading
import time
import sys 
#在多线程编程中,几个线程是同时启动,所以输出也是输出在一行,需要导入sys模块才能实现换行

def fun1(key):
    sys.stdout.write('hello %s:%s \n'%(key, time.ctime()))

def main():
    threads = []
    keys = ['a', 'b', 'c']

    #线程数
    threads_count = len(keys)

    for i in range(threads_count):
        t = threading.Thread(target=fun1,  args=(keys[i],))
        threads.append(t)#加入线程

    for i in range(threads_count):
        threads[i].start()

    for i in range(threads_count):
        threads[i].join()

if __name__ == '__main__':
    main()

运用多线程可以实现C段扫描,可以去看看Python攻防之多线程、C段扫描和数据库编程(二) (这一part的代码都是摘自这里)或python多线程 - bilibili白帽黑客教程
比如:

# -*- coding: utf-8 -*-
import thread
import time
from subprocess import Popen, PIPE
import sys

def ping_check(ip):
    check = Popen("ping {0} \n".format(ip), stdin=PIPE, stdout=PIPE, shell=True)
    data = check.stdout.read() #数据
    if 'TTL' in data: #存活
        sys.stdout.write('%s is UP \n' % ip)

#主函数
if __name__ == '__main__':
    #寻找目标 ichunqiu  1.31.128.240
    for i in range(1,255):
        ip = '1.31.128.' + str(i)
        #多线程方法
        thread.start_new_thread(ping_check, (ip, ))
        time.sleep(0.1)

你可能感兴趣的:(python,多线程)