爬虫部分
这部分就是无脑找到图片链接直接下载就可以,对每章节遍历,然后对章节内所有图遍历,代码贴在下面,有一个小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")