吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4994|回复: 23
上一主题 下一主题
收起左侧

[Python 原创] 对大神使用deepseek所写代码的人工改进(附改进后代码)

  [复制链接]
跳转到指定楼层
楼主
chydroid 发表于 2025-3-2 01:23 回帖奖励
说明


虽然是改进的代码,但不是转载,所以还是选了Python原创类别,希望没有违反规则。
原帖子地址:https://www.52pojie.cn/thread-2009173-1-1.html
原帖子作者是:逗啊逗


原帖子所附代码确实能够实现下载博看网期刊的功能,但是在交互和代码质量方面有不少需要改进的地方。

改进之后的执行效果如下:




主要改进:


1、使用GetMagazine类来封装那一堆的方法,通过定义类属性和实例属性来减少重复代码,使代码可读书性更强。
2、增加进度条,让下载更直观地看到下载了多少。与此相关的代码请看第 7、49、53、67、69行。
3、使用多线程下载,加快了下载速度。与此相关的代码请看第6、60-66行
4、其它小的改进。

新代码如下:



[Python] 纯文本查看 复制代码
import requests
import os
import img2pdf
import re
from typing import Dict, List
import threading
from tqdm import tqdm  # 需要安装tqdm库来显示进度条

class GetMagazine:
    url_base = "https://api.bookan.com.cn/resource/"
    params_base = {"instanceId": 12696, "isDetail": 1}

    def __init__(self, journal_input_id, resource_type=3):
        self.resourceType = resource_type
        self.journal_id = journal_input_id

    def get_journal_info(self) -> Dict:
        """获取杂志详细信息
            博看网址:https://new.bookan.com.cn/page/index.html
            可以去选书,然后用此程序下载想要看的书
        """
        url = f"{self.url_base}issueInfoList"
        para = self.params_base
        para["issueIds"] = self.journal_id
        para["resourceType"] = self.resourceType

        response = requests.get(url, params=para)
        if response.status_code != 200 or response.json().get("code") != 0:
            raise Exception("获取杂志信息失败")
        return response.json()["data"][0]

    def get_image_hashes(self, resource_id: str, issue_id: str, page_count: int) -> List[Dict]:
        """获取图片hash列表"""
        url = f"{self.url_base}getHash"
        params = {"resourceId": resource_id, "issueId": issue_id, "start": 1, "end": page_count,
                  "resourceType": self.resourceType}

        response = requests.get(url, params=params)
        if response.status_code != 200 or response.json().get("code") != 0:
            raise Exception("获取图片hash失败")
        return response.json()["data"]

    def download_images(self, resource_id: str, issue_id: str, hashes: List[Dict], output_dir: str):
        """下载所有图片并保存到本地"""
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        # 获得总的进度数
        total_jpg = len(hashes)  # 下载任务的总大小为hashes的个数,也就是jpg图片的数量
        print(f"该书共有{total_jpg}页,现在开始为您下载,请耐心等待,所需时间由您的网速而定")

        # 创建一个tqdm进度条对象,初始值为0,最大值为total_jpg
        progress_bar = tqdm(total=total_jpg)

        for item in hashes:

            img_url = f"http://img1-qn.bookan.com.cn/jpage8/{resource_id}/{resource_id}-{issue_id}/{item['hash']}_big.jpg"

            if item['page'] % 2 == 0:
                thread = threading.Thread(target=self.fetch_url, args=(img_url, output_dir, item))
                thread.start()
                thread.join()
            else:
                thread = threading.Thread(target=self.fetch_url, args=(img_url, output_dir, item))
                thread.start()
                thread.join()
            progress_bar.update(1)  # 更新进度条

        progress_bar.close()  # 下载完毕关闭进度条

    # 通过独立的线程传入参数,执行图片下载操作
    @staticmethod
    def fetch_url(this_url, output_dir, item):

        try:
            response = requests.get(this_url)

            if response.status_code == 200:
                # 确保文件名格式为 page_数字.jpg
                img_path = os.path.join(output_dir, f"page_{item['page']}.jpg")
                with open(img_path, "wb") as f:
                    f.write(response.content)
            else:
                print(f"下载失败: 第{item['page']}页")

        except Exception as e:
            print(this_url, None, str(e))  # 如果发生异常,存储请求的URL和异常信息

    @staticmethod
    def create_pdf(image_dir: str, output_pdf: str):
        """将图片合并为PDF"""
        # 使用正则表达式匹配 page_数字.jpg 格式的文件
        images = []
        for img in os.listdir(image_dir):
            if re.match(r"page_\d+\.jpg", img):
                images.append(os.path.join(image_dir, img))

        # 按页码排序
        images.sort(key=lambda x: int(re.search(r"page_(\d+)\.jpg", x).group(1)))

        with open(output_pdf, "wb") as f:
            f.write(img2pdf.convert(images))

    # 程序流程控制
    def app_process(self):

        image_dir = f"temp_images_{self.journal_id}"

        try:
            # 获取书籍元数据
            journal_info = self.get_journal_info()
            resource_id = journal_info["resourceId"]
            issue_id = journal_info["issueId"]
            page_count = int(journal_info["count"])

            # 获取图片hash列表
            hashes = self.get_image_hashes(resource_id, issue_id, page_count)

            # 下载图片
            self.download_images(resource_id, issue_id, hashes, image_dir)

            # 生成PDF文件
            pdf_name = f"{journal_info['resourceName']}_{journal_info['issueName']}".replace("/", "_")[:-1] + ".pdf"
            print("下载完毕,正在生成中~~~~~~")

            self.create_pdf(image_dir, pdf_name)

            print(f"====> 生成成功: {pdf_name} ")

        except Exception as e:
            print(f"处理过程中发生错误: {str(e)}")
        finally:

            # 清理临时文件(跳过无法删除的文件)
            if os.path.exists(image_dir):
                for file in os.listdir(image_dir):
                    file_path = os.path.join(image_dir, file)
                    try:
                        os.remove(file_path)
                    except Exception as e:
                        print(f"无法删除文件 {file_path}: {str(e)}")
                try:
                    os.rmdir(image_dir)
                except Exception as e:
                    print(f"无法删除目录 {image_dir}: {str(e)}")


