Python 學習筆記12 - 常用內(nèi)建模塊

datetime —— 處理日期和時間

獲取當前日期和時間

from datetime import datetime

# 獲取當前datetime
now = datetime.now()

獲取指定日期和時間

# # 用指定日期時間創(chuàng)建datetime
dt = datetime(2015, 4, 19, 12, 20)

datetime轉(zhuǎn)換為timestamp

dt = datetime(2015, 4, 19, 12, 20)
# 把datetime轉(zhuǎn)換為timestamp
t = dt.timestamp()

Python 的 timestamp 是一個浮點數(shù)。如果有小數(shù)位,小數(shù)位表示毫秒數(shù)

某些編程語言(如Java和JavaScript)的 timestamp 使用整數(shù)表示毫秒數(shù),這種情況下只需要把 timestamp 除以1000就得到Python的浮點表示方法

timestamp轉(zhuǎn)換為datetime

t = 1429417200.0
# timestamp和本地時間做轉(zhuǎn)換
dt1 = datetime.fromtimestamp(t)
# timestamp是一個浮點數(shù),它沒有時區(qū)的概念,而datetime是有時區(qū)的
# UTC時間,即UTC+0:00時區(qū)的時間
dt2 = datetime.utcfromtimestamp(t)

str轉(zhuǎn)換為datetime

dt = datetime.strptime('2015-6-1 18:19:59', '%Y-%m-%d %H:%M:%S')

datetime轉(zhuǎn)換為str

now = datetime.now()
dtStr = now.strftime('%a, %b %d %H:%M')

datetime加減

from datetime import datetime, timedelta

now = datetime.now()

now + timedelta(hours=10)

now - timedelta(days=1)

now + timedelta(days=2, hours=12)

本地時間轉(zhuǎn)換為UTC時間

一個datetime類型有一個時區(qū)屬性tzinfo,但是默認為None,所以無法區(qū)分這個datetime到底是哪個時區(qū),除非強行給datetime設(shè)置一個時區(qū):

from datetime import datetime, timedelta, timezone

# 創(chuàng)建時區(qū)UTC+8:00
tz_utc_8 = timezone(timedelta(hours=8))

# datetime表示的時間需要時區(qū)信息才能確定一個特定的時間,否則只能視為本地時間
now = datetime.now()

# 強制設(shè)置為UTC+8:00
dt = now.replace(tzinfo=tz_utc_8)

時區(qū)轉(zhuǎn)換

from datetime import datetime, timedelta, timezone

# 通過 utcnow() 拿到當前的UTC時間,并強制設(shè)置為UTC,作為基準時間
utc_dt = datetime.utcnow().replace(tzinfo=timezone.utc)
print(utc_dt)

# 利用帶時區(qū)的 datetime ,通過 astimezone() 方法,可以轉(zhuǎn)換到任意時區(qū)
bj_dt = utc_dt.astimezone(timezone(timedelta(hours=8)))
print(bj_dt)

tokyo_dt = utc_dt.astimezone(timezone(timedelta(hours=9)))
print(tokyo_dt)

# 不是必須從UTC+0:00時區(qū)轉(zhuǎn)換到其他時區(qū),任何帶時區(qū)的datetime都可以正確轉(zhuǎn)換
tokyo_dt2 = bj_dt.astimezone(timezone(timedelta(hours=9)))
print(tokyo_dt2)

collections

namedtuple

namedtuple 是一個函數(shù),它用來創(chuàng)建一個自定義的 tuple 對象,并且規(guī)定了 tuple 元素的個數(shù),并可以用屬性而不是索引來引用 tuple 的某個元素

from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])

p = Point(1, 2)

p.x
p.y

isinstance(p, tuple) ==> True

deque

deque 是為了高效實現(xiàn)插入和刪除操作的雙向列表,適合用于隊列和棧

from collections import deque

q = deque(['a', 'b', 'c'])

q.append('x')
q.pop()

q.appendleft('x')
q.popleft()

defaultdict

使用 dict 時,如果引用的 Key 不存在,就會拋出 KeyError 。如果希望 key 不存在時,返回一個默認值,就可以用 defaultdict :

from collections import defaultdict

dd = defaultdict(lambda: 'N/A')
dd['key1'] = 'abc'

dd['key1'] ==> 'abc'
dd['key2'] ==> 'N/A'

OrderedDict

要保持 dict 中 Key 的順序,可以用 OrderedDict ,OrderedDict 的 Key 會按照插入的順序排列

from collections import OrderedDict

# 普通的 dict
d = dict([('a', 1), ('b', 2), ('c', 3)])

