异步IO爬虫,使用asyncio、aiohttp和aiomysql

很多小伙伴初学python时都会学习到爬虫,刚入门时会使用requests、urllib这些同步的库进行单线程爬虫,速度是比较慢的,后学会用scrapy框架进行爬虫,速度很快,原因是scrapy是基于twisted多线程异步IO框架。 本例使用的asyncio也是一个异步IO框架,在python3.5以后加入了协程的关键字async,能够将协程和生成器区分开来,更加方便使用协程。 经过测试,平均1秒可以爬取30个详情页信息 可以使用asyncio.Semaphore来控制并发数,达到限速的效果

# -*- coding: utf-8 -*-

"""

:author: KK

:url: http://github.com/PythonerKK

:copyright: © 2019 KK <705555262@qq.com.com>

"""

import asyncio

import re

import aiohttp

from pyquery import PyQuery

import aiomysql

from lxml import etree

pool = ''

#sem = asyncio.Semaphore(4) 用来控制并发数,不指定会全速运行

stop = False

headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'

}

MAX_PAGE = 10

TABLE_NAME = 'data' #数据表名

city = '' #城市简写

url = '' #url地址拼接

urls = [] #所有页的url列表

links_detail = set() #爬取中的详情页链接的集合

crawled_links_detail = set() #爬取完成的链接集合,方便去重

async def fetch(url, session):

'''

aiohttp获取网页源码

'''

# async with sem:

try:

async with session.get(url, headers=headers, verify_ssl=False) as resp:

if resp.status in [200, 201]:

data = await resp.text()

return data

except Exception as e:

print(e)

def extract_links(source):

'''

提取出详情页的链接

'''

pq = PyQuery(source)

for link in pq.items("a"):

_url = link.attr("href")

if _url and re.match('https://.*?/\d+.html', _url) and _url.find('{}.lianjia.com'.format(city)):

links_detail.add(_url)

print(links_detail)

def extract_elements(source):

'''

提取出详情页里面的详情内容

'''

try:

dom = etree.HTML(source)

id = dom.xpath('//link[@rel="canonical"]/@href')[0]

title = dom.xpath('//title/text()')[0]

price = dom.xpath('//span[@class="unitPriceValue"]/text()')[0]