def main():
    url_input = input("请输入您想要下载的期刊杂志或书籍网址: ").strip()

    # 解析网址
    # 定义正则表达式模式,用于匹配查询参数
    pattern = r'[?&](type|id)=([^&]*)'

    # 使用re.findall()方法查找所有符合正则表达式的子串
    matches = re.findall(pattern, url_input)

    # 创建一个字典来存储查询参数的值
    query_params = {}

    # 遍历匹配结果,将查询参数的值存储到字典中
    for match in matches:
        key, value = match
        query_params[key] = value

    # 获取type和id的值
    type_value = query_params.get('type')
    id_value = query_params.get('id')

    type_value_c = "期刊杂志" if int(type_value) == 1 else "书籍"  # 三目运算符
    print(f"你要下载的是:{type_value_c}类型,该{type_value_c}的ID号是:{id_value}")
    print()

    # 实例化类,传入参数调用
    a = GetMagazine(id_value, type_value)
    a.app_process()


if __name__ == "__main__":
    main()


相信如果你仔细分析这100多行Pythonn代码,也一定能有更多的改进,使其更加完善,在此过程中编程水平就能得到有效提升。
最后说一下,我也是Python的初学者,与大家共勉,也希望得到各位大神的鼓励、帮助和指导。
感谢大家的无私奉献!向你们学习!

120.jpg (30.38 KB, 下载次数: 3)

120.jpg

免费评分

