项目介绍
本文将展示如何利用Pyhton中的异步模块来提高爬虫的效率。
我们需要爬取的目标为:融360网站上的理财产品信息(https://www.rong360.com/licai-bank/list/p1),页面如下:

我们需要爬取86394条理财产品的信息,每页10条,也就是8640个页面。
在文章Python爬虫(16)利用Scrapy爬取银行理财产品信息(共12多万条)中,我们使用爬虫框架Scrapy实现了该爬虫,爬取了127130条数据,并存入MongoDB,整个过程耗时3小时。按道理来说,使用Scrapy实现爬虫是较好的选择,但是在速度上,是否能有所提升呢?本文将展示如何利用Pyhton中的异步模块(aiohtpp和asyncio)来提高爬虫的效率。
爬虫项目
我们的爬虫分两步走:
- 爬取融360网页上的理财产品信息并存入csv文件;
- 读取csv文件并存入至MySQL数据库。
首先,我们爬取融360网页上的理财产品信息并存入csv文件,我们使用aiohttp和asyncio来加速爬虫,完整的Python代码如下:
import re import time import aiohttp import asyncio import pandas as pd import logging # 设置日志格式 logging.basicConfig(level = logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s') logger = logging.getLogger(__name__) df = pd.DataFrame(columns=['name', 'bank', 'currency', 'startDate',\ 'endDate', 'period', 'proType', 'profit', 'amount']) # 异步HTTP请求 async def fetch(sem, session, url): async with sem: headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'} async with session.get(url, headers=headers) as response: return await response.text() # 解析网页 async def parser(html): # 利用正则表达式解析网页 tbody = re.findall(r"<tbody>[\s\S]*?</tbody>", html)[0] trs = re.findall(r"<tr [\s\S]*?</tr>", tbody) for tr in trs: tds = re.findall(r"<td[\s\S]*?</td>", tr) name,bank = re.findall(r'title="(.+?)"', ''.join(tds)) name = name.replace('&', '').replace('quot;', '') currency, startDate, endDate, amount = re.findall(r'<td>(.+?)</td>', ''.join(tds)) period = ''.join(re.findall(r'<td class="td7">(.+?)</td>', tds[5])) proType = ''.join(re.findall(r'<td class="td7">(.+?)</td>', tds[6])) profit = ''.join(re.findall(r'<td class="td8">(.+?)</td>', tds[7])) df.loc[df.shape[0] + 1] = [name, bank, currency, startDate, endDate, \ period, proType, profit, amount] logger.info(str(df.shape[0])+'\t'+name) # 处理网页 async def download(sem, url): async with aiohttp.ClientSession() as session: try: html = await fetch(sem, session, url) await parser(html) except Exception as err: print(err) # 全部网页 urls = ["https://www.rong360.com/licai-bank/list/p%d"%i for i in range(1, 8641)] # 统计该爬虫的消耗时间 print('*' * 50) t3 = time.time() # 利用asyncio模块进行异步IO处理 loop = asyncio.get_event_loop() sem=asyncio.Semaphore(100) tasks = [asyncio.ensure_future(download(sem, url))