information = dict(re.compile('

(.*?)(.*?)').findall(source))

information.update(title=title, price=price, url=id)

print(information)

asyncio.ensure_future(save_to_database(information, pool=pool))

except Exception as e:

print('解析详情页出错!')

pass

async def save_to_database(information, pool):

'''

使用异步IO方式保存数据到mysql中

注:如果不存在数据表,则创建对应的表

'''

COLstr = '' # 列的字段

ROWstr = '' # 行字段

ColumnStyle = ' VARCHAR(255)'

for key in information.keys():

COLstr = COLstr + ' ' + key + ColumnStyle + ','

ROWstr = (ROWstr + '"%s"' + ',') % (information[key])

# 异步IO方式插入数据库

async with pool.acquire() as conn:

async with conn.cursor() as cur:

try:

await cur.execute("SELECT * FROM %s" % (TABLE_NAME))

await cur.execute("INSERT INTO %s VALUES (%s)"%(TABLE_NAME, ROWstr[:-1]))

print('插入数据成功')

except aiomysql.Error as e:

await cur.execute("CREATE TABLE %s (%s)" % (TABLE_NAME, COLstr[:-1]))

await cur.execute("INSERT INTO %s VALUES (%s)" % (TABLE_NAME, ROWstr[:-1]))

except aiomysql.Error as e:

print('mysql error %d: %s' % (e.args[0], e.args[1]))

async def handle_elements(link, session):

'''

获取详情页的内容并解析

'''

print('开始获取: {}'.format(link))

source = await fetch(link, session)

#添加到已爬取的集合中

crawled_links_detail.add(link)

extract_elements(source)

async def consumer():

'''

消耗未爬取的链接

'''

async with aiohttp.ClientSession() as session:

while not stop:

if len(urls) != 0:

_url = urls.pop()

source = await fetch(_url, session)

print(_url)

extract_links(source)

if len(links_detail) == 0:

print('目前没有待爬取的链接')

await asyncio.sleep(2)

continue

link = links_detail.pop()

if link not in crawled_links_detail:

asyncio.ensure_future(handle_elements(link, session))

async def main(loop):

global pool

pool = await aiomysql.create_pool(host='127.0.0.1', port=3306,

user='root', password='xxxxxx',

db='aiomysql_lianjia', loop=loop, charset='utf8',

autocommit=True)

for i in range(1, MAX_PAGE):

urls.append(url.format(city, str(i)))

print('爬取总页数:{} 任务开始...'.format(str(MAX_PAGE)))

asyncio.ensure_future(consumer())

if __name__ == '__main__':

loop = asyncio.get_event_loop()

asyncio.ensure_future(main(loop))

loop.run_forever()

aiohttp mysql_python异步爬虫asyncio+aiohttp+aiomysql异步存入数据相关推荐

  1. aiohttp保存MySQL_python链家网高并发异步爬虫asyncio+aiohttp+aiomysql异步存入数据

    python链家网二手房异步IO爬虫,使用asyncio.aiohttp和aiomysql 很多小伙伴初学python时都会学习到爬虫,刚入门时会使用requests.urllib这些同步的库进行单线 ...

  2. python链家网高并发异步爬虫asyncio+aiohttp+aiomysql异步存入数据

    python链家网二手房异步IO爬虫,使用asyncio.aiohttp和aiomysql 很多小伙伴初学python时都会学习到爬虫,刚入门时会使用requests.urllib这些同步的库进行单线 ...

  3. 前端调用mysql异步_python链家网高并发异步爬虫asyncio+aiohttp+aiomysql异步存入数据...

    python链家网二手房异步IO爬虫,使用asyncio.aiohttp和aiomysql 很多小伙伴初学python时都会学习到爬虫,刚入门时会使用requests.urllib这些同步的库进行单线 ...

  4. python爬虫 asyncio aiohttp aiofiles 单线程多任务异步协程爬取图片

    python爬虫 asyncio aiohttp aiofiles 多任务异步协程爬取图片 main.py """=== coding: UTF8 ==="&q ...

  5. 异步爬虫模块aiohttp实战之infoq

    点击上方蓝字关注 异步爬虫模块aiohttp实战之infoq 之前写过很多的关于异步的文章,介绍了asyncio的使用,大多的只是通过简单的例子说明了asyncio的使用,但是没有拿出具体的使用例子, ...

  6. 利用aiohttp实现异步爬虫

      asyncio可以实现单线程并发IO操作,是Python中常用的异步处理模块.关于asyncio模块的介绍,笔者会在后续的文章中加以介绍,本文将会讲述一个基于asyncio实现的HTTP框架--a ...

  7. 爬虫的进阶使用——异步爬虫

    一.异步爬虫 1.异步爬虫的了解 在爬取数据下载的时候,通常是下载一个才能下载下一个,我们想要同时来下载节约时间 python有限制,只能使用1个满cpu核心.GIL全局锁 想要实现从单线程到并发执行 ...

  8. python异步爬虫之线程池

    单线程不足之处 当对多个url发送请求时,只有请求完第一个url才会接着请求第二个url(requests是一个阻塞的操作),比如下载图片,这种一个个执行的方式称为单线程.其存在等待的时间,这样效率是 ...

  9. 异步IO爬虫 - asyncio、aiohttp

    在执行一些 IO 密集型任务的时候,程序常常会因为等待 IO 而阻塞.比如在网络爬虫中,如果我们使用 requests 库来进行请求的话,如果网站响应速度过慢,程序一直在等待网站响应,最后导致其爬取效 ...

最新文章

  1. Py之textgenrnn:textgenrnn库的简介、安装、使用方法详细攻略
  2. 蓝桥杯_算法训练_ALGO10_集合运算
  3. docker运行python程序_如何使用Docker运行多个Python脚本和一个可执行文件?
  4. 不要轻易和少妇上床:金融危机是这…
  5. kafka php 0.8,php5.6 centos7 kafka0.8.1
  6. 解决Yii2邮件发送问题(结果返回成功,但接收不到邮件)
  7. crypto在web的使用
  8. ASP.NET基础教程-Server对象
  9. 鼎博电梯门禁数据分析
  10. Firefly III 搭建个人财务记账平台
  11. TS Moly Lubricants TSMoly
  12. 高维统计理论 估计量的Minimax误差分析 基础理论
  13. 嵌入式单片机面试笔记
  14. esxi添加硬盘驱动
  15. java.sql.SQLSyntaxErrorException: Table ‘H_PERSION‘ doesn‘t exist
  16. COB-软封装的一些理解
  17. Git 强制更新覆盖本地代码
  18. PHP数组内容制作分页功能
  19. 理解实时频谱分析仪的频域电平触发
  20. 从Folding@home项目看GPU通用计算发展

热门文章

  1. 更改PVE登录IP管理地址
  2. HTTP返回状态码详解
  3. 3GPP TS 29244-g30 中英文对照 | 5.13.1 General
  4. 我国教育大数据开发利用,主要面临哪些难题?
  5. 关于SAP的号码范围(number range)
  6. 利用PhotoShop CS6进行抠图
  7. redis的rdb持久化的cow技术(写时复制)及fork子进程理解
  8. DSS部署-11、Spark on Yarn部署
  9. 如何制定一份高质量的测试计划
  10. 【Java爬虫】学爬虫从简单的开始,无门槛小白都能学会,带你爬取豆瓣电影Top250