od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
od ==> OrderedDict([('a', 1), ('b', 2), ('c', 3)])

OrderedDict 可以實現(xiàn)一個 FIFO(先進先出)的 dict ,當容量超出限制時,先刪除最早添加的 Key :

from collections import OrderedDict

class LastUpdatedOrderedDict(OrderedDict):

    def __init__(self, capacity):
        super(LastUpdatedOrderedDict, self).__init__()
        self._capacity = capacity

    def __setitem__(self, key, value):
        containsKey = 1 if key in self else 0
        if len(self) - containsKey >= self._capacity:
            last = self.popitem(last=False)
            print('remove:', last)
        if containsKey:
            del self[key]
            print('set:', (key, value))
        else:
            print('add:', (key, value))
        OrderedDict.__setitem__(self, key, value)

Counter

Counter 是一個簡單的計數(shù)器,例如,統(tǒng)計字符出現(xiàn)的個數(shù):

from collections import Counter

c = Counter()

for ch in 'programming':
    c[ch] = c[ch] + 1

c

base64

Base64編碼會把3字節(jié)(4*6 bit)的二進制數(shù)據(jù)編碼為4字節(jié)的文本數(shù)據(jù),長度增加33%,好處是編碼后的文本數(shù)據(jù)可以在郵件正文、網(wǎng)頁等直接顯示

如果要編碼的二進制數(shù)據(jù)不是3的倍數(shù),Base64用\x00字節(jié)在末尾補足后,再在編碼的末尾加上1個或2個=號,表示補了多少字節(jié),解碼的時候,會自動去掉

"url safe"的base64編碼:針對字符 + 和 / 在URL中就不能直接作為參數(shù),把字符 + 和 / 分別變成 - 和 _

import base64

base64.b64encode(b'binary\x00string') ==> b'YmluYXJ5AHN0cmluZw=='

# b64decode() 可接受一個 str 
base64.b64decode(b'YmluYXJ5AHN0cmluZw==') ==> b'binary\x00string'
base64.b64decode('YmluYXJ5AHN0cmluZw==') ==> b'binary\x00string'

base64.b64encode(b'i\xb7\x1d\xfb\xef\xff') ==> b'abcd++//'
base64.urlsafe_b64encode(b'i\xb7\x1d\xfb\xef\xff') ==> b'abcd--__'

base64.urlsafe_b64decode('abcd--__') ==> b'i\xb7\x1d\xfb\xef\xff'

由于=字符也可能出現(xiàn)在Base64編碼中,但=用在URL、Cookie里面會造成歧義,所以,很多Base64編碼后會把=去掉

因為Base64是把3個字節(jié)變?yōu)?個字節(jié),所以,Base64編碼的長度永遠是4的倍數(shù),因此,需要加上=把Base64字符串的長度變?yōu)?的倍數(shù),就可以正常解碼了

能處理去掉=的base64解碼函數(shù):

import base64

def safe_base64_decode(s):
    return base64.b64decode(s + '=' * (4 - len(s) % 4))

struct

準確地講,Python沒有專門處理字節(jié)的數(shù)據(jù)類型

但由于b'str'可以表示字節(jié),所以,字節(jié)數(shù)組=二進制str

Python 提供了一個 struct 模塊來解決 bytes 和其他二進制數(shù)據(jù)類型的轉(zhuǎn)換

structpack 函數(shù)把任意數(shù)據(jù)類型變成 bytes

import struct

# pack的第一個參數(shù)是處理指令,'>I'的意思是:>表示字節(jié)順序是big-endian,也就是網(wǎng)絡(luò)序,I表示4字節(jié)無符號整數(shù)
struct.pack('>I', 10240099) ==> b'\x00\x9c@c'

unpackbytes 變成相應的數(shù)據(jù)類型:

# 根據(jù)>IH的說明,后面的bytes依次變?yōu)?I:4字節(jié)無符號整數(shù) 和 H:2字節(jié)無符號整數(shù)
struct.unpack('>IH', b'\xf0\xf0\xf0\xf0\x80\x80') ==> (4042322160, 32896)

struct模塊定義的數(shù)據(jù)類型

hashlib

Python 的 hashlib 提供了常見的摘要算法,如MD5,SHA1等等

import hashlib

md5 = hashlib.md5()
md5.update('how to use md5 in python hashlib?'.encode('utf-8'))

# 生成結(jié)果是固定的128 bit字節(jié),通常用一個32位的16進制字符串表示
print(md5.hexdigest())



