book118可预览文档下载

book118可预览文档下载@TOC

book118可预览文档下载

最早从csdn上搜到的book118可预览文档下载方法是js代码,很简短的一段,然后在开发者工具里使用。按步骤一回车即可下载。

function download(url, fileName) {
    let xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);//true表示异步
    xhr.responseType = 'blob';
    xhr.onload = () => {
        if (xhr.status === 200) {
           downloadByA(xhr.response,fileName);
        }
    };
    xhr.send();
}
function downloadByA(data,fileName){
	let urlObject = window.URL || window.webkitURL || window;
	let export_blob=new Blob([data]);
	let a=document.createElement("a");
	a.href=urlObject.createObjectURL(export_blob);
	a.download=fileName;
	a.click();
}
//下面这块代码需要按自己需求,进行稍微地修改,上面两块代码可以不用动
document.querySelectorAll(".pageBox img").forEach(function(ele, i) {
    download(ele.src,i+".jpg");
});

原文链接在这里文章链接

但是使用以后发现有问题,文件页数一多就出现缺页情况。
再次搜索发现了python实现的代码。
Py3 下载book118预览图片并合并成docx文件文章链接
就拷贝测试了一下,发现作者的源码有问题,然后进行了部分更正,和格式调整。
中间除了点list和函数间调用时的bug。
然后增加了用pymupdf 模块 生产pdf文件的步骤,毕竟pdf更方便的多,反正下载的也是不可编辑的png图片。

#!/usr/bin/env python
# coding: utf-8

# In[1]:


# -*- coding: utf-8 -*-


# In[2]:


import requests


# In[3]:


import json


# In[4]:


import re


# In[5]:


import time


# In[6]:


import os


# In[7]:


import sys


# In[8]:


import lxml


# In[9]:


from bs4 import BeautifulSoup


# In[10]:


from docx import Document


# In[11]:


from docx.shared import Cm


# In[12]:


import glob


# In[13]:


import fitz


# In[14]:


headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'}
    


# In[15]:


mylist=[]


# In[16]:


#定义保存地址


# In[17]:


def path1():
    path1=input('please input path:')
    if len(path1)< 2:
        path1 = 'C:\\tmp'
    if os.path.exists(path1) == False:
        os.makedirs(path1)

    mylist.append(path1)
    


# In[18]:


#len(path1)


# In[19]:


#获取真实预览地址turl
def turl():
    url = input('please input url:')
    if len(url)<10:
        url = 'https://max.book118.com/html/2017/0323/96553980.shtm'
    aid = re.search('\d{1,100}\.s',url).group()[:-2]
    rep = requests.get(url, headers=headers)
    soup = BeautifulSoup(rep.content, 'lxml', from_encoding='utf-8')
    title = soup.title.contents[0]
    title = title[:title.find('.')]
    #time.sleep(2)
    turl = 'https://max.book118.com/index.php?g=Home&m=NewView&a=index&aid={}'.format(aid)
    #print('turl:',turl)
    mylist.append(turl)
    mylist.append(title)
    #print(mylist)
    

    


# In[20]:


def bookinfo():
    
    turl()
    #获取预览信息,放在book中
    rep2 = requests.get(mylist[1], headers=headers)
    #time.sleep(8)
    if '验证' in rep2.text:
        
        print('need verify')
        print(rep2.text)
    else:
        bs = BeautifulSoup(rep2.content,'lxml', from_encoding='utf-8')
        for i in bs.find_all('script'):
            js = i.string
            if js is not None and 'PREVIEW_PAGE' in js:
                p1 = re.compile(".+?'(.+?)'")
                js_line = js.splitlines(1)
                book = {
                    'pageAll':p1.findall(js_line[1])[0],
                    'pagePre':p1.findall(js_line[1])[1],
                    'aid':p1.findall(js_line[7])[0],
                    'viewToken':p1.findall(js_line[7])[1],
                    'title':mylist[2]
                    }
                print("ok")     
            else:
    
                print("")
    
    print('book:',book)
    mylist.append(book)
     


# In[21]:


