pdf处理
pdf是二进制文件,使用PyPDF2
模块进行处理,安装方法pip install PyPDF2
。
提取文本
- 导入PyPDF2模块,然后以读二进制模式打开pdf文件,并将其保存到对象pdfFileObj。
- 调用pdfFileReader()并传入pdfFileObj,将PdfFileReader对象保存到pdfReader。
- 获取pdf文件总页数调用PdfFileReader对象的
numPages
属性。 - 从某页中提取文本,首先通过PdfFileReader对象的
getPage()
方法得到Page对象,然后调用Page对象的extractText()
方法得到文本字符串。1
2
3
4
5
6
7import PyPDF2
pdfFileObj = open("test.pdf", 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFileObj)
print(pdfReader.numPages) #文件总页数
pageObj = pdfReader.getPage(0) #下标从0开始
pageObj.extractText()
解密pdf
当pdf文件加密时,需要传入密码才能正常打开,此时使用decrypt()
函数传入密码即可。1
2
3
4
5
6
7import PyPDF2
pdfFileObj = open("test.pdf", 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFileObj)
print(pdfReader.isEncrypted) #是否加密,是返回True,否则返回False
pdfReader.decrypt("123456")
pageObj = pdfReader.getPage(0)
创建pdf
创建pdf使用PdfFileWriter
对象。但是该模块不允许直接编辑pdf文件,一般都是从其他pdf拷贝页面。
- 打开一个或多个pdf文件,得到PdfFileReader对象。
- 创建一个新的PdfFileWriter对象。
- 将页面从PdfFileReader对象拷贝到PdfFileWriter对象。
- 利用PdfFileWriter对象写入输出到pdf。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19pdf1File = open("test1.pdf", "rb")
pdf2File = open("test2.pdf", "rb")
pdf1Reader = PyPDF2.PdfFileReader(pdf1File)
pdf2Reader = PyPDF2.PdfFileReader(pdf2File)
pdfWriter = PyPDF2.PdfFileWriter()
for pageNum in range(pdf1Reader.numPages):
pageobj = pdf1Reader.getPage(pageNum)
pdfWriter.addPage(pageobj)
for pageNum in range(pdf2Reader.numPages):
pageobj = pdf2Reader.getPage(pageNum)
pdfWriter.addPage(pageobj)
pdfOutputFile = open("tst_com.pdf", "wb")
pdfWriter.write(pdfOutputFile)
pdfOutputFile.close()
pdf1File.close()
pdf2File.close()
注意:此处addPage()
方法只能在末尾添加页面,PyPDF2不支持在中间插入页面。
pdf转换
pdf转换使用pdfkit
模块,安装方法pip install pdfkit
。
由于pdfkit模块是wkhtmltopdf工具的封装,所以需要安装该工具,点击wkhtmltopdf至官方下载地址,根据操作系统版本选择下载安装即可。安装之后将bin执行文件路径添加到PATH变量中。
网页转换为pdf
1
2
3import pdfkit
pdfkit.from_url("12345", "output1.pdf")html转换为pdf
1
2
3import pdfkit
pdfkit.from_file("12345.html", "output2.pdf")字符转换成pdf
1
2
3import pdfkit
pdfkit.from_string("12345", "output3.pdf")
实例
抓取linux教程然后制作成pdf文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import codecs
import os
import sys
import pdfkit
import requests
base_url = 'http://www.apelearn.com/study_v2/'
if not os.path.exists("aming"):
os.mkdir("aming")
os.chdir("aming")
s = requests.session()
for i in range(1, 27):
url = base_url + 'chapter' + str(i) + '.html' #拼接网页url
file = str(i) + '.pdf'
try:
pdfkit.from_url(url, file)
except:
continue将生成的多个pdf文件合并成1个pdf。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import codecs
import PyPDF2
import os
files = list()
for fileName in os.listdir("aming"):
if fileName.endswith(".pdf"):
files.append(fileName)
newFiles = sorted(files, key=lambda d: int(d.split(".pdf")[0])) #按照章节进行排序,默认为ASCII码排序
os.chdir("aming")
pdfWriter = PyPDF2.PdfFileWriter() #生成一个空白的pdf
for item in newFiles:
pdfReader = PyPDF2.PdfFileReader(open(item, "rb"))
for page in range(pdfReader.numPages):
pdfWriter.addPage(pdfReader.getPage(page))
with codecs.open("aminglinux.pdf", "wb") as f:
pdfWriter.write(f)
图片处理
python3中使用pillow
模块,安装方法pip install pillow
,使用的时候导入方法from PIL import Iamge
。
image的属性
- format
识别图像的源格式,如果该文件不是从文件读取,则置为None。 - size
返回一个元组,包含2个元素,值为像素意义上的宽和高。 - mode
包括RGB(true color image)/L(luminance)/CMTK(pre-press image)。image的方法
- image.show()
显示最近加载的图像 - image.open(file)
打开文件 - image.save(outputfile)
保存文件 - image.crop(left, upper, right, lower)
从图像中提取某个矩形大小的图像。它接受一个四元素的元组作为参数,坐标系统的原点(0,0)是左上角。
Image的几何处理: - im.resize((128, 128))
调整图片大小 - im.rotate(45)
逆时针旋转 45 度角。 - im.transpose(Image.FLIP_LEFT_RIGHT)
左右对换。 - im.transpose(Image.FLIP_TOP_BOTTOM)
上下对换。 - im.transpose(Image.ROTATE_90)
旋转 90 度角。 - im.transpose(Image.ROTATE_180)
旋转 180 度角。 - im.transpose(Image.ROTATE_270)
旋转 270 度角。实例
显示图片信息并查看图片
1
2
3
4
5from PIL import Image
image = Image.open("test.jpg")
print(image.format, image.size, image.mode)
image.show()抠图
将图片指定区域进行裁剪并保存在cutting.jpg中。1
2
3
4
5
6
7from PIL import Image
image = Image.open("test..jpg")
print(image.format, image.size, image.mode)
box = (600, 300, 1050, 660)
region = image.crop(box)
region.save("cutting.jpg")图片拼合
将指定区域的图片截取出来并旋转180度,然后拼接在一起1
2
3
4
5
6
7
8
9
10from PIL import Image
image = Image.open("test..jpg")
print(image.format, image.size, image.mode)
box = (600, 300, 1050, 660)
egion = image.crop(box)
#egion.save("cutting.jpg")
region = egion.transpose(Image.ROTATE_180)
image.paste(region, box)
image.show()图片缩放
1
2
3
4
5
6
7
8
9
10from PIL import Image
infile = "test.jpg"
outfile = "newtest.jpg"
image = Image.open(infile)
(x, y) = image.size
newx = 300
newy = int(y*newx/x)
out = image.resize((newx, newy), Image.ANTIALIAS)
out.show()验证码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41import random
import string
from PIL import Image, ImageFont, ImageDraw, ImageFilter
font_path = "msyh.ttf"
number = 4
size = (100, 30)
bgcolor = (255, 255, 255)
fontcolor = (0, 0, 255)
linecolor = (255, 0, 0)
draw_line = True
# 加入干扰线条数的上下限
line_number = 30
#生成一个随机字符串
def getNumber():
source = list(string.ascii_letters) + list(string.digits)
return "".join(random.sample(source, number))
#绘制干扰线
def getLine(draw, width, height):
begin = random.randint(0, width), random.randint(0, height)
end = random.randint(0, width), random.randint(0, height)
draw.line([begin, end], fill=linecolor)
def getCode():
width, height = size
image = Image.new("RGBA", size, bgcolor)
font = ImageFont.truetype(font_path, 25)
draw = ImageDraw.Draw(image)
text = getNumber()
font_width, font_height = font.getsize(text)
draw.text(((width - font_width) / 2, (height - font_height) / 2), text, font=font, fill=fontcolor) # 填充字符串
if draw_line:
for i in range(line_number):
getLine(draw, width, height)
image = image.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强
image.save('idencode.png') # 保存验证码图片
if __name__ == '__main__':
getCode()
关于pillow
模块的更多介绍,可以点击Pillow查看官方文档。