对于python的新学者来说,学习python3+的概率要大好多,毕竟喜欢新的东西。python2 就是不支持中文这一点太不好了!当初我就是因为这个坚定的选择python3的,一开始也是发现好多很好的库没有python3的版本,但现在回头看,感觉python2好旧了。
所以这一篇当然是关于python3的新东西。也就是用python3进行异步网页抓取,因为那什么urllib是阻塞的,然后很多已有的异步框架是基于python2的,所以网上这方面的技术还是比较少的,相关的可以找到廖雪峰的博客里有些。还有就是这篇文章了 python:利用asyncio进行快速抓取 。然后你会发现上面的例子不完整,还或许有错。然后你会对这个较新的领域有些疑问,你会被标准库的asyncio之底层雷到。比如数据库的异步怎么做,比如文件读写的异步有木有必要,,主要是python文件处理在各类系统不一,window有些函数还不支持……然后,你就可以继续往下看了。
俺也是自己看了一天的文档于是自己搭建了自己的异步抓取小框架。现在,用这个框架只需要填写一些请求地址、请求参数啊什么的就能异步抓了,快速高效。当然抓到的网页怎么处理那个是要自己写的,框架里用的是pyquery。数据库异步框架被我好困难的找到了 ——aiomysql,在人家博客里被非常低调的一笔带过了……然后我看到有文章分析出python的文件读写没必要异步,一方面那太复杂,找不到简单的库,你要接触底层的python函数库那随你。其次,python的速度与磁盘读写的速度能差别多大呢?真的有必要吗,而且非常大的数据人家又有了数据库的方案。
框架是在github上的,代码很少,在github上有详细的介绍。下面贴一点主要代码,看看我的design:
import aiohttp import asyncio import config import processData as pd async def fetchData(url, callback = pd.processData, params=None): #set request url and parameters here or you can pass from outside. conn = aiohttp.TCPConnector(limit=config.REQ_AMOUNTS) s = aiohttp.ClientSession(headers = config.HEADERS, connector=conn) #use s.** request a webside will keep-alive the connection automaticaly, #so you can set multi request here without close the connection #while in the same domain. #i.e. #await s.post(‘***/page1‘) #await s.get(‘***/page2‘) ######################################################################## async with s.get(url, params = params) as r: #this format will auto close connection after preccessing. #here the conection closed automaticly. data = await r.text() #here data will be just string with html format. return await callback(data) if __name__ == ‘__main__‘: loop = asyncio.get_event_loop() calendar_url= ‘http://ec.cn.forexprostools.com/?ecoDayFontColor=%23c5c5c5&ecoDayBackground=%23ffffff&innerBorderColor=%23edeaea&borderColor=%23edeaea&columns=exc_flags,exc_currency,exc_importance,exc_actual,exc_forecast,exc_previous&category=_employment,_economicActivity,_inflation,_credit,_centralBanks,_confidenceIndex,_balance,_Bonds&importance=1,2,3&features=datepicker,timezone,timeselector,filters&countries=29,25,54,145,34,163,32,70,6,27,37,122,15,113,107,55,24,121,59,89,72,71,22,17,51,39,93,106,14,48,33,23,10,35,92,57,94,97,68,96,103,111,42,109,188,7,105,172,21,43,20,60,87,44,193,125,45,53,38,170,100,56,80,52,36,90,112,110,11,26,162,9,12,46,85,41,202,63,123,61,143,4,5,138,178,84,75&calType=week&timeZone=28&lang=1‘
#coroutine in tasks will run automaticly tasks = [ #add every web url you want to crawl and never feel limitation. just remember pass the callback function to process data. fetchData(‘http://www.xm.com‘, pd.Xm), fetchData(‘http://www.aetoscg.com/cn/long-and-short.html‘, pd.Asto), fetchData(calendar_url, pd.Calendar) ] loop.run_until_complete(asyncio.wait(tasks)) loop.close()
中间那段长得不像话的链接原谅我,我不是为了充字数的,我是想爬取外汇的财经日历。代码很简洁,就是设计很干净。config——网站请求配置文件在config.py, 数据处理文件,也就是异步请求返回后的callback在processData.py 文件, 我巧妙的将yield/await这种看着同步其实异步的写法与 callback这个关键字结合,只想让你秒懂。
原文:http://www.cnblogs.com/jassada/p/5294862.html