前言
本篇要从小7的朋友说起。数据组的他收到业务提交的三个excel。要求将其中的地址转成经纬度,然后匹配最近的银行网点。现用的转换程序约二秒出一条记录,三个excel总数据量约十几万。这也难怪会愁了。
正文
0x01使用scrapy爬虫框架处理。
原因有以下几点:
- 上次使用scrapy爬携程评论现在还是比较熟悉
- scrapy使用的是异步请求(重点)
- 框架设计有数据持久化 但在程序中,速度任然很慢。没去深究原因,转面使用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的关系。