目錄
一、Python黑客領域的現狀
二、Python正則運算式
2.1 正則運算式的介紹
2.2 正則運算式使用方法
2.3 貪婪模式和非貪婪模式
三、Python Web編程
3.1 urllib、urllib2、requests
3.1.1 urllib
3.1.2 urllib2
3.1.3 requests
3.2 爬蟲的介紹
3.3 利用python開發一個爬蟲
四、Python 多執行緒
4.1 執行緒和行程
4.1.1 執行緒和行程介紹
4.1.2 執行緒的創建步驟
4.1.3 通過執行緒類創建執行緒物件
4.1.4 執行緒創建與啟動的代碼
4.1.5 多執行緒完成多任務總結
4.2 thread模塊
4.3 threading模塊
4.3.1 Thread類
4.3.2 生產者 - 消費者問題和Queue模塊
4.4 執行緒執行帶有引數的任務
4.4.1 執行緒執行帶有引數的任務
4.4.2 args引數的使用
4.4.3 kwargs引數使用
4.4.4 執行緒執行帶有引數的任務代碼演示
4.5 主執行緒和子執行緒的結束順序
4.5.1 設定守護主執行緒
五、Python 多行程
5.1 多任務介紹
5.2 行程的介紹
5.3 多行程完成多任務
5.3.1 行程的創建步驟
5.3.2 通過行程類創建行程物件
5.3.3 行程創建與啟動的代碼
5.4 行程執行帶有引數的任務
5.4.1 行程執行帶有引數的任務
5.5 獲取行程編號
5.5.1 os.getpid()的使用
5.5.2 os.getppid()的使用
5.6 行程的注意點
5.6.1 主行程會等待所有子行程執行結束再結束
5.6.2 設定守護主執行緒
5.7 案例-多行程實作傳智教學視頻檔案夾多任務拷貝器
5.7.1 案例:需求分析
5.7.2 案例:實作步驟
5.7.3 案例:檔案拷貝函式實作步驟
5.7.4 程式:
六、Python 網路編程
6.1 C/S架構
6.2 套接字 - 通信端點
6.2.1 套接字介紹
6.2.2 socket模塊
6.2.3 套接字物件方法
6.3 python網路編程
七、Python 資料庫編程
7.1 Python DB API
7.2 Python Mysql開發環境
7.3 python資料庫編程實體
八、總結(python安全應用編程入門知識串講)
一、Python黑客領域的現狀
基于Python的平臺:Seebug、TangScan、BugScan等 ;
Python程式的廣度:進行蜜罐部署、WIFI中間人、快速把網頁內容轉pdf檔案腳本等(我們可以利用python開發出方方面面的程式);
python的深度:sqlmap注入神器、中間人攻擊神器mitmproxy/mitmdump等;
Python是跨平臺的!
為什么選擇python:
簡單易學、免費開源、高級語言、可移植、可擴展、可嵌入、豐富的擴展庫
學習基礎:
掌握python基礎知識(《python核心編程》),了解http協議、熟練使用BurpSuite,Sqlmap等工具
能學到什么:
python較為高級的用法;爬蟲的開發,多執行緒,網路編程,資料庫編程; Python hacker的應用;開發掃描器,爆破器,POC腳本
python就是一個能快速實作我們想法的編程語言!
python可以幫助我們做什么?
我們需要掌握:python正則運算式、python web編程、python多執行緒編程、python網路編程、python資料庫編程(排列組合就可以寫出很多有用的小工具哦!)
目錄掃描:
Web+多執行緒{requests+threading+Queue:[后臺 | 敏感檔案(syn|upload)| 敏感目錄(phpmyadmin)]}
資訊收集:
Web+資料庫{中間件(Tomcat|Jobss)+ C段WEB資訊+ 搜集特定程式}
資訊匹配&SQL注入:
Web+正則{抓取資訊(用戶名| 郵箱?)+SQL注入}
反彈Shell:
python網路編程
python在網路安全中的應用知識串講:
1、選擇一款自己使用舒服編輯器:我使用的是sublime text
2、至少看一本關于python的書籍
3、學會使用python自帶的功能,學習閱讀源代碼(base64模塊等)
4、閱讀官方檔案(docs.python.org)
5、多練習,刻意聯系
如何在sublime上運行python:
C:\Python27
C:\Users\mi\AppData\Local\Programs\Python\Python36
import base64
#print dir(base64)
#print help(base64)
#print base64.__file__ #回傳檔案所在位置:C:\Python27\lib\base64.pyc
#打開 C:\Python27\lib\base64.pyc查看
-------------------------------------------------------------------------------------------
print base64.b64encode('waffle') #base64編碼
二、Python正則運算式
2.1 正則運算式的介紹
使用單個字串來描述、匹配一系列符合某個句法規則的字串,簡單理解就是對字串的檢索匹配和處理,
2.2 正則運算式使用方法
Python通過re模塊提供對正則運算式的支持,
①先將正則運算式的字串形式編譯為Pattern實體;
②使用Pattern實體處理文本并獲得匹配結果;
③使用實體獲得資訊,進行其他的操作,
函式:
1、re.compile('佟麗婭') 編譯
2、pattern.match(msg) 只要頭沒有匹配成功就回傳None
3、re.search('佟麗婭',s) # search進行正則字串匹配方法,匹配的是整個字串
print(result) # <_sre.SRE_Match object; span=(2, 5), match='佟麗婭'> match是匹配的內容部分
print(result.span()) # 回傳位置 (2, 5)
4、result.group() # 佟麗婭 使用group來提取到匹配的內容部分
5、re.findall('[a-z][0-9][a-z]',msg) # findall 匹配整個字串,會找完所有的匹配的才會停止,一直到結尾
6、sub (類似replace) 將匹配的資料進行替換
sub(正則運算式,'新內容',string) 回傳的結果就是替換后的結果
7、split 切割
result=re.split(r'[,:]','java:99,python:95') 在字串中搜索,如果遇到冒號或逗號就分割一下,將分割內容保存到串列中
實體:
>>> import re
>>> pattern=re.compile('hello')
>>> match=pattern.match('hello world!')
>>> print(match)
<_sre.SRE_Match object; span=(0, 5), match='hello'>
>>> print(match.group())
hello
>>>
---------------------------------------------------
實際情況下,我們可以將第一步和第二步合并
>>> word=re.findall('hello','hello world!')
>>> word
['hello']
>>>
---------------------------------------------------
>>> word='http://www.ichunqiu.com python_1.1'
>>> key=re.findall('h.',word) # .是匹配除換行外的所有字符
>>> key
['ht', 'hu', 'ho']
>>> key=re.findall('\.',word) # \是轉義字符
>>> key
['.', '.', '.']
# [...]表示字符集,對應的位置可以是字符集中任意字符[abc]或[a-c],第一個字符是^表示取反,如[^abc],所有特殊字符在字符集都失去原有的特殊含義,在字符集中如果要使用、-或者^,可以在前面加上反斜杠,
基礎知識:
python re模塊:提供正則
預定義字符集(可以寫在[...]中):
\A:表示從字串的開始處匹配
\Z:表示從字串的結束處匹配,如果存在換行,只匹配到換行前的結束字串,
\b:匹配一個單詞邊界,也就是指單詞和空格間的位置,例如, 'py\b' 可以匹配"python" 中的 'py',但不能匹配 "openpyxl" 中的 'py',
\B:匹配非單詞邊界, 'py\b' 可以匹配"openpyxl" 中的 'py',但不能匹配"python" 中的 'py',
\d:匹配任意數字,等價于 [0-9], digit
\D:匹配任意非數字字符,等價于 [^\d],not digit
\s:匹配任意空白字符,等價于 [\t\n\r\f], space
\S:匹配任意非空白字符,等價于 [^\s],
\w:匹配任意字母數字及下劃線,等價于[a-zA-Z0-9_],
\W:匹配任意非字母數字及下劃線,等價于[^\w]
\\:匹配原義的反斜杠\,
-----------------------------------------------------------------------------------------
字符:
‘.’用于匹配除換行符(\n)之外的所有字符,
‘^’用于匹配字串的開始,即行首,
‘$’用于匹配字串的末尾(末尾如果有換行符\n,就匹配\n前面的那個字符),即行尾,
-----------------------------------------------------------------------------------------
定義正則驗證次數(數量詞):
‘*’用于將前面的模式匹配0次或多次(貪婪模式,即盡可能多的匹配) >=0
‘+’用于將前面的模式匹配1次或多次(貪婪模式) >=1
‘?’用于將前面的模式匹配0次或1次(貪婪模式) 0 ,1
'{m}' 用于驗證將前面的模式匹配m次
'{m,}'用于驗證將前面的模式匹配m次或者多次 >=m
'{m,n}' 用于驗證將前面的模式匹配大于等于m次并且小于等于n次
-----------------------------------------------------------------------------------------
‘*?,+?,??’即上面三種特殊字符的非貪婪模式(盡可能少的匹配),
‘{m,n}’用于將前面的模式匹配m次到n次(貪婪模式),即最小匹配m次,最大匹配n次,
‘{m,n}?’即上面‘{m,n}’的非貪婪版本,
-----------------------------------------------------------------------------------------
邏輯、分組:
| : 代表左右運算式任意匹配一個,它總是先嘗試匹配左邊的運算式,一旦成功匹配則跳過右邊的運算式,如果|沒有包括在()中,則它的范圍是整個正則運算式,
(...): 被括起來的運算式將作為分組,從運算式左邊開始,每遇到一個分組的左括號,編號+1,分組運算式作為一個整體,可以后接數量詞,運算式中|僅在該組中有效,
(abc){2} ---->abcabc
a(123|456)c ----> a456c 或者 a123c
-----------------------------------------------------------------------------------------
‘\\’:'\'是轉義字符,在特殊字符前面加上\,特殊字符就失去了其所代表的含義,比如\+就僅僅代表加號+本身,
‘[]’用于標示一組字符,如果^是第一個字符,則標示的是一個補集,比如[0-9]表示所有的數字,[^0-9]表示除了數字外的字符,
‘|’比如A|B用于匹配A或B,
‘(...)’用于匹配括號中的模式,可以在字串中檢索或匹配我們所需要的內容,
2.3 貪婪模式和非貪婪模式
Python里數量詞默認是貪婪的(在少數語言里也可能是默認非貪婪),總是嘗試匹配盡可能多的字符;
非貪婪則相反,總是嘗試匹配盡可能少的字符,
在"*","?","+","{m,n}"后面加上?,使貪婪變成非貪婪,
實戰:提取i春秋官網課程名字
#coding=utf-8
import re
html='''
網頁的HTML代碼(觀察課程名稱附近代碼,找出相似點)
'''
title=re.findall(r'<p class="coursename" title="(.*?)" onclick',html)
for i in title:
print i
三、Python Web編程
這里的web編程并不是利用python開發web程式,而是指利用python與web進行互動,獲取web資訊,
無論是哪種語言與web進行互動,獲取web資訊,都是黑客必備的一項技能
3.1 urllib、urllib2、requests
urllib、urllib2是python自帶的兩個web編程相關的庫,他們長相相似,使用方法也有很大的相同,都是利用urlopen這個方法對物件發起請求
3.1.1 urllib
1、urllib.urlopen()
2、urllib.urlretrieve() [retrieve:取回;找回;檢索資料]
urlretrieve(url,filename=None,reporthook=None,data=None)
例如下載百度圖片:https://www.baidu.com/img/bd_logo1.png
>>> import urllib,urllib2
>>> urllib.urlretrieve('https://www.baidu.com/img/bd_logo1.png',filename='/tmp/baidu.png')
('/tmp/baidu.png', <httplib.HTTPMessage instance at 0x7fb477c2d1e0>)
>>>
3.1.2 urllib2
1、urllib2.urlopen()
2、urllib2.Requests()
注:urllib和urllib2雖然雖然長的十分類似,但是他們是不可以相互代替的,他們都有各自獨一無二的方法,其中最主要的兩點:
urllib2有requests方法,它用來定制請求頭
urllib有urlretrieve方法,它用來下載檔案
舉例:
>>> import urllib,urllib2
>>> url='http://www.baidu.com'
>>> r=urllib.urlopen(url) # 用urllib向百度這個地址發起請求
>>> print r.read() # 查看請求之后回傳的內容、
----------------------------------------------
>>> r=urllib2.urlopen(url) #使用urllib2也能回傳同樣的內容
>>> print r.read()
瀏覽器向百度發送請求后查看網頁源代碼:
3.1.3 requests
requests是第三方庫,需要自己安裝
>>> import requests
>>> r=requests.get('https://www.baidu.com')
>>> print r.text #回傳回應內容
>>> print r.content #回傳二進制的回應內容
>>> print r.status_code #回傳狀態碼
200
>>> print r.headers #回傳請求頭
>>> print r.cookies #回傳cookies
<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
>>> r=requests.get('https://www.baidu.com',timeout=0.1) # 設定超時(在爬蟲中有用)
3.2 爬蟲的介紹
網路爬蟲(又被稱為網頁蜘蛛,網路機器人,更經常的稱為網頁追逐者),是一種按照一定規則,自動的抓取萬維網資訊的程式或者腳本,(各大搜索引擎說白了就是一個大的爬蟲)
用爬蟲最大的好處是批量且自動化的獲取和處理資訊,對于宏觀或者微觀的情況都可以多一個側面去了解,
黑客使用爬蟲,最常見的就是我們可以進行目錄掃描,搜索測驗頁面,手冊檔案,搜索管理員的登錄界面等,我們可以利用爬蟲開發web的漏洞掃描,像綠盟的漏掃,
3.3 利用python開發一個爬蟲
實體:用爬蟲獲取ichunqiu網站課程的名稱
我們依次訪問i春秋網站第1,2,3頁面,用burpsuite抓取
我們看看用python如何爬下這些課程內容,我們以第一頁為例:
訪問:https://www.ichunqiu.com/courses/ajaxCourses?courseTag=&courseDiffcuty=&IsExp=&producerId=&orderField=2&orderDirection=2&pageIndex=1&tagType=&isOpen=1:
回傳內容和python運行結果不一致,把header加上:
#coding=utf-8
import requests
#import re #用不到
import json
url='https://www.ichunqiu.com/courses/ajaxCourses?courseTag=&courseDiffcuty=&IsExp=&producerId=&orderField=2&orderDirection=2&pageIndex=1&tagType=&isOpen=1'
headers={
'Host': 'www.ichunqiu.com', #注意要加單引號和逗號分隔!
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With':'XMLHttpRequest',
'Referer': 'https://www.ichunqiu.com/courses/open-no?sort=2'
} #有防爬機制的網站都可以這樣處理
r=requests.get(url=url,headers=headers) #給網站發起請求
print(r.text)
data=json.loads(r.text)
name_long=len(data['result'])
#print data['result'][0]['courseName']
for i in range(name_long):
print data['result'][i]['courseName']
我們知道這些資料是通過json回傳的,鍵值如下:
上面我們只獲取了一頁的課程名稱,如果我們要獲取所有課程怎么做呢?
演示:
#coding=utf-8
import requests
import json
#url='https://www.ichunqiu.com/courses/ajaxCourses?courseTag=&courseDiffcuty=&IsExp=&producerId=&orderField=2&orderDirection=2&pageIndex=1&tagType=&isOpen=1'
url_start='https://www.ichunqiu.com/courses/ajaxCourses?courseTag=&pageIndex='
def lesson(url):
headers={
'Host': 'www.ichunqiu.com',
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With':'XMLHttpRequest',
'Referer': 'https://www.ichunqiu.com/courses/open-no?sort=2'
} #有防爬機制的網站都可以這樣處理
r=requests.get(url=url,headers=headers) #給網站發起請求
print(r.text)
data=json.loads(r.text)
# json.load()是用來讀取檔案的,即,將檔案打開然后就可以直接讀取
# json.loads()是用來讀取字串的,即,可以把檔案打開,用readline()讀取一行,然后json.loads()一行,
name_long=len(data['result'])
#print data['result'][0]['courseName']
for i in range(name_long):
print data['result'][i]['courseName']
for i in range(1,9): #有8頁
url=url_start+str(i)+'courseDiffcuty=&IsExp=&producerId=&orderField=2&orderDirection=2&tagType=&isOpen=1'
lesson(url)
上面代碼就可以獲得i春秋網站所有課程名稱!
練習網站:
爬蟲萌新:http://www.heibanke.com/lesson/crawler_ex00/
爬蟲熟手:http://glidedsky.com/
全年齡段的爬蟲愛好者:http://www.pythonchallenge.com/(腦洞)
四、Python 多執行緒
4.1 執行緒和行程
4.1.1 執行緒和行程介紹
行程:行程是程式的一次執行,每個行程都有自己的地址空間、記憶體、資料堆疊及其他記錄其運行軌跡的輔助資料,(程式就是磁盤中可執行的一些資料,只他們運行了,他們才被賦予了生命),每一個行程之間是相互獨立的,他們通過一些協議才可以相互訪問,如果說一個行程能訪問到超過自己分配記憶體的區域,也就產生了溢位,
執行緒:所有的執行緒運行在一個行程當中,共享相同的運行環境,執行緒有開始順序執行和結束三個部分,行程包括了執行緒,許多執行緒結合在一起,輔助協同作業,從而完成行程分配給他們的任務,
在python使用多行程的時候,一定是要有多核CPU的支持,但是python的多行程對windows系統支持并不是很好,所以我們往往使用多執行緒來加速我們的處理,
多執行緒是python程式實作多任務的一種方式,執行緒是程式執行的最小單位,同屬一個行程的多個執行緒共享行程所擁有的全部資源,
4.1.2 執行緒的創建步驟
1、匯入執行緒模塊 import threading
2、通過執行緒類創建執行緒物件
執行緒物件 = threading.Thread(target=任務名)
3、啟動執行緒物件:執行緒物件.start()
4.1.3 通過執行緒類創建執行緒物件
執行緒物件 = threading.Thread(target=任務名)
引數名 | 說明 |
target | 執行的目標任務名,這里指的是函式名(方法名) |
name | 執行緒名,一般不用設定(創建執行緒時自己取的名字) |
group | 執行緒組,目前只能使用None |
4.1.4 執行緒創建與啟動的代碼
使用單任務:
#!/usr/bin/env python
# coding=utf-8
import time
def sing():
for i in range(3):
print "唱歌..."
time.sleep(1)
def dance():
for i in range(3):
print "跳舞..."
time.sleep(1)
# 下面用單任務執行一下
if __name__ == '__main__':
sing()
dance()
使用多任務改進: (提高效率)
#!/usr/bin/env python
# coding=utf-8
import time
import threading
def sing():
for i in range(3):
print "唱歌..."
time.sleep(1)
def dance():
for i in range(3):
print "跳舞..."
time.sleep(1)
# 下面用多任務執行一下
if __name__ == '__main__':
# 創建執行緒物件,并且希望他啟動之后執行唱歌的函式
sing_thread=threading.Thread(target=sing)
#創建執行緒物件,并且希望他啟動之后執行跳舞的函式
dance_thread=threading.Thread(target=dance)
# 啟動執行緒
sing_thread.start()
dance_thread.start()
4.1.5 多執行緒完成多任務總結
- 匯入執行緒模塊:import threading
- 創建子行程并指定執行任務:sub_thread=threading.Thread(target=任務名)
- 啟動執行緒執行任務:sub_thread.start()
4.2 thread模塊
start_new_thread(function,args kwargs=None) //派生一個新的執行緒,給定agrs和kwargs來執行function
thread.start_new_thread ( function, args[, kwargs] )
引數說明:
該方法的第一個引數 function 表示要執行的函式,如上面定義的函式名,該函式將作為執行緒的入口函式使用,args 和kwargs是該函式的引數,args是必須的,型別是元組;kwargs是可選的,型別是字典,
產生一個新的執行緒,在新的執行緒中用指定的引數和可選的kwargs來呼叫這個函式
注意:使用這種方法的時候,一定要加time.sleep(),否則每個執行緒將可能不執行,
此方法還有一個缺點,遇到較復雜問題的時候,執行緒數不易控制,
#coding=utf-8
import thread
import time
def func1():
print "hello world! %s"%time.ctime()
# 當我們要使用多執行緒的方法讓函式多次運行:
def main():
thread.start_new_thread(func1,())
thread.start_new_thread(func1,())
time.sleep(2)
if __name__== '__main__':
main()
現在要對所有C段的機器進行探測,看它是否存活:
#coding=utf-8
#現在要對所有C段的機器進行探測,看它是否存活:
import thread
import time
from subprocess import Popen,PIPE #用這個模塊來執行系統命令
def ping_check(ip):
check=Popen(['/bin/bash','-c','ping -c 2 '+ip],stdin=PIPE,stdout=PIPE)
data = check.stdout.read()
if 'ttl' in data:
print '%s is UP'% ip
# popen 打開行程檔案指標
#pipe管道的意思 subprocess子行程
#stdout 標準輸出
# stdin 標準輸入
def main():
for i in range(1,255):
ip='116.211.155.'+str(i) # 1-254
thread.start_new_thread(ping_check,(ip,))
time.sleep(0.1)
if __name__== '__main__': #呼叫主函式
main()
4.3 threading模塊
4.3.1 Thread類
a)使用threading模塊
b)子類化Thread類
解決了執行緒數可控的問題!
#coding=utf-8
import threading
import time
def fun1(key):
print "hello %s:%s"%(key,time.ctime()) #time.ctime列印當前時間
def main():
threads=[]
keys=['zhangsan','lisi','wangmazi']
threads_count=len(keys)
for i in range(threads_count): # 檢查腳本的名稱是threading.py,懷疑是與模塊名稱沖突,導致加載錯誤,換一個名字
t=threading.Thread(target=fun1,args=(keys[i],)) # 第一個引數是執行緒函式變數,第二個引數args是一個陣列變數引數,如果只傳遞一個值,就只需要i, 如果需要傳遞多個引數,那么還可以繼續傳遞下去其他的引數,其中的逗號不能少,少了就不是陣列了,就會出錯
threads.append(t)
for i in range(threads_count):
threads[i].start() # 告訴作業系統開一個執行緒
for i in range(threads_count):
threads[i].join() # Thread 的 join() 方法,可以阻塞自身所在的執行緒
if __name__== '__main__': #呼叫主函式
main()
想在很短的時間內訪問baidu:
#coding=utf-8
import threading
import time
import requests
import sys
def fun1():
time_start=time.time() #訪問百度的時間 time.time()回傳當前時間的時間戳(1970紀元后經過的浮點秒數),
r=requests.get(url='http://www.baidu.com')
times=time.time()-time_start # 計算出所有的訪問時間
sys.stdout.write('status:%s----%s---%s\n'%(r.status_code,times,time.strftime('%H:%M:%S'))) # 列印狀態碼、訪問時間,當地時間
def main():
threads=[]
threads_count=10 # 定義執行緒數 10 同時對baidu訪問十次,列印他回傳的一些資料
for i in range(threads_count): # 檢查腳本的名稱是threading.py,懷疑是與模塊名稱沖突,導致加載錯誤,換一個名字
t=threading.Thread(target=fun1,args=()) # 第一個引數是執行緒函式變數,第二個引數args是一個陣列變數引數,如果只傳遞一個值,就只需要i, 如果需要傳遞多個引數,那么還可以繼續傳遞下去其他的引數,其中的逗號不能少,少了就不是陣列了,就會出錯
threads.append(t)
for i in range(threads_count):
threads[i].start() # 告訴作業系統開一個執行緒
for i in range(threads_count):
threads[i].join() # Thread 的 join() 方法,可以阻塞自身所在的執行緒
if __name__== '__main__': #呼叫主函式
main()
4.3.2 生產者 - 消費者問題和Queue模塊
a)Queue模塊( qsize(), empty(), full(), put(), get() )
b) 完美搭檔,Queue + Thread
解決了生產引數和計算結果時間都不確定的問題!
案例:多執行緒對C段進行ping檢測
#coding=utf-8
import threading
import Queue
from subprocess import Popen,PIPE
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()
print ip
check_ping=Popen(['/bin/bash','-c','ping -c 2 '+ip],stdin=PIPE,stdout=PIPE)
data = check_ping.stdout.read()
if 'ttl' in data:
sys.stdout.write(ip+ ' is UP\n') # 使用sys以比較友好的方式對我們結果進行列印
def main():
threads=[]
threads_count=100
queue=Queue.Queue()
for i in range(1,255):
queue.put('116.211.155.'+str(i))
for i in range(threads_count):
threads.append(DoRun(queue))
for i in threads:
i.start()
for i in threads:
i.join()
if __name__== '__main__': #呼叫主函式
main()
練習:使用爬蟲結合多執行緒的方式對ichunqiu,所有的課程進行爬取(http://www.ichunqiu.com/courses)
4.4 執行緒執行帶有引數的任務
4.4.1 執行緒執行帶有引數的任務
引數名 | 說明 |
args | 以元祖的方式給執行任務傳參 |
kwargs | 以字典的方式給執行任務傳參 |
4.4.2 args引數的使用
# target:執行緒執行的函式名
# args:表示以元祖方式給函式傳參
sing_thread = threading.Thread(target=sing,args=(3,)) # 唱歌三次
sing_thread.start()
4.4.3 kwargs引數使用
# target:執行緒執行的函式名
# kwargs:表示以字典方式給函式傳參
dance_thread = threading.Thread(target=dance,kwargs={'count':3}) # 跳舞三次
# 開啟執行緒
dance_thread.start()
4.4.4 執行緒執行帶有引數的任務代碼演示
#!/usr/bin/env python
# coding=utf-8
import time
import threading
def sing(num,name):
for i in range(num):
print name,":唱歌..."
time.sleep(1)
def dance(count):
for i in range(count):
print "跳舞..."
time.sleep(1)
if __name__ == '__main__':
# args:以元組的方式給執行任務傳遞引數
sing_thread=threading.Thread(target=sing,args=(3,"xiaoming"))
#kwargs:以字典方式
dance_thread=threading.Thread(target=dance,kwargs={'count':2})
# 啟動執行緒
sing_thread.start()
dance_thread.start()
元祖方式傳參要保證元素順序和引數順序一致,字典方式傳參要保證key和引數名保持一致!
4.5 主執行緒和子執行緒的結束順序
主執行緒會等待所有的子執行緒執行結束后主執行緒再結束,除非把它設定為守護主執行緒
#!/usr/bin/env python
# coding=utf-8
import time
import threading
def work():
for i in range(10):
print "working,,,"
time.sleep(0.2)
if __name__ == '__main__':
sub_thread = threading.Thread(target=work)
sub_thread.start()
#主執行緒等待1s,后結束
time.sleep(1)
print "主執行緒結束了,,,"
# 結論: 主執行緒會等待所有的子執行緒結束后再結束
下面我希望主執行緒一結束,子執行緒就能自動銷毀:
4.5.1 設定守護主執行緒
要想主執行緒不等待子執行緒執行完成可以設定守護主執行緒
#主執行緒結束時不想等待子執行緒結束再結束,可以設定子現場守護主執行緒
#1、threading.Thread(target=work,daemon=True)
#2、執行緒物件.setDaemon=True(setDaemon一定要在start之前)
#!/usr/bin/env python
# coding=utf-8
import time
import threading
# 設定守護主執行緒方式1: daemon=True 守護主執行緒
work_thread = threading.Thread(target=work,daemon=True)
# 設定主執行緒方式2
#work_thread.setDaemon(True)
work_thread.start()
# 主執行緒延時1s
time.sleep(1)
print "over!"
五、Python 多行程
5.1 多任務介紹
5.1.1 電腦中的多任務:
5.1.2 多任務的優勢:
多任務的最大好處是充分利用CPU資源,提高程式的執行效率,
多任務是指在同一時間內執行多個任務,
5.1.3 多任務的兩種表現形式:
- 并發:在一段時間內交替去執行多個任務
例子:對于單核CPU處理多任務,作業系統輪流讓各個任務交替執行,由于交替的速度非常快,所以我們認為他們一起在運行,
- 并行:在一段時間內真正同時一起執行多個任務,
例子:對于多核CPU處理多任務,作業系統會給CPU的每個內核安排一個執行的任務,多個內核是真正的一起同時執行多個任務,這里需要注意多核CPU是并行的執行多任務,始終有多個任務一起執行,(并行:任務數量小于或等于CPU的核心數)
5.2 行程的介紹
5.2.1 程式中實作多任務的方式
在python語言中,想要實作多任務可以使用多行程來完成,
5.2.2 行程的概念
行程是資源分配的最小單位,它是作業系統進行資源分配和調度運行的基本單位,通俗理解:一個正在運行的程式就是一個行程,例如:正在運行的QQ,微信等,他們都是一個行程,(一個沒運行的程式就是一個程式),一個程式運行后至少有一個行程,
5.2.3 多行程的作用
5.3 多行程完成多任務
5.3.1 行程的創建步驟
1、匯入行程包:import multiprocessing
2、通過行程類創建行程物件:行程物件=multiprocessing.Process()
3、啟動行程執行任務:行程物件.start()
5.3.2 通過行程類創建行程物件
行程物件=multiprocessing.Process(target=任務名)
引數名 | 說明 |
target | 執行的目標任務名,這里指的是函式名(方法名) |
name | 行程名,一般不用設定(系統會默認設定) |
group | 行程組,目前只能使用None |
5.3.3 行程創建與啟動的代碼
# 創建子行程
sing_process = multiprocessing.Process(target=sing)
# 創建子行程
dance_process = multiprocessing.Process(target=dance)
#啟動行程
sing_process.start()
dance_process.start()
單任務:
import time
# 唱歌
def sing():
for i in range(3):
print "singing..."
time.sleep(0.5)
# 跳舞
def dance():
for i in range(3):
print "dancing..."
time.sleep(0.5)
if __name__='__main__':
sing()
dance()
使用多行程實作多任務:
# 1、匯入行程包
import time
import multiprocessing
# 唱歌
def sing():
for i in range(3):
print "singing..."
time.sleep(0.5)
# 跳舞
def dance():
for i in range(3):
print "dancing..."
time.sleep(0.5)
if __name__='__main__':
# 2、使用行程類創建行程物件
sing_process=multiprocessing.Process(target=sing)
dance_process=multiprocessing.Process(target=dance)
# 3、使用行程物件啟動行程執行指定任務
sing_process.start()
dance_process.start()
5.4 行程執行帶有引數的任務
5.4.1 行程執行帶有引數的任務
引數名 | 說明 |
args | 以元祖的方式給執行任務傳參 |
kwargs | 以字典的方式給執行任務傳參 |
通多執行緒操作一樣,不再演示,
5.5 獲取行程編號
行程編號的作用:
當程式中行程的數量越來越多的時候,如果沒有辦法區分主執行緒和子執行緒還有不同的子執行緒,那么就無法進行有效的行程管理,為了方便管理實際上每個行程都是有自己的編號的,
獲取行程編號的兩種方式:
1、獲取當前行程編號
os.getpid()
2、獲取當前父行程編號
os.getppid()
5.5.1 os.getpid()的使用
import os
pid=os.getpid()
print(pid)
5.5.2 os.getppid()的使用
def work():
#獲取當前行程編號
print("work行程編號:",os.getpid())
#獲取父行程的編號
print("work父行程編號:",os.getppid())
5.6 行程的注意點
5.6.1 主行程會等待所有子行程執行結束再結束
5.6.2 設定守護主執行緒
行程物件.daemon = True
設定守護主行程,主行程退出后子行程直接銷毀,不再執行子行程中的代碼,
5.7 案例-多行程實作傳智教學視頻檔案夾多任務拷貝器
5.7.1 案例:需求分析
①目標檔案夾是否存在,如果不存在就創建,如果存在則不創建
②遍歷源檔案夾中所有檔案,并拷貝到目標檔案夾
③使用行程實作多任務,完成高并發,完成高并發拷貝
5.7.2 案例:實作步驟
1、定義源檔案夾所在路徑,目標檔案夾所在路徑
# 1、定義源檔案目錄和目標檔案夾的目錄
source_dir="python教學視頻"
dest_dir="/home/python/桌面/test"
2、創建目標檔案夾
try:
# 2.創建目標檔案夾目錄
os.mkdir(dest_dir)
except:
print("目標檔案夾已經存在,未創建~)
3、通過os.listdir獲取源目錄中的檔案串列
# 3、串列得到所有源檔案中的檔案
file_list = os.listdir(source_dir)
print(file_list)
4、遍歷每個檔案,定義一個函式,專門實作檔案拷貝
# 4、for回圈,依次拷貝每個檔案夾
for file_name in file_list:
copy_work(filename, source_dir, dest_dir)
5、采用行程實作多任務,完成高并發拷貝
# 4、for回圈,依次拷貝每個檔案夾
for file_name in file_list:
#copy_work(filename, source_dir, dest_dir)
sub_process = multiprocessing.Process(target=copy_work,args=(file_name,source_dir,dest_dir))
sub_process.start()
5.7.3 案例:檔案拷貝函式實作步驟
1、拼接源檔案和目標檔案所在的路徑
def copy_work(file_name,source_dir,dest_dir):
#拼接路徑
source_path = source_dir+"/" + file_name
dest_path = dest_dir + "/" + file_name
2、打開源檔案、創建目標檔案
def copy_work(file_name,souce_dir,dest_dir):
#拼接路徑
source_path = source_dir+"/" + file_name
dest_path = dest_dir + "/" + file_name
print(source_path,"----->",dest_path)
#打開源檔案、創建目標檔案
with open(source_path,"rb") as source_file:
with open(dest_path,"wb") as dest_file:
3、讀取源檔案的內容并且寫入到目標檔案中(回圈)
def copy_work(file_name,souce_dir,dest_dir):
......
while True:
#回圈讀取資料
file_data=source_file.read(1024)
if file_data:
#回圈寫入到目標檔案
dest_file.write(file_data)
else:
break
5.7.4 程式:
import os
def copy_work(file_name,souce_dir,dest_dir):
#拼接路徑
source_path = source_dir+"/" + file_name
dest_path = dest_dir + "/" + file_name
print(source_path,"----->",dest_path)
#打開源檔案、創建目標檔案
with open(source_path,"rb") as source_file:
with open(dest_path,"wb") as dest_file:
while True:
#回圈讀取資料
file_data=source_file.read(1024)
if file_data:
#回圈寫入到目標檔案
dest_file.write(file_data)
else:
break
if __name__== '__main__':
#定義源檔案夾和目標檔案夾
source_dir="python教學視頻"
dest_dir="/home/python/桌面/test"
#創建目標檔案夾
try:
os.mkdir(dest_dir)
except:
print("目標檔案夾已經存在,未創建~)
#讀取源檔案夾的檔案串列
file_list = os.listdir(source_dir)
#遍歷檔案串列實作拷貝
#使用多行程實作多任務拷貝
for file_name in file_list:
sub_process = multiprocessing.Process(target=copy_file,args=(file_name,source_dir,dest_dir))
sub_process.start()
六、Python 網路編程
6.1 C/S架構
6.2 套接字 - 通信端點
6.2.1 套接字介紹
6.2.2 socket模塊
AF_INET是基于網路的套接字,SOCK_STREAM是基于tcp的資料傳輸
Linux 下的 socket() 函式:
int socket(int af, int type, int protocol);
1) af 為地址族(Address Family),也就是 IP 地址型別,常用的有 AF_INET 和 AF_INET6,AF 是“Address Family”的簡寫,INET是“Inetnet”的簡寫,AF_INET 表示 IPv4 地址,例如 127.0.0.1;AF_INET6 表示 IPv6 地址,例如 1030::C9B4:FF12:48AA:1A2B,
2)type 為資料傳輸方式/套接字型別,常用的有 SOCK_STREAM(流格式套接字/面向連接的套接字) 和 SOCK_DGRAM(資料報套接字/無連接的套接字)
3) protocol 表示傳輸協議,常用的有 IPPROTO_TCP 和 IPPTOTO_UDP,分別表示 TCP 傳輸協議和 UDP 傳輸協議
int tcp_socket = socket(AF_INET, SOCK_STREAM, 0); //創建TCP套接字 int udp_socket = socket(AF_INET, SOCK_DGRAM, 0); //創建UDP套接字
6.2.3 套接字物件方法
6.3 python網路編程
server.py:
#!/usr/bin/env python
#coding=utf-8
from socket import *
HOST='' # 我們如果用本機作為服務端的話,地址可以省略
PORT=2334 # 埠是int型的
BUFSIZE = 1024 #地址大小
ADDR=(HOST,PORT)
# 下面開始撰寫服務器端的代碼
tcpServer=socket(AF_INET,SOCK_STREAM) #AF_INET是基于網路的套接字,SOCK_STREAM是基于tcp的資料傳輸
#將地址系結到套接字上
tcpServer.bind(ADDR)
#讓服務端進行監聽
tcpServer.listen(5)
#接受客戶端向他發送的請求(下面代碼完成了服務器無線回圈,以及接受客戶端連接)
while True:
print 'waiting for connect...'
tcpClient,addr = tcpServer.accept() # 阻塞式等待連接到來
print '..connected from:',addr # 連接來自...的地址
#以下代碼完成通信的回圈,等待客戶端和服務端資料的一些互動
while True:
data=tcpClient.recv(BUFSIZE)
if not data:
break
tcpClient.send('[%s] %s'%(ctime(),data))
# 關閉連接!
tcpClient.close()
tcpServer.close()
client.py:
#!/usr/bin/env python
#coding=utf-8
from socket import *
from time import ctime
HOST='192.168.0.6' # 客戶端
PORT=2334 # 埠是int型的
BUFSIZE = 1024 #地址大小
ADDR=(HOST,PORT)
# 創建客戶端套接字
tcpClient=socket(AF_INET,SOCK_STREAM) #AF_INET是基于網路的套接字,SOCK_STREAM是基于tcp的資料傳輸
#將地址系結到套接字上
tcpClient.connect(ADDR)
#與服務端進行互動
while True:
data=raw_input('~:')
if not data:
break
tcpClient.send(data)
data=tcpClient.recv(BUFSIZE)
if not data:
break
print data
# 關閉連接!
tcpClient.close()
客戶機win10的地址是192.168.0.8,服務器端代碼在kali(192.168.0.6)下運行:
首先運行服務端代碼,開始監聽,再運行客戶端,
七、Python 資料庫編程
7.1 Python DB API
Python DB API包含內容:
Python DB API訪問資料庫流程:
7.2 Python Mysql開發環境
7.3 python資料庫編程實體
#!/usr/bin/env python
import MySQLdb
conn=MySQLdb.connect(
#10.211.55.9 3306 ichunqiu 123#@!
host='10.211.55.9',
port=3306,
user='ichunqiu',
passwd='123#@!',
)
cus=conn.cursor()
sql='select version()'
cus.execute(sql)
print cus.fetchone()
cus.close()
conn.close()
上面我們學過如何爬取ichunqiu所有課程名,那么我們能不能將這些資料匯入到資料庫中呢?
我們只要對那個程式添加一些資料庫的資訊程式代碼就可以成功將我們的資訊匯入資料庫:
#coding=utf-8
import requests
import json
#url='https://www.ichunqiu.com/courses/ajaxCourses?courseTag=&courseDiffcuty=&IsExp=&producerId=&orderField=2&orderDirection=2&pageIndex=1&tagType=&isOpen=1'
url_start='https://www.ichunqiu.com/courses/ajaxCourses?courseTag=&pageIndex='
def lesson(url):
headers={
'Host': 'www.ichunqiu.com',
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With':'XMLHttpRequest',
'Referer': 'https://www.ichunqiu.com/courses/open-no?sort=2'
} #有防爬機制的網站都可以這樣處理
r=requests.get(url=url,headers=headers) #給網站發起請求
print(r.text)
data=json.loads(r.text)
# json.load()是用來讀取檔案的,即,將檔案打開然后就可以直接讀取
# json.loads()是用來讀取字串的,即,可以把檔案打開,用readline()讀取一行,然后json.loads()一行,
name_long=len(data['result'])
#print data['result'][0]['courseName']
for i in range(name_long):
#print data['result'][i]['courseName'],data[['result'][i]['produceName']
sql="insert into lessons (lesson_name,lesson_own) values('%s','%s')"%(data['result'][i]['courseName'].encode('utf-8'),data[['result'][i]['produceName'].encode('utf-8')) #phpmyadmin中設計好資料庫結構
cus.execute(sql)
conn=MySQLdb.connect(host='10.211.55.9',port=3306,user='ichunqiu',passwd='123#@!',db='ichunqiu')
cus=conn.cursor()
for i in range(1,9): #有8頁
url=url_start+str(i)+'courseDiffcuty=&IsExp=&producerId=&orderField=2&orderDirection=2&tagType=&isOpen=1'
lesson(url)
cus=conn.commit() # 一定要用commit,否則不會提交到資料庫,就不用cus.close()
#cus.close()
conn.close()
八、總結(python安全應用編程入門知識串講)
1、多練習,一定要善于發現感興趣的內容,通過所學知識去實作;
2、關注相關領域;
尋找大師,跟隨大師,與大師同行,洞察大師,成為大師
知乎,ve2x.com, github
3、擴展:
想要提高,就不能始終使用已有的東西(很多東西等待我們自己去學)
4、應用;
不要別人提需求,要根據自己的需求動手實作,達到目地安全
分析行為:通過日志,分析攻擊行為(re模塊)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/295567.html
標籤:其他
上一篇:政策解讀 | 杜絕“大資料殺熟” 《個人資訊保護法》來了
下一篇:Web安全之檔案上傳漏洞