def prepage_url():
    
    #利用book中的信息获取预览图片地址,放在url_dict中
    page = {
        'max':int(mylist[3]['pageAll']),
        'pre':int(mylist[3]['pagePre']),
        'num':1,
        'repeat':0
        }  
    #设置循环,尽量获取全部预览图片的地址
    url3_dict = {}
    while page['num'] < page['pre']:        
        url3 = 'https://openapi.book118.com/getPreview.html' 
        playload = {
            'project_id': 1,
            'aid': mylist[3]['aid'],  
            'view_token': mylist[3]['viewToken'], 
            'page': page['num']
            }
        rep3 = requests.get(url3, params=playload, headers=headers)    
        rep3_dict = json.loads(rep3.text[12:-2])    
        if rep3_dict['data'][str(page['num'])]:
            
            url3_dict.update(rep3_dict['data'])
            page['num'] = page['num'] + 6
            time.sleep(3)
            page['repeat'] = 0
        else:
            if page['repeat'] > 6:
                sys.stdout.write('\r{0}'.format(str(page['num']) + " : Repeat too much.\n !get nothing, sleep 5 second."))
                sys.stdout.flush()
                time.sleep(3)
            else:
                sys.stdout.write('\r{0}'.format(str(page['num']) + " : !get nothing, sleep 2 second."))
                sys.stdout.flush()
                time.sleep(3)
            page['repeat'] = page['repeat'] + 1
        
    print(url3_dict) 
    mylist.append(url3_dict)
    


# In[22]:


def download():
    
    #指定文件夹path
    path=mylist[0] + '/{}'.format(mylist[2])
    
    if os.path.exists(path) == False:
        os.makedirs(path)
    
    #下载预览图片到path,并合并到docx文件
    myDocx = Document()
    for section in myDocx.sections:
        
        section.page_width = Cm(21)
        section.page_height = Cm(29.7)
        section.left_margin = section.right_margin = section.top_margin = section.bottom_margin = Cm(0)
    for item in mylist[4]:
        
        try:
            num = 'Page{:0>3}'.format(item)
            url_item=mylist[4][item]
            url_item=url_item[url_item.index('view'):]
            url = 'http://' + url_item#根据url_dict内url的完整度进行调整
            print('url:',url,';')
            rep = requests.get(url, headers=headers)
            img_filename = path + '/{}.png'.format(num)
            with open(img_filename, 'wb') as img:
                img.write(rep.content)
            print('Saved locally img_filename:',img_filename)
            myDocx.add_picture(img_filename, width=Cm(21))
        except:
            print('{} download wrong'.format(item))
    
    myDocx.save('{}.docx'.format(mylist[2]))
    mylist.append(path)
    return
    


# In[23]:


def pic2pdf():
    doc = fitz.open( )
    path=mylist[5]+"/*"
    #print(mylist[5])
    a1=len(mylist[0]) + 1
    name=mylist[5][a1:]+".pdf"
    print(name)
    for img in sorted(glob.glob(path)):
        assert isinstance(img, object)
        #print(img)
        imgdoc = fitz.open(img)
        pdfbytes = imgdoc.convertToPDF()
        imgpdf = fitz.open("pdf", pdfbytes)
        doc.insertPDF(imgpdf)
    if os.path.exists(name):
        os.remove(name)
    doc.save(name)
    doc.close()


# In[24]:


def main():    
    path1()
    bookinfo()
    prepage_url()
    download()
    print('all done')
    number = input('是否需要输出pdf:(是打1,否打其他)')
    if int(number) == 1:
        pic2pdf()
        print("pdf's done")
    else:
        print('88')
        
    
    


# In[25]:


if __name__ == '__main__':
    
    main()

用到的模块包括
requests
json
re
time
os
sys
lxml
bs4
python-docx
pymupdf

为了好看,把代码分成了五个函数。其实不做成函数也一样用,还更简单些,不会出莫名其妙的麻烦。

图片存放地址是path1(默认定义的是c盘tmp目录)下,会根据下载的文档名称生成新的子目录。
下载的doc和pdf文件会在程序本地。
ps:1.windows下""在路径里会出错。
2.{}。format()是一种字符串格式化的方法。
3.跨函数调用的时候,return值会缺少某些属性
4.python在识别路径的时候对\和/都很友好。

下一步加一个界面。
用pyinstaller 打包的时候 跑到另一个xp的机器上测试,结果发现了一个错误
pil/_imaging.cp38-win32.pyd文件找不到。
因为其他电脑都装了python,暂时还没去处理这个问题。回头再继续debug。

测试了一个195页的文件,没有出现错误。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_39972887

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值