# 如果數(shù)據(jù)量很大,可以分塊多次調(diào)用update(),最后計算的結(jié)果是一樣的
md5 = hashlib.md5()
md5.update('how to use md5 in '.encode('utf-8'))
md5.update('python hashlib?'.encode('utf-8'))
print(md5.hexdigest())
import hashlib

sha1 = hashlib.sha1()
sha1.update('how to use sha1 in '.encode('utf-8'))
sha1.update('python hashlib?'.encode('utf-8'))

# SHA1的結(jié)果是160 bit字節(jié),通常用一個40位的16進制字符串表示
print(sha1.hexdigest())

itertools

Python 的內(nèi)建模塊 itertools 提供了非常有用的用于操作迭代對象的函數(shù)

itertools 模塊提供的全部是處理迭代功能的函數(shù),它們的返回值不是 list ,而是 Iterator

itertools 提供的幾個“無限”迭代器:

  • count() 會創(chuàng)建一個無限的迭代器
import itertools

natuals = itertools.count(1)

for n in natuals:
    print(n) ==> 1,2,3,...
  • cycle() 會把傳入的一個序列無限重復下去
import itertools

cs = itertools.cycle('ABC')

for c in cs:
    print(c) ==> 'A','b','c','A','b','c',...
  • repeat() 負責把一個元素無限重復下去,不過如果提供第二個參數(shù)就可以限定重復次數(shù)
import itertools

ns = itertools.repeat('A', 3)

for n in ns:
    print(n) ==> 'A','A','A'

無限序列雖然可以無限迭代下去,但是通常我們會通過takewhile()等函數(shù)根據(jù)條件判斷來截取出一個有限的序列:

import itertools

natuals = itertools.count(1)

ns = itertools.takewhile(lambda x: x <= 10, natuals)

list(ns) ==> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

itertools 提供的幾個迭代器操作函數(shù)更加有用:

  • chain() 可以把一組迭代對象串聯(lián)起來,形成一個更大的迭代器
import itertools

for c in itertools.chain('ABC', 'XYZ'):
    print(c) ==> 'A' 'B' 'C' 'X' 'Y' 'Z'
  • groupby() 把迭代器中相鄰的重復元素挑出來放在一起
