python爬取漫画保存为一个pdf

同学说想看某漫画,在网站上广告比较多,问我能不能爬一下,研究了一天爬了下来,记录一些遇到的小问题

爬虫部分

这部分就是无脑找到图片链接直接下载就可以,对每章节遍历,然后对章节内所有图遍历,代码贴在下面,有一个小tips,有的图片通过requests方法直接下载存在文件损坏情况,使用urllib.request.urlopen方法可以正常下载。

# 从首页爬取章节网址
def getChapter(url):
    response = requests.get(url) # 使用requests库的get方法向指定URL发送GET请求,并将响应保存在response变量中
    soup = BeautifulSoup(response.text, 'html.parser') # 使用BeautifulSoup库解析response文本内容,指定解析器为html.parser
    chapters = soup.find_all('a') # 使用BeautifulSoup库的find_all方法查找所有的a标签,并将结果保存在chapters 变量中
    result = []
    # 截取有效标签中的href属性
    for i in chapters[23:-5]:
        chapter_url = i['href']
        result.append(chapter_url)
    return result

# 从具体的图片原地址下载图片
def getImg (img_url, img_name) :
    img_url = urllib.request.Request(img_url)
    # 将url页面的源代码保存成字符串
    bimg = urllib.request.urlopen(img_url).read()
    with open(f'images/{img_name}', 'wb') as f: # 以二进制写模式打开名为images/xxx的文件,xxx为图片名称
        f.write(bimg) # 将图片数据写入文件中
        print(f'下载完成:{img_name}') # 输出下载完成信息
        
# 从章节网址读取所有内容图片地址
def getImgurl(imgsurl,chapter):
    response = requests.get(imgsurl) # 使用requests库的get方法向章节网址发送GET请求,并将响应保存在response变量中
    soup = BeautifulSoup(response.text, 'html.parser') # 使用BeautifulSoup库解析response文本内容,指定解析器为html.parser
    img_tags = soup.find_all('img') # 使用BeautifulSoup库的find_all方法查找所有的img标签,并将结果保存在img_tags变量中
    pages = soup.find_all('p')[0].get_text() # 因为漫画存在分页(x/x),所以获取一下总页数数据
    now_total = pages.split('/')
    page = round(int(now_total[1]) / int(now_total[0])) # 根据每页图片数确定章节总页数
    for i in range(page):
        for num,img in enumerate(img_tags): # 遍历所有img_tags
            img_url = img.get('src') # 获取当前img标签的src属性值,即图片的URL
            if not img_url.startswith('http'): # 如果图片URL不是以http开头,说明是一个相对路径,需要将其拼接成完整URL
                img_url = url + img_url
            # print(img_url)
            now_page = num + i * 5 + 1
            if now_page >= 10:
                img_name = str(chapter) + '-' + str(now_page) + '.jpg'
            else:
                img_name = str(chapter) + '-0' + str(now_page) + '.jpg'
            if now_page == int(now_total[1]):
                return
            getImg(img_url, img_name)
        response = requests.get(imgsurl[:-5] + '-' + str(i+2) + '.html')  # 使用requests库的get方法向指定URL发送GET请求,并将响应保存在response变量中
        soup = BeautifulSoup(response.text, 'html.parser')  # 使用BeautifulSoup库解析response文本内容,指定解析器为html.parser
        img_tags = soup.find_all('img')  # 使用BeautifulSoup库的find_all方法查找所有的img标签,并将结果保存在img_tags变量中

合并为pdf部分

下载完的图片保存在一个文件夹里,一般量少情况可以直接使用PIL.Image.save方法将图片转为单页pdf然后按页拼接保存,但是经过实验后发现超过3000张图片后需要8h+。
所以采用其他方法,save方法在少量图片情况下性能可以接受,可以将大量图片分批转为pdf,然后采用PyPDF2的PdfMerger()方法将生成的pdf进行合并,代码如下。

# 将jpg图片转为pdf,函数中设置为20张图片拼接为一个pdf,超过20张速度会变慢
def image_to_pdf(picture_path):
    imagelist = []
    picName_lst = os.listdir(picture_path)
    print(picName_lst)
    i = 1
    savefilepath = str(i) + "_xxxxx" + ".pdf"
    for j, el in enumerate(picName_lst):
        print(j+1)
        new_path = os.path.join(picture_path, el)
        image = Image.open(new_path)
        image.convert("RGB")
        imagelist.append(image)
        im1 = imagelist[0]
        im_rest = imagelist[1:]
        # 此方法对少量图片可直接拼接为pdf
        im1.save(savefilepath, save_all=True, append_images=im_rest)
        if (j+1)%20 == 0:
            i = i + 1
            imagelist = []
            savefilepath = str(i) + "_xxxxx" + ".pdf"
# 将多个pdf合并
def mergerpdf(target_path):
    pdf_lst = [f for f in os.listdir(target_path) if f.endswith('.pdf')]
    pdf_lst = [os.path.join(target_path, filename) for filename in pdf_lst]
    # 注意顺序,合并顺序为 001 002 ... 010 ... 020 ... 100, 要将位数少的高位补零 
    print(pdf_lst)
    file_merger = PdfMerger()
    i = 1
    for pdf in pdf_lst:
        file_merger.append(pdf)  # 合并pdf文件
        print(i)
        i = i + 1
    file_merger.write(r"合并文档.pdf")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值