url越多越适合使用异步协程进行编程。
爬取西游记:
“data = resp.json()['data']['novel']['items']”
cid = item['cid'] title = item['title']
这个代码就是找到items,因为items里面有title和cid。然后再提取出items中的title和cid。
爬取每个章节的的book_id和c_id时使用同步操作即可。代码如下:
resp = requests.get(url)
data = resp.json()['data']['novel']['items']
print(data)
tasks = [] # 异步任务列表
# 获取每一个章节的id获取小说内容, 同步任务进行也可以。下载各章节内容时,需要异步任务进行
for item in data: # item就是对应每个章节的名称和cid
cid = item['cid']
title = item['title']
tasks.append(asyncio.create_task(getChapterContent(title, cid)))
因为每一个章节内容都有一个url,所以下载章节内容时用异步操作进行比较合适。
async def getChapterContent(title, cid):
data = {
'book_id': b_id,
'cid': b_id + '|' + cid, # 在url中 cid 是 book_id | cid
'need_bookinfo': 1
}
# 获取章节内容的url json.dumps(data):将data变为字符串格式
url = "https://dushu.baidu.com/api/pc/getChapterContent?data=" + json.dumps(data)
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
dic = await resp.json()
print(dic)
# 将章节内容写入文件(异步形式写入)
async with aiofiles.open(f'西游记/{title}', mode='w', encoding='utf-8') as f:
await f.write(dic['data']['novel']['content'])
import json
import requests
import asyncio
import aiofiles # pip install aiofiles
import aiohttp # pip install aiohttp
"""
1.同步操作: 访问getCatalog 拿到所有章节的cid和名称
2.异步操作: 访问getChapterContent 下载所有的文章内容
"""
# 同步操作(requests.get)拿到cid 和 b_id
async def getCatalog(url):
"""
获取小说的章节目录
:param url: 获取小说的章节目录的URL
:return:
"""
resp = requests.get(url)
data = resp.json()['data']['novel']['items']
print(data)
tasks = [] # 异步任务列表
# 获取每一个章节的id获取小说内容, 同步任务进行也可以。下载各章节内容时,需要异步任务进行
for item in data: # item就是对应每个章节的名称和cid
cid = item['cid']
title = item['title']
# 准备异步任务
tasks.append(asyncio.create_task(getChapterContent(title, cid)))
await asyncio.wait(tasks)
# 下载各章节内容,必须异步进行
async def getChapterContent(title, cid):
"""
根据章节id获取小说内容
:param title: 章节名称
:param cid: 章节id
:return:
"""
data = {
'book_id': b_id,
'cid': b_id + '|' + cid, # 在url中 cid 是 book_id | cid
'need_bookinfo': 1
}
# 获取章节内容的url json.dumps(data):将data变为字符串格式
url = "https://dushu.baidu.com/api/pc/getChapterContent?data=" + json.dumps(data)
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
dic = await resp.json()
print(dic)
# 将章节内容写入文件(异步形式写入)
async with aiofiles.open(f'西游记/{title}', mode='w', encoding='utf-8') as f:
await f.write(dic['data']['novel']['content'])
if __name__ == '__main__':
b_id = '4306063500' # 书本id
data = {'book_id': b_id}
# 获取章节目录的URL
url = 'https://dushu.baidu.com/api/pc/getCatalog?data={"book_id": "'+ b_id + '" }'
asyncio.get_event_loop().run_until_complete(getCatalog(url))