import itertools

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']
'''

# 實際上挑選規(guī)則是通過函數(shù)完成的,只要作用于函數(shù)的兩個元素返回的值相等,這兩個元素就被認為是在一組的,而函數(shù)返回值作為組的key
for key, group in itertools.groupby('AaaBBbcCAAa', lambda c: c.upper()):
    print(key, list(group))
    
'''
A ['A', 'a', 'a']
B ['B', 'B', 'b']
C ['c', 'C']
A ['A', 'A', 'a']
'''

contextlib

Python 的 with 語句允許我們非常方便地使用資源,而不必擔心資源沒有關(guān)閉

with open('/path/to/file', 'r') as f:
    f.read()

并不是只有 open() 函數(shù)返回的fp對象才能使用 with 語句。實際上,任何對象,只要正確實現(xiàn)了上下文管理,就可以用于 with 語句

實現(xiàn)上下文管理是通過 __enter____exit__ 這兩個方法實現(xiàn)的

class Query(object):

    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print('Begin')
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type:
            print('Error')
        else:
            print('End')
            
    def query(self):
        print('Query info about %s...' % self.name)


with Query('Bob') as q:
    q.query()

@contextmanager

編寫 __enter____exit__ 仍然很繁瑣,因此 Python 的標準庫 contextlib 提供了更簡單的寫法

@contextmanager 這個 decorator 接受一個 generator ,用 yield 語句把 with ... as var 把變量輸出出去,然后,with 語句就可以正常地工作了

from contextlib import contextmanager

class Query(object):

    def __init__(self, name):
        self.name = name

    def query(self):
        print('Query info about %s...' % self.name)
        
@contextmanager
def create_query(name):
    print('Begin')
    q = Query(name)
    yield q
    print('End')
    
    
with create_query('Bob') as q:
    q.query()

很多時候,我們希望在某段代碼執(zhí)行前后自動執(zhí)行特定代碼,也可以用 @contextmanager 實現(xiàn)

@contextmanager
def tag(name):
    print("<%s>" % name)
    yield
    print("</%s>" % name)

with tag("h1"):
    print("hello")
    print("world")

代碼的執(zhí)行順序是:

  1. with語句首先執(zhí)行yield之前的語句,因此打印出<h1>;
  2. yield調(diào)用會執(zhí)行with語句內(nèi)部的所有語句,因此打印出hello和world;
  3. 最后執(zhí)行yield之后的語句,打印出</h1>。

因此,@contextmanager 讓我們通過編寫 generator 來簡化上下文管理

@closing

如果一個對象沒有實現(xiàn)上下文,我們就不能把它用于 with 語句

可以用 closing() 來把該對象變?yōu)樯舷挛膶ο?/p>

with 語句使用 urlopen()

from contextlib import closing
from contextlib import contextmanager
from urllib.request import urlopen

with closing(urlopen('https://www.python.org')) as page:
    for line in page:
        print(line)
        
# closing也是一個經(jīng)過@contextmanager裝飾的generator
# 它的作用就是把任意對象變?yōu)樯舷挛膶ο螅⒅С謜ith語句
@contextmanager
def closing(thing):
    try:
        yield thing
    finally:
        thing.close()

XML

操作XML有兩種方法:DOM和SAX

  • DOM會把整個XML讀入內(nèi)存,解析為樹,因此占用內(nèi)存大,解析慢,優(yōu)點是可以任意遍歷樹的節(jié)點
  • SAX是流模式,邊讀邊解析,占用內(nèi)存小,解析快,缺點是我們需要自己處理事件

正常情況下,優(yōu)先考慮SAX,因為DOM實在太占內(nèi)存

在 Python 中使用 SAX 解析 XML 非常簡潔,通常我們關(guān)心的事件是 start_elementend_elementchar_data ,準備好這3個函數(shù),然后就可以解析 xml 了

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 可以用字符串拼接。復雜 XML 建議改用 JSON

str.join(list) 返回 str

利用SAX編寫程序解析Yahoo的XML格式的天氣預報,獲取當天和第二天的天氣:(未完成)

from xml.parsers.expat import ParserCreate

class WeatherSaxHandler(object):
    
    def __init__(self):
        self._city = ''
        self._country = ''
        self._data = {}
        
    @property
    def get_data(self):
        return self._data
        
    def start_element(self, name, attrs):
        # print('sax:start_element: %s, attrs: %s' % (name, str(attrs)))
        if name == 'yweather:location':
            self._data['city'] = attrs['city']
            self._data['country'] = attrs['country']
        elif 

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

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

def parse_weather(xml):
    handler = WeatherSaxHandler()
    parser = ParserCreate()
    parser.StartElementHandler = handler.start_element
    parser.EndElementHandler = handler.end_element
    parser.CharacterDataHandler = handler.char_data
    parser.Parse(xml)
    return handler.
    return {
        'city': 'Beijing',
        'country': 'China',
        'today': {
            'text': 'Partly Cloudy',
            'low': 20,
            'high': 33
        },
        'tomorrow': {
            'text': 'Sunny',
            'low': 21,
            'high': 34
        }
    }

測試數(shù)據(jù):

data = r'''<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
    <channel>
        <title>Yahoo! Weather - Beijing, CN</title>
        <lastBuildDate>Wed, 27 May 2015 11:00 am CST</lastBuildDate>
        <yweather:location city="Beijing" region="" country="China"/>
        <yweather:units temperature="C" distance="km" pressure="mb" speed="km/h"/>
        <yweather:wind chill="28" direction="180" speed="14.48" />
        <yweather:atmosphere humidity="53" visibility="2.61" pressure="1006.1" rising="0" />
        <yweather:astronomy sunrise="4:51 am" sunset="7:32 pm"/>
        <item>
            <geo:lat>39.91</geo:lat>
            <geo:long>116.39</geo:long>
            <pubDate>Wed, 27 May 2015 11:00 am CST</pubDate>
            <yweather:condition text="Haze" code="21" temp="28" date="Wed, 27 May 2015 11:00 am CST" />
            <yweather:forecast day="Wed" date="27 May 2015" low="20" high="33" text="Partly Cloudy" code="30" />
            <yweather:forecast day="Thu" date="28 May 2015" low="21" high="34" text="Sunny" code="32" />
            <yweather:forecast day="Fri" date="29 May 2015" low="18" high="25" text="AM Showers" code="39" />
            <yweather:forecast day="Sat" date="30 May 2015" low="18" high="32" text="Sunny" code="32" />
            <yweather:forecast day="Sun" date="31 May 2015" low="20" high="37" text="Sunny" code="32" />
        </item>
    </channel>
</rss>
'''

測試:

weather = parse_weather(data)
assert weather['city'] == 'Beijing', weather['city']
assert weather['country'] == 'China', weather['country']
assert weather['today']['text'] == 'Partly Cloudy', weather['today']['text']
assert weather['today']['low'] == 20, weather['today']['low']
assert weather['today']['high'] == 33, weather['today']['high']
assert weather['tomorrow']['text'] == 'Sunny', weather['tomorrow']['text']
assert weather['tomorrow']['low'] == 21, weather['tomorrow']['low']
assert weather['tomorrow']['high'] == 34, weather['tomorrow']['high']
print('Weather:', str(weather))

HTMLParser

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>''')

