前言
本篇要從小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的關係。