参与人数 8吾爱币 +14 热心值 +7 收起 理由
ny20210527 + 1 + 1 我很赞同!
Lizhongliu + 1 + 1 谢谢@Thanks!
zwc720 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
fu888 + 1 + 1 牛
姚小凌龙 + 1 谢谢@Thanks!
逗啊逗 + 2 + 1 用心讨论,共获提升!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
hiromao2010 + 1 + 1 我也在学习Python ,非常不错

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
2025lin 发表于 2025-3-14 21:17
2025lin 发表于 2025-3-14 21:13
图书的链接不是固定的,程序里面的图片链接生成需要修改一下,让程序自动适配图书的链接,不然就会报错。 ...

import requests
import os
import img2pdf
import re
import shutil
import logging
from typing import Dict, List
from concurrent.futures import ThreadPoolExecutor
from tqdm import tqdm  # 导入tqdm库

# 配置日志
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")


def get_journal_info(journal_id: str) -> Dict:
    """获取杂志详细信息"""
    url = "https://api.bookan.com.cn/resource/issueInfoList"
    params = {
        "instanceId": 12696,
        "resourceType": 3,
        "issueIds": journal_id,
        "isDetail": 1
    }
    response = requests.get(url, params=params)
    if response.status_code != 200 or response.json().get("code") != 0:
        raise Exception(f"获取杂志信息失败: {journal_id}")
    data = response.json()["data"][0]

    # 确保返回的数据中包含 webp 字段
    if "webp" not in data:
        raise ValueError(f"API 返回的数据中缺少 webp 字段: {journal_id}")
    return data


def get_image_hashes(resource_id: str, issue_id: str, page_count: int) -> List[Dict]:
    """获取图片hash列表"""
    url = "https://api.bookan.com.cn/resource/getHash"
    params = {
        "resourceType": 3,
        "resourceId": resource_id,
        "issueId": issue_id,
        "start": 1,
        "end": page_count
    }
    response = requests.get(url, params=params)
    if response.status_code != 200 or response.json().get("code") != 0:
        raise Exception(f"获取图片hash失败: {resource_id}-{issue_id}")
    data = response.json()["data"]
    if not data:
        raise ValueError(f"未获取到任何图片hash信息: {resource_id}-{issue_id}")
    return data


def download_image(item, resource_id, issue_id, output_dir, webp):
    """下载单张图片"""
    # 使用 webp 动态构造 img_url
    img_url = f"http://img1-qn.bookan.com.cn/jpage{webp}/{resource_id}/{resource_id}-{issue_id}/{item['hash']}_big.jpg"
    response = requests.get(img_url)
    if response.status_code == 200:
        img_path = os.path.join(output_dir, f"page_{item['page']}.jpg")
        with open(img_path, "wb") as f:
            f.write(response.content)
       # logging.info(f"下载成功: {output_dir} 第{item['page']}页") #, URL: {img_url}"
    else:
        logging.error(f"下载失败: {output_dir} 第{item['page']}页, URL: {img_url}")


def download_images(resource_id: str, issue_id: str, hashes: List[Dict], output_dir: str, webp: str):
    """多线程下载所有图片"""
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    total = len(hashes)
    with ThreadPoolExecutor(max_workers=5) as executor:
        # 使用tqdm显示进度条
        with tqdm(total=total, desc="下载进度", unit="页") as pbar:
            futures = [
                executor.submit(download_image, item, resource_id, issue_id, output_dir, webp)
                for item in hashes
            ]
            for future in futures:
                future.result()
                pbar.update(1)  # 更新进度条


def create_pdf(image_dir: str, output_pdf: str):
    """将图片合并为PDF"""
    images = []
    for img in os.listdir(image_dir):
        if re.match(r"page_\d+\.jpg", img):
            images.append(os.path.join(image_dir, img))

    if not images:
        raise ValueError(f"未找到任何图片文件,请检查下载过程: {image_dir}")

    logging.info(f"找到 {len(images)} 张图片: {image_dir}")
    images.sort(key=lambda x: int(re.search(r"page_(\d+)\.jpg", x).group(1)))

    # 使用tqdm显示进度条
    with tqdm(total=len(images), desc="生成PDF进度", unit="页") as pbar:
        with open(output_pdf, "wb") as f:
            f.write(img2pdf.convert(images))
        pbar.update(len(images))  # 更新进度条