urllib

urllib 提供了一系列用于操作URL的功能

urllibrequest 模塊可以非常方便地抓取URL內(nèi)容,也就是發(fā)送一個GET請求到指定的頁面,然后返回HTTP的響應:

from urllib import request

with request.urlopen('https://api.douban.com/v2/book/2129650') as f:
    data = f.read()
    print('Status:', f.status, f.reason)
    for k, v in f.getheaders():
        print('%s: %s' % (k, v))
    print('Data:', data.decode('utf-8'))

模擬瀏覽器發(fā)送GET請求,就需要使用 Request 對象,通過往 Request 對象添加 HTTP 頭,我們就可以把請求偽裝成瀏覽器

from urllib import request

# 模擬iPhone 6去請求豆瓣首頁
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')
with request.urlopen(req) 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'))

如果要以 POST 發(fā)送一個請求,只需要把參數(shù) 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'))

如果還需要更復雜的控制,比如通過一個 Proxy 去訪問網(wǎng)站,我們需要利用 ProxyHandler 來處理

proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'})
proxy_auth_handler = urllib.request.ProxyBasicAuthHandler()
proxy_auth_handler.add_password('realm', 'host', 'username', 'password')
opener = urllib.request.build_opener(proxy_handler, proxy_auth_handler)
with opener.open('http://www.example.com/login.html') as f:
    pass

作業(yè):利用urllib讀取XML,將XML一節(jié)的數(shù)據(jù)由硬編碼改為由urllib獲取:

import re
from xml.parsers.expat import ParserCreate
from urllib import request

class DefaultSaxHandler(object):
    def __init__(self):
        self.today = 0
        self.__data = {}

    @property
    def get_data(self):
        return self.__data

    def satrt_element(self,name,attrs):
        if name == "yweather:location":
            self.__data['city'] = attrs['city']
            self.__data['country'] = attrs['country']
        if name == "yweather:condition":
            self.today = re.split(r'\s?', attrs['date'])[1]
        if name == "yweather:forecast":
            if re.split(r'\s?', attrs['date'])[0] == self.today:
                self.__data['today'] = {}
                self.__data['today']['text'] = attrs['text']
                self.__data['today']['low'] = int(attrs['low'])
                self.__data['today']['high'] = int(attrs['high'])
            if int(re.split(r'\s?', attrs['date'])[0]) == int(self.today) + 1:
                self.__data['tomorrow'] = {}
                self.__data['tomorrow']['text'] = attrs['text']
                self.__data['tomorrow']['low'] = int(attrs['low'])
                self.__data['tomorrow']['high'] = int(attrs['high'])

    def end_element(self,name):
        pass

    def char_data(self,text):
        pass


class get_weather(object):
    def __init__(self,city):
        self._city = city

    @staticmethod
    def get_yahoo(city):
        url = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22" + city +"%22)&format=xml&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"
        with request.urlopen(url) as f:
            data = f.read()
        return data

    def parse_weather(self):
        handler = DefaultSaxHandler()
        parser = ParserCreate()
        parser.StartElementHandler = handler.satrt_element
        parser.EndElementHandler = handler.end_element
        parser.CharacterDataHandler = handler.char_data
        parser.Parse(self.get_yahoo(self._city))
        return str(handler.get_data)


weather = get_weather("shanghai").parse_weather()
print(weather)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • python學習筆記 聲明:學習筆記主要是根據(jù)廖雪峰官方網(wǎng)站python學習學習的,另外根據(jù)自己平時的積累進行修正...
    renyangfar閱讀 3,081評論 0 10
  • 本學習筆記針對有其他語言基礎(chǔ)的情況下記錄的, 主要記錄一些與其他語言不一樣的地方, 使用于快速學習. 常用指令 p...
    GrayLand閱讀 1,070評論 0 3
  • 1.datetime datetime是Python處理日期和時間的標準庫。它的用法如下:a.獲取當前時間 b.獲...
    這是朕的江山閱讀 425評論 0 1
  • 文本 1. string:通用字符串操作 2. re:正則表達式操作 3. difflib:差異計算工具 4. t...
    三也視界閱讀 5,943評論 2 9
  • 美如煙花 在樓道口盯了半天才找到白如因的身影,陳海洛正要覺得驚喜感慨,真是“眾里尋她千百度,卻在燈火闌珊處。” 只...
    有魚姑娘閱讀 368評論 0 6