Python爬虫笔记——多协程(gevent and queue)

1、爬取8个网站(包括百度、新浪、搜狐、腾讯、网易、爱奇艺、天猫、凤凰)。用多协程gevent()模块来爬取。

这里有一个关于gevent的一些基础介绍的链接
Python并发之协程gevent基础(5)

from gevent import monkey
#从gevent库里导入monkey模块。
monkey.patch_all()
#monkey.patch_all()能把程序变成协作式运行,就是可以帮助程序实现异步。
import gevent,time,requests
#导入gevent、time、requests。

start = time.time()
#记录程序开始时间。

url_list = ['https://www.baidu.com/',
'https://www.sina.com.cn/',
'http://www.sohu.com/',
'https://www.qq.com/',
'https://www.163.com/',
'http://www.iqiyi.com/',
'https://www.tmall.com/',
'http://www.ifeng.com/']
#把8个网站封装成列表。

def crawler(url):
#定义一个crawler()函数。
    r = requests.get(url)
    #用requests.get()函数爬取网站。
    print(url,time.time()-start,r.status_code)
    #打印网址、请求运行时间、状态码。

tasks_list = [ ]
#创建空的任务列表。

for url in url_list:
#遍历url_list。
    task = gevent.spawn(crawler,url)
    #用gevent.spawn()函数创建任务。
    tasks_list.append(task)
    #往任务列表添加任务。
gevent.joinall(tasks_list)
#执行任务列表里的所有任务,就是让爬虫开始爬取网站。
end = time.time()
#记录程序结束时间。
print(end-start)
#打印程序最终所需时间。
print(tasks_list)

运行代码如下:

https://www.baidu.com/ 0.4305078983306885 200
https://www.sina.com.cn/ 0.652501106262207 200
http://www.ifeng.com/ 0.6529850959777832 200
https://www.163.com/ 0.6529850959777832 200
http://www.sohu.com/ 0.7468271255493164 200
https://www.qq.com/ 0.799919605255127 200
https://www.tmall.com/ 0.8475008010864258 200
http://www.iqiyi.com/ 0.9194967746734619 200
0.9199841022491455
[<Greenlet at 0x2162cb6c9d8: _run>, <Greenlet at 0x2162d915158: _run>, <Greenlet at 0x2162d915268: _run>, <Greenlet at 0x2162d915378: _run>, <Greenlet at 0x2162d915488: _run>, <Greenlet at 0x2162d915598: _run>, <Greenlet at 0x2162d9156a8: _run>, <Greenlet at 0x2162d9157b8: _run>]

2、爬取8个网站(包括百度、新浪、搜狐、腾讯、网易、爱奇艺、天猫、凤凰)。用多协程gevent()和queue()模块来爬取。
queue模块
当我们用多协程来爬虫,需要创建大量任务时,我们可以借助queue模块。
queue翻译成中文是队列的意思。我们可以用queue模块来存储任务,让任务都变成一条整齐的队列,就像银行窗口的排号做法。因为queue其实是一种有序的数据结构,可以用来存取数据。
这样,协程就可以从队列里把任务提取出来执行,直到队列空了,任务也就处理完了。就像银行窗口的工作人员会根据排号系统里的排号,处理客人的业务,如果已经没有新的排号,就意味着客户的业务都已办理完毕。

我们创建了两只可以异步爬取的爬虫。它们会从队列里取走网址,执行爬取任务。一旦一个网址被一只爬虫取走,另一只爬虫就取不到了,另一只爬虫就会取走下一个网址。直至所有网址都被取走,队列为空时,爬虫就停止工作。
在这里插入图片描述
用协程技术和队列爬取8个网站的完整代码如下:

from gevent import monkey
#从gevent库里导入monkey模块。
monkey.patch_all()
#monkey.patch_all()能把程序变成协作式运行,就是可以帮助程序实现异步。
#会自动将python的一些标准模块替换成gevent框架
import gevent,time,requests
#导入gevent、time、requests
from gevent.queue import Queue
#从gevent库里导入queue模块

start = time.time()

url_list = ['https://www.baidu.com/',
'https://www.sina.com.cn/',
'http://www.sohu.com/',
'https://www.qq.com/',
'https://www.163.com/',
'http://www.iqiyi.com/',
'https://www.tmall.com/',
'http://www.ifeng.com/']

work = Queue()
#创建队列对象,并赋值给work。
#用Queue()能创建queue对象,相当于创建了一个不限任何存储数量的空队列。如果我们往Queue()中传入参数,比如Queue(10),则表示这个队列只能存储10个任务。
for url in url_list:
#遍历url_list
    work.put_nowait(url)
    #用put_nowait()函数可以把网址都放进队列里。queue.put_nowait即往队列里存储数据。

def crawler():
    while not work.empty():
    #当队列不是空的时候,就执行下面的程序。queue.empty()是判断队列是否为空。
        url = work.get_nowait()
        #用get_nowait()函数可以把队列里的网址都取出。
        r = requests.get(url)
        #用requests.get()函数抓取网址。
        print(url,work.qsize(),r.status_code)
        #打印网址、队列长度、抓取请求的状态码。queue.qsize()是判断队列还剩多少数量

