實踐:異步實戰—爬取小説

24. 實戰:用異步爬蟲“扒光“一部小説_Vec_ci

24. 實戰:用異步爬蟲“扒光“一部小説_Vec_ci_02

 

 

 

一、找取內容加載的js異步接口,然後會發現這是其中一章的內容,id=1569782244,所以需要去找齊所有章節的id

24. 實戰:用異步爬蟲“扒光“一部小説_Vec_#開發語言_03

24. 實戰:用異步爬蟲“扒光“一部小説_Vec_#開發語言_04

 

 

二、找齊所有章節的id

24. 實戰:用異步爬蟲“扒光“一部小説_Vec_json_05

24. 實戰:用異步爬蟲“扒光“一部小説_Vec_異步任務_06

所以就可以通過該網址來爬取所有章節的id,並提取出來每一章的題目以及id值

async def getbook_id(url):    resp=requests.get(url)
    dic=resp.json()
    tasks=[]
    for a in dic["data"]["novel"]["items"]:
        title=a["title"]+".txt"
        cid=a["cid"]

三、找齊id後,拼接小説每一章對應的網址url

data = {    "book_id":book_id,
    "cid":f"{book_id}|{cid}",
    "need_bookinfo":1
}
data=json.dumps(data)
url=f"https://dushu.baidu.com/api/pc/getChapterContent?data={data}"

四、將爬取每一個章節任務都劃入到tasks中

async def getbook_id(url):    resp=requests.get(url)
    dic=resp.json()
    tasks=[]
    for a in dic["data"]["novel"]["items"]:
        title=a["title"]+".txt"
        cid=a["cid"]
        #準備異步任務
        tasks.append(asyncio.create_task(getcontent(book_id,cid,title)))  #將每個章節的爬取任務添加到任務列表中
    await asyncio.gather(*tasks)

 

五、將章節寫入保存到novels文件夾

async with aiohttp.ClientSession() as session: #創建異步HTTP客户端會話    async with session.get(url,data=data) as resp:
        dic=await resp.json()# 異步解析響應內容為JSON格式的字典
        content=dic["data"]["novel"]["content"] #從響應數據中提取小説章節內容
        async with aiofiles.open(f"novels/{title}",mode='w',encoding="utf-8") as f: # 使用異步文件操作庫aiofiles,以寫入模式打開文件
            await f.write(content)

六、完整代碼以及運行結果

import asyncioimport aiohttp
import aiofiles
import requests
import json


async def getcontent(book_id,cid,title):
    data = {
        "book_id":book_id,
        "cid":f"{book_id}|{cid}",
        "need_bookinfo":1
    }
    data=json.dumps(data)
    url=f"https://dushu.baidu.com/api/pc/getChapterContent?data={data}"
    async with aiohttp.ClientSession() as session: #創建異步HTTP客户端會話
        async with session.get(url,data=data) as resp:
            dic=await resp.json()# 異步解析響應內容為JSON格式的字典
            content=dic["data"]["novel"]["content"] #從響應數據中提取小説章節內容
            async with aiofiles.open(f"novels/{title}",mode='w',encoding="utf-8") as f: # 使用異步文件操作庫aiofiles,以寫入模式打開文件
                await f.write(content)

async def getbook_id(url):
    resp=requests.get(url)
    dic=resp.json()
    tasks=[]
    for a in dic["data"]["novel"]["items"]:
        title=a["title"]+".txt"
        cid=a["cid"]
        #準備異步任務
        tasks.append(asyncio.create_task(getcontent(book_id,cid,title)))  #將每個章節的爬取任務添加到任務列表中
    await asyncio.gather(*tasks)

if __name__=="__main__":
    book_id="4306063500"
    url='https://dushu.baidu.com/api/pc/getCatalog?data={%22book_id%22:%22'+book_id+'%22}'
    await getbook_id(url)

24. 實戰:用異步爬蟲“扒光“一部小説_Vec_ci_07