1. 程式人生 > >Python常用內建模組——學習筆記

Python常用內建模組——學習筆記

1、datetime:Python處理日期和時間的標準庫 引入方法: from datetime import datetime 第一個datetime是模組,第二個datetime是類。 如果僅匯入import datetime,則必須引用全名datetime.datetime
  • 獲取當前日期和時間:datetime.now()
  • 加減當前時間:now + timedelta(days=2, hours=12)
datetime->timestamp:
>>> from datetime import datetime >>> dt = datetime(2015, 4, 19, 12, 20) # 用指定日期時間建立datetime
>>> dt.timestamp() # 把timestamp轉換為datetime1429417200.0       # Python的timestamp是一個浮點數。如果有小數位,小數位表示毫秒數。 某些程式語言(如Java和JavaScript)的timestamp使用整數表示毫秒數,這種情況下只需要把timestamp除以1000就得到Python的浮點表示方法。
datetime->str datetime->UTC時間 時區轉化 儲存datetime,最佳方法是將其轉換為timestamp再儲存,因為timestamp的值與時區完全無關。 2、collections
: Python內建的一個集合模組,提供了許多有用的集合類。
  • namedtuple: 建立一個自定義的tuple物件
>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(1, 2)
>>> p.x
1
  • deque: 為了高效實現插入和刪除操作的雙向列表,適合用於佇列和棧
>>> from collections import deque
>>> q = deque(['a', 'b', 'c'])
>>> q.append('x')
>>> q.appendleft('y')
>>> q
deque(['y', 'a', 'b', 'c', 'x']) >>> q.pop() >>> q deque(['y', 'a', 'b', 'c']) >>> q. popleft() >>> q deque([ 'a', 'b', 'c'])
  • defaultdict: 使用dict時,如果引用的Key不存在,就會丟擲KeyError。如果希望key不存在時,返回一個預設值,就可以用defaultdict
>>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'N/A')
>>> dd['key1'] = 'abc' >>> dd['key1'] # key1存在'abc' >>> dd['key2'] # key2不存在,返回預設值'N/A'
  • OrderedDict: 保持Key的順序,可以用OrderedDict(按插入序)。 OrderedDict可以實現一個FIFO(先進先出)的dict,當容量超出限制時,先刪除最早新增的Key
>>> from collections import OrderedDict
>>> d = dict([('a', 1), ('b', 2), ('c', 3)])
>>> d # dict的Key是無序的
{'a': 1, 'c': 3, 'b': 2}
>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> od # OrderedDict的Key是有序的
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
  • Counter:計數器,也是dict的子類,如統計字母出現的次數,類似於Wordcount
>>> from collections import Counter >>> c=Counter
>>> c('Programming')
Counter({'r': 2, 'm': 2, 'g': 2, 'P': 1, 'a': 1, 'o': 1, 'i': 1, 'n': 1})
3、base64 : 用64個字元來表示任意二進位制資料. Base64是一種任意二進位制到文字字串的編碼方法,常用於在URL、Cookie、網頁中傳輸少量二進位制資料。 4、struct: 解決bytes和其他二進位制資料型別的轉換。 Windows的點陣圖檔案(.bmp)是一種非常簡單的檔案格式,可以用struct分析出其檔案頭結構。 兩個位元組:'BM'表示Windows點陣圖,'BA'表示OS/2點陣圖; 一個4位元組整數:表示點陣圖大小; 一個4位元組整數:保留位,始終為0; 一個4位元組整數:實際影象的偏移量; 一個4位元組整數:Header的位元組數; 一個4位元組整數:影象寬度; 一個4位元組整數:影象高度; 一個2位元組整數:始終為1; 一個2位元組整數:顏色數。 通過分析點陣圖檔案的檔案頭結構,可以檢查任意檔案是否是點陣圖檔案
>>> struct.unpack('<ccIIIIIIHH', s) (b'B', b'M', 691256, 0, 54, 40, 640, 360, 1, 24)
5、hashlib:提供常見的摘要演算法,MD5,SHA1,SHA256,SHA512等 摘要演算法又稱雜湊演算法、雜湊演算法。它通過一個函式,把任意長度的資料轉換為一個長度固定的資料串(通常用16進位制的字串表示)。 目的是為了發現原始資料是否被人篡改過 。摘要演算法之所以能指出資料是否被篡改過,就是因為摘要函式是一個單向函式,計算f(data)很容易,但通過digest反推data卻非常困難。而且,對原始資料做一個bit的修改,都會導致計算出的摘要完全不同。也可以看成加密演算法。
import hashlib

md5 = hashlib.md5()
md5.update('how to use md5 in '.encode('utf-8'))
md5.update('python hashlib?'.encode('utf-8'))
print(md5.hexdigest())
注意:在pycharm上測試執行時,新建的.py檔名稱不要取hashlib,因為程式碼中需要import hashlib,如果檔名也是hashlib就會引入當前檔案(模組),從導致出現錯誤。 6、itertools: 提供用於操作迭代物件的函式
  • count()會建立一個無限的迭代器,count(1)從1開始的迭代器
for in itertools.count(1):
    print(n)
    if n==10:
        break
  • cycle()會把傳入的一個序列無限重複下去
for in itertools.cycle('abc'):
    print(c)
    i+=1
if i==10:
        break
  • repeat()負責把一個元素無限重複下去,不過如果提供第二個引數就可以限定重複次數