tasks_list  = [ ]
#创建空的任务列表
for x in range(2):
#相当于创建了2个爬虫
    task = gevent.spawn(crawler)
    #用gevent.spawn()函数创建执行crawler()函数的任务。
    #gevent.spawn()会自动将python的一些标准模块替换成gevent框架。
    tasks_list.append(task)
    #往任务列表添加任务。
gevent.joinall(tasks_list)
#用gevent.joinall方法,执行任务列表里的所有任务,就是让爬虫开始爬取网站。
#gevent.joinall(jobs)是将协程任务添加到事件循环,接收一个任务列表。
end = time.time()
print(end-start)

代码运行结果如下:

https://www.baidu.com/ 6 200
https://www.sina.com.cn/ 5 200
http://www.sohu.com/ 4 200
https://www.qq.com/ 3 200
https://www.163.com/ 2 200
https://www.tmall.com/ 1 200
http://www.iqiyi.com/ 0 200
http://www.ifeng.com/ 0 200
3.0378034114837646

3、用多协程爬取薄荷网的食物热量。

代码如下:

import gevent
from gevent.queue import Queue
from gevent import monkey
monkey.patch_all()
import requests, bs4, csv

work = Queue()
url_1 = 'http://www.boohee.com/food/group/{type}?page={page}'
for x in range(1, 4):
    for y in range(1, 4):
        real_url = url_1.format(type=x, page=y)
        work.put_nowait(real_url)

url_2 = 'http://www.boohee.com/food/view_menu?page={page}'
for x in range(1,4):
    real_url = url_2.format(page=x)
    work.put_nowait(real_url)

def crawler():
    headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'
    }
    while not work.empty():
        url = work.get_nowait()
        res = requests.get(url, headers=headers)
        bs_res = bs4.BeautifulSoup(res.text, 'html.parser')
        foods = bs_res.find_all('li', class_='item clearfix')
        for food in foods:
            food_name = food.find_all('a')[1]['title']
            food_url = 'http://www.boohee.com' + food.find_all('a')[1]['href']
            food_calorie = food.find('p').text
            writer.writerow([food_name, food_calorie, food_url])
            #借助writerow()函数,把提取到的数据:食物名称、食物热量、食物详情链接,写入csv文件。
            print(food_name)

csv_file= open('boohee.csv', 'w', newline='')
#调用open()函数打开csv文件,传入参数:文件名“boohee.csv”、写入模式“w”、newline=''。
writer = csv.writer(csv_file)
# 用csv.writer()函数创建一个writer对象。
writer.writerow(['食物', '热量', '链接'])
#借助writerow()函数往csv文件里写入文字:食物、热量、链接

tasks_list = []
for x in range(5):
    task = gevent.spawn(crawler)
    tasks_list.append(task)
gevent.joinall(tasks_list)

运行结果:

