简述

在浏览漫画网站的时候,我们总是希望可以一件下载这篇漫画,并以一个方便的格式保存下来,手动的方式是一张张图片按章节保存成文件夹,但是这样的方式不适合在多种设备上阅读,或者做书签。这个时候,我们可以通过写一些简单的脚本,通过输入网址,就把漫画以 PDF 的格式保存下来。

EH 上的尝试

说明

EH 是一个很大的同人漫画网站,用于较大的漫画资源库,是一个不错的尝试目标

程序设计

  • 语言: Python
  • 主要的库:requests、flask、reportlab、Pillow、multiprocessing

实现方式

  1. 输入一个网址
  2. 使用 requests 库抓取所有漫画页面,并按顺序保存在一个文件夹下
  3. 编写一个函数,调用 reportlab ,把文件夹下的图片按顺序保存为合适大小的 PDF 文件
  4. 保存 PDF 文件

做一个下载服务网页

在实现了基本功能之后,我们可以将这个功能部署到一台服务器上,这样就可以在更多的设备上下载到 PDF ,并且如果配合自动化软件比如 Workflow ,就可以实现在移动设备上的一键下载 PDF 漫画。

程序设计

  • 需要语言: Python、html、js
  • 主要的库:flask、multiprocessing

实现方式

  1. 使用 URL 的参数传入一个网址
  2. 后端下载 PDF, 前端实时显示进度条、漫画名称、总页数
  3. 后端下载完成之后,可通过前端的“下载”按钮进行 PDF 的下载
  4. 使用 multiprocessing 实现多个漫画同时下载

部分代码

  1. 图片转 PDF 的代码:
# 这个函数返回保存的PDF的文件路径
def pic2pdf(path, name, savepath = './temp/'):
    fs = os.listdir(path)
    # 删除非支持文件,并按照文件名排序
    for each in fs: 
        if ('.jpg' or '.png' or '.jpeg') not in each:
            fs.remove(each)
    fs = sorted(fs)
    # 寻找适合的画布大小
    # w = 0
    # h = 0
    # for each in fs:
    #     img = Image.open(path+each)
    #     iw, ih = img.size
    #     w = max(w,iw)
    #     h = max(h,ih)
    # 确定PDF的名称,并生成PDF
    f_pdf = savepath + name+'.pdf'
    c = canvas.Canvas(f_pdf)
    for each in fs:
        # (w, h) = landscape(A4)
        img = Image.open(path+each)
        c.setPageSize(img.size)
        # print(c._pagesize)
        c.drawImage(path+each, 0, 0, img.size[0], img.size[1])
        c.showPage()
    c.save()
    return f_pdf

  1. 下载漫画图片的代码:
@app.route('/get/<regex(".*"):url>')
def getimg(url):
    try:
        html = requests.get(url, headers = header, proxies = proxy).text

        soup = BeautifulSoup(html,'lxml')
        
        if 'Prev Page' in html:
            print('This is not the first page!')
            return "Error This may not the first page!"

        print(soup.title.string)
        name = str(soup.title.string)
        name = name[:name.find(' Page 1')]
        m = int(re.findall('(.*?)/(.*)',str(soup.find_all('td')[1].text))[0][1])
    except:
        return html

    para['title'] = name
    para['sn'] = ''.join(random.sample(string.ascii_letters + string.digits, 16))
    os.popen('mkdir temp/%s'%para['sn'])
    para['total'] = m
    lastR = render_template("down.html",
                            para = para)
    p = Process(target=download,args=(soup, m, para['sn'], ProcDict))
    p.start()
    return lastR

效果图

图片大概 3M 请耐心等待加载完成

Preview

备注

对,这就是方便 Pad 下本子的 (*ゝω・)

@Aeonni 写于2018.08.21

转载请注明出处