python数据处理(二)

pdf处理

pdf是二进制文件,使用PyPDF2模块进行处理,安装方法pip install PyPDF2

提取文本

  1. 导入PyPDF2模块,然后以读二进制模式打开pdf文件,并将其保存到对象pdfFileObj。
  2. 调用pdfFileReader()并传入pdfFileObj,将PdfFileReader对象保存到pdfReader。
  3. 获取pdf文件总页数调用PdfFileReader对象的numPages属性。
  4. 从某页中提取文本,首先通过PdfFileReader对象的getPage()方法得到Page对象,然后调用Page对象的extractText()方法得到文本字符串。
    1
    2
    3
    4
    5
    6
    7
    import 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
7
import 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拷贝页面。

  1. 打开一个或多个pdf文件,得到PdfFileReader对象。
  2. 创建一个新的PdfFileWriter对象。
  3. 将页面从PdfFileReader对象拷贝到PdfFileWriter对象。
  4. 利用PdfFileWriter对象写入输出到pdf。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    pdf1File = 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
    3
    import pdfkit

    pdfkit.from_url("12345", "output1.pdf")
  • html转换为pdf

    1
    2
    3
    import pdfkit

    pdfkit.from_file("12345.html", "output2.pdf")
  • 字符转换成pdf

    1
    2
    3
    import pdfkit

    pdfkit.from_string("12345", "output3.pdf")

实例

  1. 抓取linux教程然后制作成pdf文件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import 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
  2. 将生成的多个pdf文件合并成1个pdf。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import 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. 显示图片信息并查看图片

    1
    2
    3
    4
    5
    from PIL import Image

    image = Image.open("test.jpg")
    print(image.format, image.size, image.mode)
    image.show()
  2. 抠图
    将图片指定区域进行裁剪并保存在cutting.jpg中。

    1
    2
    3
    4
    5
    6
    7
    from 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")
  3. 图片拼合
    将指定区域的图片截取出来并旋转180度,然后拼接在一起

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from 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()
  4. 图片缩放

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from 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()
  5. 验证码

    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
    41
    import 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查看官方文档。

Recommended Posts