爬虫案例-01

"""
将就看看吧,写太详细了过不了QAQ


本网站的文件是直接写在页面上的
尝试将线程池和协程连起来用

1.找到章节下载链接
2.下载小说文本(协程异步下载)
3.存放文件
4.执行分页

"""
import os
import requests
import asyncio
import aiohttp
import aiofiles
import time
from bs4 import BeautifulSoup
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor

header={
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
    "Referer":"https://www.bbiquge.net/"
    }

global name # 定义全局变量,用来保存书籍名字方便文件的分类


# 下载小说内容,异步操作下载
async def dowload(down_url):
    async with aiohttp.ClientSession() as session:
        async with session.get(down_url) as resp:
            data = await resp.read()
            res = BeautifulSoup(data,"html.parser").find('div',attrs={'id':'content'}).text # 获取文本内容
            ress = BeautifulSoup(data,"html.parser").find('h1').text # 获取小说章节名字
            print(ress+'下载中')
            file_path = f'../file/小说/{name}/{ress}.txt' # 设置保存的路径和文件名及文件格式,这里用的是相对路径
            async with aiofiles.open(file_path,'w',encoding='utf-8') as f: # aiofiles 异步文件操作
                 await f.write(res)
                 print(ress+'下载完成')


# 传入的是每页的链接,获取章节下载链接
async def getUrl(url):
    res = requests.get(url,headers=header,verify=False) # verify=False 将安全模式关闭,这里是因为在我调试过程中访问太多次后上不去了才用的
    print(url)
    resp = BeautifulSoup(res.text,"html.parser").find('div',attrs={'class':'zjbox'}).findAll('dd')
    task=[] # 用于保存异步任务
    # 每一个url都是一个异步协程操作
    for line in resp:
        if line.find('a') is not None:
            down_url = url.rsplit('/',1)[0]+'/'+ line.find('a')['href']
            # 准备异步任务
            task.append(asyncio.create_task(dowload(down_url))) # 添加异步任务,添加时要将任务转为task即asyncio.create_task()  (旧一点的版本可以直接添加,由系统自动转。这里用的是py3.11版本)

    await asyncio.wait(task) # 等待异步添加完成


# 获取小说名字,方便文件管理
def get_name(url):
    global name
    # split('/')[0].strip() 对名字进行处理,文件夹名不能含有空格,其他字符等
    name = BeautifulSoup(requests.get(url,headers=header,verify=False).text,"html.parser").find('h1').text.split('/')[0].strip()
    path = f'../file/小说/{name}'
    os.makedirs(path, exist_ok=True) # 若文件不存在则创建,存在则跳过
    print(name)

def bq(url):
    asyncio.run(getUrl(url))



if __name__ == '__main__':
    t1 = time.time() # 检测用时

    url = input("输入要下载书籍的首页:")
    ye = int(input("请输入该书籍的页数:"))
    get_name(url)

    # 这里开了线程池,具体有没有用就不大清楚了。我只测了一组,快了50秒左右,也有可能是网络原因,各位可以去多测几组看看
    with ThreadPoolExecutor(50) as t:
        for i in range(1,ye + 1):
            if(i==1):
                t.submit(bq,url)
            else:
                durl = url + f"index_{i}.html"
                t.submit(bq,durl)

    t2 = time.time()
    print(t2-t1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值