for in itertools.repeat('a',3):
    print(n)
  • chain()可以把一組迭代物件串聯起來,形成一個更大的迭代器:
for c in itertools.chain('ABC', 'XYZ'):        print(c)    # 迭代效果:'A' 'B' 'C' 'X' 'Y' 'Z'
  • groupby()把迭代器中相鄰的重複元素挑出來放在一起:
>>> for key, group in itertools.groupby('AAABBBCCAAA'):
...     print(key, list(group))
...
A ['A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
A ['A', 'A', 'A
小結: itertools模組提供的全部是處理迭代功能的函式,它們的返回值不是list,而是Iterator,只有用for迴圈迭代的時候才真正計算。 7、XML:Python解析XML
(DOM和SAX) DOM會把整個XML讀入記憶體,解析為樹,因此佔用記憶體大,解析慢,優點是可以任意遍歷樹的節點。SAX是流模式,邊讀邊解析,佔用記憶體小,解析快,缺點是我們需要自己處理事件。正常情況下,優先考慮SAX,因為DOM實在太佔記憶體。
  • Python利用SAX解析XML(關心的事件:start_elementend_elementchar_data):
from xml.parsers.expat import ParserCreate

class DefaultSaxHandler(object):
    def start_element(self, name, attrs):
        print('sax:start_element: %s, attrs: %s' % (name, str(attrs)))

    def end_element(self, name):
        print('sax:end_element: %s' % name)

    def char_data(self, text):
        print('sax:char_data: %s' % text)

xml = r'''<?xml version="1.0"?>
<ol>
    <li><a href="/python">Python</a></li>
    <li><a href="/ruby">Ruby</a></li>
</ol>
'''

handler = DefaultSaxHandler()
parser = ParserCreate()
parser.StartElementHandler = handler.start_element
parser.EndElementHandler = handler.end_element
parser.CharacterDataHandler = handler.char_data
parser.Parse(xml)
  • 生成XML:拼接字串、JSON
L = []   #list L.append(r'<?xml version="1.0"?>')
L.append(r'<root>')
L.append(encode('some & data'))
L.append(r'</root>')
return ''.join(L) #str
8、HTMLParser 編寫一個搜尋引擎:
  • 用爬蟲吧目標網站頁面抓下來
  • 解析該HTML頁面
from html.parser import HTMLParser
from html.entities import name2codepoint

class MyHTMLParser(HTMLParser):

    def handle_starttag(self, tag, attrs):
        print('<%s>' % tag)

    def handle_endtag(self, tag):
        print('</%s>' % tag)

    def handle_startendtag(self, tag, attrs):
        print('<%s/>' % tag)

    def handle_data(self, data):
        print(data)

    def handle_comment(self, data):
        print('<!--', data, '-->')
    def handle_entityref(self, name): #特殊字元         print('&%s;' % name)

    def handle_charref(self, name): #特殊字元
        print('&#%s;' % name)

parser = MyHTMLParser()
parser.feed('''<html>
<head></head>
<body>
<!-- test html parser -->
    <p>Some <a href=\"#\">html</a> HTML&nbsp;tutorial...<br>END</p>
</body></html>''')
9、urllib: 提供一系列用於操作URL的功能
  • Get(下載)
#模擬iPhone 6去請求豆瓣首頁 from urllib import request

req = request.Request('http://www.douban.com/') req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25') #不新增該header時,表示對以上頁面進行抓取(檢視該頁面開啟時返回的值),添加了該header,表示 模擬iPhone 6去請求豆瓣首頁 with request.urlopen(req) as f:  #用request方式開啟URL,將返回值標記為f
    print('Status:', f.status, f.reason)
    for k, v in f.getheaders():
        print('%s: %s' % (k, v))
    print('Data:', f.read().decode('utf-8'))
  • Post(上傳): 如果要以POST傳送一個請求,只需要把引數data以bytes形式傳入。
#模擬微博登入 from urllib import request, parse
print('Login to weibo.cn...')
email = input('Email: ')
passwd = input('Password: ')
login_data = parse.urlencode([
    ('username', email),
    ('password', passwd),
    ('entry', 'mweibo'),
    ('client_id', ''),
    ('savestate', '1'),
    ('ec', ''),
    ('pagerefer', 'https://passport.weibo.cn/signin/welcome?entry=mweibo&r=http%3A%2F%2Fm.weibo.cn%2F')
])

req = request.Request('https://passport.weibo.cn/sso/login')
req.add_header('Origin', 'https://passport.weibo.cn')
req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25')
req.add_header('Referer', 'https://passport.weibo.cn/signin/login?entry=mweibo&res=wel&wm=3349&r=http%3A%2F%2Fm.weibo.cn%2F')

with request.urlopen(req, data=login_data.encode('utf-8')) as f:
    print('Status:', f.status, f.reason)
    for k, v in f.getheaders():
        print('%s: %s' % (k, v))     print('Data:', f.read().decode('utf-8')) #en加de解
  • Handler: 通過一個Proxy去訪問網站,我們需要利用ProxyHandler來處理
小結: urllib提供的功能就是利用程式去執行各種HTTP請求。如果要模擬瀏覽器完成特定功能,需要把請求偽裝成瀏覽器。偽裝的方法是先監控瀏覽器發出的請求,再根據瀏覽器的請求頭來偽裝,User-Agent頭就是用來標識瀏覽器的。