十萬數據處理(初試python黑魔法asyncio)

前言

本篇要從小7的朋友說起。數據組的他收到業務提交的三個excel。要求將其中的地址轉成經緯度,然後匹配最近的銀行網點。現用的轉換程序約二秒出一條記錄,三個excel總數據量約十幾萬。這也難怪會愁了。

正文

0x01使用scrapy爬蟲框架處理。

原因有以下幾點:
1. 上次使用scrapy爬攜程評論現在還是比較熟悉
2. scrapy使用的是異步請求(重點)
3. 框架設計有數據持久化
但在程序中,速度任然很慢。沒去深究原因,轉面使用aiohttp+asyncio處理。

0x02試用asyncio

asyncio是Python 3.4版本引入的標準庫,直接內置了對異步IO的支持。
asyncio的編程模型就是一個消息循環。我們從asyncio模塊中直接獲取一個EventLoop的引用,然後把需要執行的協程扔到EventLoop中執行,就實現了異步IO

asyncio代碼,40個併發跑起真的非常快。7萬的數據,半個小時搞定。

import time
import asyncio
from aiohttp import ClientSession

i = 0
max = 40
addrs = []
tasks = []
url = "http://api.map.baidu.com/geocoder/v2/?address={}&output=json&ak=你的百度AK"

async def getInfo(url):
    async with ClientSession() as session:
        async with session.get(url) as response:
            return await response.read()

def run():
    #讀取地址文件
    with open('a.txt', 'r', encoding='utf8') as f:
        lines = f.readlines()
        for line in lines:
            line = line.strip('\n')
            task = asyncio.ensure_future(getInfo(url.format(line)))
            tasks.append(task)
            addrs.append(line)
            global i, max
            i = i + 1
            if i >= max: # 40個一併發
                t = 0
                results = loop.run_until_complete(asyncio.gather(*tasks))
                #寫入響應信息
                with open('a_dst.txt', 'a', encoding='utf8') as dstfile:
                    for r in results:
                        dstfile.writelines(addrs[t] + r.decode() + '\n')
                        t = t + 1
                i = 0
                tasks.clear()
                addrs.clear()

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    run()

0x03處理後續結果

處理下結果文件,最後轉成excel,十幾萬的數據處理完成。

結束語

使用asyncio上手還是比較簡單。主要是理解事件循環,協程和任務,future的關係。

參考:
Python黑魔法 — 異步IO( asyncio) 協程
python異步編程之asyncio(百萬併發)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章