说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
本例是一个利用的 Python(使用版本 Python 3.11)的异步机制批量获取豆瓣TOP250电影的电影(案例中仅解析了电影的标题),同时还提供了同步代码和异步代码的对比。
同步代码如下:
import time
import atexit
from bs4 import BeautifulSoup
import httpx
start = time.time()
atexit.register(lambda: print('用时(秒):', time.time()-start))
headers = {'User-Agent': 'Mozilla/5.0 Chrome/108.0.0.0 Safari/537.36'}
c = httpx.Client(headers=headers)
def get_data(page_id):
# 任务第一步: 获取网页信息
print(f'{time.strftime("%X")} Hello {page_id}!')
r = c.get(f'https://movie.douban.com/top250?start={page_id}&filter=')
# 任务第二步: 解析页面信息(获取电影标题)
soup = BeautifulSoup(r.text, 'html.parser')
data = [i.span.text for i in soup.select('.item')]
print(f'{time.strftime("%X")} end {page_id}!')
return data
def main():
data = []
for i in range(0, 250, 25):
data.append(get_data(i) )
return data
data = main()
print(data)
'''
09:03:01 Hello 0!
09:03:04 end 0!
09:03:04 Hello 25!
09:03:04 end 25!
09:03:04 Hello 50!
09:03:04 end 50!
09:03:04 Hello 75!
09:03:04 end 75!
09:03:04 Hello 100!
09:03:05 end 100!
09:03:05 Hello 125!
09:03:05 end 125!
09:03:05 Hello 150!
09:03:05 end 150!
09:03:05 Hello 175!
09:03:05 end 175!
09:03:05 Hello 200!
09:03:05 end 200!
09:03:05 Hello 225!
09:03:05 end 225!
[['肖申克的救赎', '霸王别姬', '阿甘正传'...
..., '我爱你', '地球上的星星']]
用时(秒): 4.4769511222839355
'''
异步代码如下(由于异步机制,需要存为 py 文件用命令执行):
import asyncio
import time
import atexit
from bs4 import BeautifulSoup
import httpx
start = time.time()
atexit.register(lambda: print('用时(秒):', time.time()-start))
headers = {'User-Agent': 'Mozilla/5.0 Chrome/108.0.0.0 Safari/537.36'}
c = httpx.AsyncClient(headers=headers)
# 单网页任务
async def get_data(page_id):
# 任务第一步: 获取网页信息
print(f'{time.strftime("%X")} Hello {page_id}!')
r = await c.get(f'https://movie.douban.com/top250?start={page_id}&filter=')
# 任务第二步: 解析页面信息(获取电影标题)
soup = BeautifulSoup(r.text, 'html.parser')
data = [i.span.text for i in soup.select('.item')]
print(f'{time.strftime("%X")} end {page_id}!')
return data
# 异步执行 100 个任务
async def main():
data = await asyncio.gather(*(get_data(i) for i in range(0, 250, 25)))
return data
# 执行
data = asyncio.run(main())
print(data)
'''
09:12:37 Hello 0!
09:12:37 Hello 25!
09:12:37 Hello 50!
09:12:37 Hello 75!
09:12:37 Hello 100!
09:12:37 Hello 125!
09:12:37 Hello 150!
09:12:37 Hello 175!
09:12:37 Hello 200!
09:12:37 Hello 225!
09:12:38 end 150!
09:12:38 end 25!
09:12:38 end 200!
09:12:38 end 0!
09:12:38 end 225!
09:12:38 end 175!
09:12:38 end 100!
09:12:38 end 125!
09:12:38 end 75!
09:12:38 end 50!
[['肖申克的救赎', '霸王别姬', '阿甘正传', ...
...'穿越时空的少女', '我爱你', '地球上的星星']]
用时(秒): 0.7952451705932617
'''
利用上下文管理器:
from bs4 import BeautifulSoup
import asyncio
import httpx
import atexit
import time
start = time.time()
atexit.register(lambda: print('用时(秒):', time.time()-start))
headers = {'User-Agent': 'Mozilla/5.0 Chrome/108.0.0.0 Safari/537.36'}
async def get_data():
async with httpx.AsyncClient(headers=headers) as client:
tasks = [client.get(f'https://movie.douban.com/top250?start={i}&filter=') for i in range(0, 250, 25)]
resp = await asyncio.gather(*tasks)
result = [[i.span.text for i in BeautifulSoup(r.text, 'html.parser').select('.item')] for r in resp]
# result = [r.url for r in resp]
print(result)
asyncio.run(get_data())
可以看到,异步代码同时明显很少。
(完)
更新时间:2024-01-18 17:13:28 标签:python 爬虫