Easy Fun 高蛋白小酥鱼(藤椒味)
鸡蛋,又叫鸡子、鸡卵、蛋
Easy Fun 低脂鸡胸肉肠(香辣味)
Easy Fun 鸡胸肉丝(原味)
Easy Fun 低脂鸡胸肉(黑椒味)
Easy Fun 低脂鸡胸肉(香辣味)
Easy Fun 低脂鸡肉丸(原味),又叫Easy Fun 低脂鸡肉丸(原味)、Easy Fun 低脂鸡胸肉丸(原味)
Easy Fun 高蛋白小酥鱼(海苔味)
Easy Fun 低脂鸡胸肉肠(原味)
猪小排,又叫排骨、猪排
鸡(土鸡,家养)
鸡(母鸡,一年内)
鸡(肉鸡,肥)
鸭肉,又叫鸭子、鹜肉、家凫肉
猪蹄,又叫猪脚、猪手、猪蹄爪
螃蟹(河蟹),又叫螃蟹、毛蟹、稻蟹、中华绒螯蟹、横行介士、无肠公子
猪肉(瘦),又叫猪精肉,瘦肉
鸡蛋白(鸡蛋清),又叫鸡蛋白、鸡蛋清、蛋清、蛋白
火腿肠
鸡胸脯肉,又叫鸡柳肉、鸡里脊肉、鸡胸、鸡胸肉
荷包蛋(油煎),又叫荷包蛋、煎蛋、煎荷包蛋、煎鸡蛋
咸鸭蛋,又叫盐蛋、腌蛋、味蛋
猪肉(肥瘦),又叫豕肉、彘肉
瓦罐鸡汤(含料),又叫瓦罐汤
瓦罐鸡汤(无料)
猪小排(良杂猪)
猪肉(奶脯),又叫软五花、奶脯、五花肉
猪大排,又叫猪排
Easy Fun 低脂鸡胸肉肠
松花蛋(鸭蛋),又叫皮蛋
酸奶
牛奶,又叫纯牛奶、牛乳、全脂牛奶
无糖全脂拿铁,又叫拿铁咖啡、拿铁(全脂,无糖)
奶酪,又叫乳酪、芝士、起司、计司
酸奶(中脂)
脱脂奶粉
酸奶(调味)
酸奶(果料),又叫果料酸奶
酸奶(果粒),又叫果粒酸奶
蒙牛 高钙牛奶,又叫蒙牛袋装高钙牛奶
脱脂牛奶,又叫脱脂奶
光明 e+益生菌酸牛奶(原味)220ml (袋装)
低脂牛奶,又叫低脂奶 脱脂奶
早餐奶
酸奶(高蛋白)
奶片
全脂牛奶粉
光明 纯牛奶,又叫光明牛奶
光明 优倍 高品质鲜牛奶,又叫光明 优倍高品质鲜牛奶
光明 优倍 0脂肪 高品质脱脂鲜牛奶
Easy Fun 营养粉丝(香菇炖鸡),又叫Easy Fun 营养粉丝(香菇炖鸡味)
Easy Fun 营养粉丝(牛肉味噌味)
白粥,又叫白粥(粳米),稀饭,大米粥,白米粥,米粥,大米汤汤
Easy Fun 营养粉丝(番茄鸡蛋),又叫Easy Fun 营养粉丝(番茄鸡蛋味)
Easy Fun 低脂咖喱鸡饭
Easy Fun 抹茶红豆麦片
Easy Fun 高蛋白微波蛋糕预拌粉(香浓可可味)
Easy Fun 红枣黑米圈(新包装)
Easy Fun 鸡肉松烤麦片
Easy Fun 山药紫薯圈
包子(猪肉馅)
米饭,又叫大米饭,饭,蒸米、锅巴饭
Easy Fun 高纤奇亚籽苏打饼干,又叫Easy Fun 高纤 奇亚籽苏打饼干、奇亚籽苏打咸味饼干、苏打饼干、EASY FUN 苏打饼干
白薯,又叫山芋、红皮山芋,地瓜、甘薯
大米,又叫稻米、米、生米
全麦面包,又叫全麦面包、全麦吐司、全麦面包片、全麦土司
烙饼
花卷,又叫花之卷、大花卷、小花卷
油条,又叫小油条
曼可顿全麦高纤维面包
稀饭,又叫白粥(籼米),大米粥,白米粥
玉米(鲜),又叫苞谷、珍珠米、棒子、玉蜀黍、苞米、六谷、鲜玉米
燕麦片,又叫燕麦
面条(生),又叫面
煮面条,又叫面、水煮面、面条(煮)
籼米粉,又叫米线、米粉、粉
面包
红薯,又叫地瓜、番薯、甘薯
小米粥
马铃薯,又叫土豆、洋芋、地蛋、山药蛋、洋番薯
光明 优倍 0乳糖 巴士杀菌调制乳
光明 致优 全鲜乳,又叫光明 致优全鲜乳
光明 0脂肪 鲜牛奶,又叫光明 0脂肪鲜牛奶
牛奶(强化VA,VD),又叫牛乳(强化VA,VD)
光明 低脂牛奶
蒙牛 木糖醇酸牛奶,又叫蒙牛木糖醇酸奶
低脂奶酪
伊利 无蔗糖酸牛奶(利乐包)150g
蒙牛 酸牛奶(草莓+树莓)100g (小盒装)
光明减脂90%脱脂鲜牛奶
牛肉面,又叫兰州拉面、牛腩面、牛肉拌面
炒上海青,又叫炒青菜
番茄炒蛋,又叫番茄炒鸡蛋、西红柿炒蛋、西红柿炒鸡蛋、西虹市炒鸡蛋、番茄炒蛋
吐司,又叫吐司面包、白吐司、面包片、切片面包
鸡蛋羹,又叫蒸蛋
绿豆汤
素炒小白菜,又叫小青菜
烧茄子
绿豆粥,又叫绿豆稀饭
菜包子,又叫香菇菜包、菜包子、素包子、素包、香菇青菜包、素菜包、香菇青菜包、香菇包子
卤蛋,又叫卤鸡蛋
清炒土豆丝
清爽西兰花
烧麦,又叫烧卖、糯米烧卖
炒大白菜,又叫大白菜
西红柿鸡蛋汤,又叫西红柿蛋汤、西红柿蛋花汤
大饼,又叫饼,家常饼,死面饼
清蒸鱼,又叫清蒸鱼、蒸鱼、鱼、蒸洄鱼
酸菜鱼,又叫酸汤鱼、酸辣鱼、酸菜鱼
寿司 自制1,又叫寿司卷
蛋炒饭,又叫黄金炒饭、蛋炒饭
红烧鳓鱼
盐水虾,又叫焖鲜虾
清炒绿豆芽,又叫有机活体豆苗、炒绿豆芽
葱油饼,又叫葱花饼、葱油饼
清炒西葫芦,又叫炒西葫、西葫芦丝
西红柿鸡蛋面,又叫番茄蛋面、番茄鸡蛋面
酸辣土豆丝
红烧肉
韭菜包子
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值