def process_journal(journal_id: str):
    """处理单本书籍的下载和PDF生成"""
    image_dir = f"temp_images_{journal_id}"
    try:
        # 获取杂志元数据
        journal_info = get_journal_info(journal_id)
        resource_id = journal_info["resourceId"]
        issue_id = journal_info["issueId"]
        page_count = int(journal_info["count"])
        webp = journal_info["webp"]  # 获取 webp 值

        # 获取图片hash列表
        hashes = get_image_hashes(resource_id, issue_id, page_count)
        logging.info(f"hashes for {journal_id}: {hashes}")

        # 下载图片
        logging.info(f"开始下载图片: {journal_id}")
        download_images(resource_id, issue_id, hashes, image_dir, webp)

        # 生成PDF文件
        pdf_name = f"{journal_info['resourceName']}_{journal_info['issueName']}.pdf".replace("/", "_")
        create_pdf(image_dir, pdf_name)
        logging.info(f"PDF生成成功: {pdf_name}")

    except Exception as e:
        logging.error(f"处理过程中发生错误: {journal_id}, {str(e)}")
        import traceback
        traceback.print_exc()
    finally:
        # 清理临时文件
        if os.path.exists(image_dir):
            try:
                shutil.rmtree(image_dir)
            except Exception as e:
                logging.error(f"无法删除目录 {image_dir}: {str(e)}")


def main():
    # 输入多个期刊杂志ID,用逗号或空格分隔
    journal_ids_input = input("请输入期刊杂志ID(多个ID用逗号或空格分隔): ").strip()
    if not journal_ids_input:
        logging.error("期刊杂志ID不能为空")
        return

    # 分割输入为多个ID
    journal_ids = re.split(r"[,\s]+", journal_ids_input)

    # 处理每本书籍
    for journal_id in journal_ids:
        logging.info(f"开始处理期刊: {journal_id}")
        process_journal(journal_id)
        logging.info(f"期刊处理完成: {journal_id}")


if __name__ == "__main__":
    main()你可以尝试用这个下载图书(杂志的需要修改类型,没做到两者合并),使用也很简单,找到需要的图书ID,如:310518779,输入到下面即可,也可以一次下载多本图书,中间使用英文逗号间隔即可,希望可以帮到你
推荐
2025lin 发表于 2025-3-14 21:13
timryde 发表于 2025-3-14 13:11
http://new.bookan.com.cn/page/detail.html?type=3&id=310518779
这本书是多少,改了好几个数字都下载 ...

图书的链接不是固定的,程序里面的图片链接生成需要修改一下,让程序自动适配图书的链接,不然就会报错。类似于这种:  
# 使用 webp 动态构造 img_url
    img_url = f"http://img1-qn.bookan.com.cn/jpage{webp}/{resource_id}/{resource_id}-{issue_id}/{item['hash']}_big.jpg"
沙发
 楼主| chydroid 发表于 2025-3-2 01:28 |楼主
还有一点未说的改进就是由输入ID码,变为粘贴从博看网复制的网址即可,适合书籍和期刊。
3#
lsp5454 发表于 2025-3-2 11:24
赞一个,好东东,准备一试
4#
Windows10 发表于 2025-3-2 14:45
所以AI代码还是有一些瑕疵的
5#
z94213715 发表于 2025-3-2 15:09
尝试着学习一下,感谢分享!
6#
hiromao2010 发表于 2025-3-2 16:24
学习中,非常好
7#
逗啊逗 发表于 2025-3-3 11:13
感谢认可,不是什么大神,也是python初学者,另外代码有一点小改动,可以参考我帖子置顶评论。
8#
zhangxingzhong 发表于 2025-3-3 12:34
学习的,菜鸟路过
9#
lbg2222000 发表于 2025-3-4 20:09
这个很好
10#
hbwhbw91 发表于 2025-3-5 08:44
学习中,非常厉害
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-10-22 16:25

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表