9/22/2020

使用PyPDF2模塊抽取PDF部分頁面另存新檔 | Python筆記

最近試著整理有關PDF的Python程式,本文筆記的是,把已有的PDF檔案,取出一頁或多頁,另存一個PDF檔。以下就是完整的代碼附註釋。


#使用的是PyPDF2模塊

from PyPDF2 import PdfFileReader, PdfFileWriter


#可直接寫入PDF檔案名稱(須含副檔名),也可用input()取得

fileName = input('填入PDF档,须含副档名: ')

     

#實例化一個writer

pdf_writer = PdfFileWriter()


#開啟已有的PDF檔,並實例化一個reader

file_to_get = open(fileName, 'rb')

pdf_reader = PdfFileReader(file_to_get)


#看一下原檔的總頁數

NUM = pdf_reader.getNumPages()

print(NUM)


#開啟要存的新檔

newPDF = open('newPages.pdf', 'wb')


#這裡以input()收取要存的頁面。也可改成直接寫入數列

Pages = list()

k = 0

while k == 0:

    ent = int(input('Enter page number or enter -1 to quit:'))

    if ent >= 0:

        Pages.append(ent)

    else:

        k = k + 1


#檢查輸入的頁碼        

print(Pages)


#把指定的頁面逐頁加入writer,再寫入檔案

for pm in Pages:

    newpage = pdf_reader.getPage(pm)

    pdf_writer.addPage(newpage)

    pdf_writer.write(newPDF)


#記得關閉檔案!若沒有關閉檔案會出現錯誤,少一頁    

newPDF.close()


9/21/2020

與pip相關的指令 on Mac電腦 | Python筆記

pip 是用來安裝模塊(module)、管理模塊的程式。本文假設Mac電腦的Python3已經安裝完成,以下筆記的是pip的相關指令。以下寫在%後面的指令,代表在終端機狀態下(不需啟動python)。

% pip --version

據說pip在Python安裝後就附帶在裡面了,我們可以用這個指令查詢pip的版本號碼。


% pip list

% pip freeze

以上兩個指令都可以用來查詢已安裝的模塊有哪些,以及模塊的版本號碼。


但是,如果你的pip版本不是最新,pip list查詢的結果會順便提醒你現在有新版可以更新,並且提示更新pip的指令。例如以下這個:

% python3.8 -m pip install --upgrade pip

更新之後,再查詢一次pip版本,就可以看到版本號碼變了。



不過,用pip list或pip freeze雖然可以查詢模塊的版本號碼,卻無法得知哪些模塊不是最新版本。

% pip list --outdated

這個指令可以用來查詢哪些模塊已經過時(outdated)。



% pip install --upgrade modulename

遇到有過時的模塊,可以用這個更新的指令,升級到最新的版本。



安裝新的模塊


% pip install modulename

用這個指令來安裝新的模塊。


% pip list

同前,查看已安裝的模塊有哪些。


% pip show modulename

查詢某個模塊的詳細資料,包括版本號碼、模塊用途、相關網站、開發者、開發者電子郵箱、模塊儲存位置等。



% pip uninstall modulename

如果想要移除某個模塊,用這個指令來解除安裝。


9/20/2020

PDF轉檔為純文字格式:使用Adobe Reader或Python

想要把PDF格式的文件轉為別的格式,通常有點困難。一般習慣使用Microsoft OFFICE文書處理系統的人,知道可以把WORD文件、EXCEL文件轉換為PDF格式,但是OFFICE沒辦法幫你把PDF逆向轉回WORD文件或EXCEL文件。

PDF是Adobe公司所開發的一種文件格式,全名為Portable Document Format,所謂的portable可攜式,意思是這種文件格式可以跨越操作系統、應用程式的界線,不侷限使用單一特定的應用程式才能打開(相比之下,Word文件就是一定要用微軟的WORD應用程式打開,才能正常顯示)。

本文的主題則是,如何將PDF檔案轉換為純文字檔

最簡單直觀的方式,是用Adobe Reader這個應用程式。目前它是可以免費下載使用的。用Adobe Reader打開一個PDF文件後,點選「檔案」>>「另存為文字檔」,就可以了。(如果想要轉換為OFFICE裡面的Word、Excel或PowerPoint,則必須付費使用Adobe Acrobat Pro DC。它不只可以用來轉檔,還可以讓你編輯PDF文件。)

補充一點,如果想要知道PDF文件裡的文字是什麼編碼,可以在Adobe Reader內查看,點選「檔案」>>「內容」,再選擇「字型」的標籤頁,就可找到。


也可寫Python程式把PDF轉為純文字格式

接下來要討論的則是,用Python程式將PDF格式轉換為純文字,並另存新檔。目前為止我試過 pdfplumber 和 pypdf2 兩個模塊(module),兩者都有效果好的時候。


pdfplumber:

pdfplumber的特色是程式碼中不需要指明文字的編碼,而且它可以用來轉換中文內容的檔案。pdfplumber似乎是可以自己辨別文字編碼然後進行轉換。不過,可以想像,若PDF文件用的剛好是這個模塊不兼容的編碼,就沒辦法正確轉檔了!我自己試過的例子:現在比較罕見的ETenms-B5-H中文編碼,就沒辦法用pdfplumber轉換出來。


import pdfplumber  #引入模塊


file = 'filename.pdf'

pdfob = pdfplumber.open(file)  #用模塊開啟要轉換的PDF檔

pgnum = len(pdfob.pages)

textfile = open('new.txt', 'w')  #指定並開啟一個純文字檔


for pg in range(pgnum):  

    page = pdfob.pages[pg] #每次呼叫一頁

    text = page.extract_text() #擷取純文字       

    textfile.write(text) #寫入純文字檔

    

pdfob.close()

textfile.close()


pypdf2:

pypdf2這個模塊使用時可以註明文字編碼。編碼如果正確的話,有機會轉換出整齊排列的純文字。如前述,用Adobe Reader的應用程式,可以查出文件的編碼。有需要時也可查閱網上資料,找出正確的編碼名稱:https://docs.python.org/2.4/lib/standard-encodings.html


import PyPDF2 as pp2 #引入模塊


PDFfile = open('tobeconverted.pdf', 'rb') #開啟PDF檔,記得模式要寫rb

pdfreader = pp2.PdfFileReader(PDFfile) 

textfile = open('catcher.text', 'a')

print(pdfreader.getNumPages()) #取得PDF檔案的頁數

i = 0

while i < pdfreader.getNumPages():

    pageinfo = pdfreader.getPage(i)  #每次取出一頁

    Text = pageinfo.extractText() #提取純文字(下行為另一種寫法,可註明文字編碼)

    #Text = pageinfo.extractText().encode('latin1', errors='ignore').decode('utf-8', errors='ignore')

    textfile.writelines(Text) #寫入提取的純文字

    i = i + 1


PDFfile.close()

textfile.close()


寫Python程式來轉換PDF檔,好處就是不必特地下載任何軟體程式來轉檔。不過,由於文字編碼的類別實在太紛雜了,似乎還沒有一個包山包海什麼編碼都能解的萬能模塊可以用。

再補充一點,其實用來解析PDF檔案的Python模塊還有很多,但如果想處理的檔案含有中文內容,可以先用pdfplumber試試看,可能是最有效率的。而如果是轉換英文檔案,則pdfplumber和pypdf都很有機會成功(若能知道文字編碼為何,那麼pypdf2轉換出來的文字有可能更整齊有序,畢竟轉換出整齊的純文字,才方便後續的閱讀或是整理)。


9/10/2020

Blogger網誌防複製,鎖右鍵的語法

認真寫部落格累積原創文章的人,應該都很討厭被不明人士複製自己的文章然後轉貼在別的地方。對於不希望文章被人隨便複製轉貼的Blogger作者來說,有一個簡單的方式就是在網誌的原始碼中嵌入一段語法,使「反白-按右鍵-複製」的功能失效。

2020年7~8月開始,Google把Blogger的後台做了更新,有些按鈕和功能換了位置,變得不容易找到。本文說明如何在新版本的blogger後台嵌入鎖右鍵的語法。

1)首先登入你的blogger,進入後台管理頁面。有些人擁有或管理超過一個網誌,所以請確定你是在想要鎖右鍵的那個網誌的管理後台。

2)左側的選單找到【主題】,點開後會看到頁面中間有「我的主題」字樣,以及下方有一個醒目的橘色【自訂】選單,需點擊旁邊的倒三角形才能展開選單。





3)選單下拉後,會看到「編輯HTML」,請點擊它,進入網誌的原始碼頁面(這裡的原始碼看起來眼花撩亂,請小心不要更改到別的內容)。




4)用游標在原始碼的區域點一下,然後按 Ctrl + F(搜尋),在跳出的搜尋框中輸入:</head>。找到後,我們要在這個</head>之前嵌入以下語法:


<!--鎖右鍵 -->
<script type='text/javascript'>
document.oncontextmenu = function(){return false;}
document.onselectstart = function(){return false;}
document.onmousedown = function(){return false;}
</script>
<!--鎖右鍵 -->



5)語法嵌入後,別忘了儲存(在頁面右上角附近有一個磁碟片的圖案,就是儲存按鍵)。步驟到此結束。可以登出帳號,重新打開網誌,檢查確認鎖右鍵是否已經生效。

6)建議在語法前後加上備註:<!--鎖右鍵 -->,以方便辨認。萬一日後改變心意,不想鎖右鍵了,只要回到原始碼,可以很快找到這段語法並刪掉它。

9/09/2020

修圖去背景,用Keynote就OK!

講到修圖去背景,很多人首先想到的是用Photoshop這類的修圖軟體,這好像也是P圖一詞的由來。但是在現實生活中,身為網路小白的人,若不是以處理影像為主業,付費使用這類專業軟體顯然不太實際。以我自己來說,我要的是可以運用自己電腦裡已經有的程式APP,或是網上容易找到的免費軟體,滿足影像處理的基本需求就好,例如不同圖片格式之間的轉存、圖片的剪裁、圖片長寬像素的設定等等,而本文要介紹的則是簡單的去背景技巧,所使用的是蘋果電腦內附帶的免費軟體Keynote。

Mac電腦的Keynote是用來製作簡報的軟體,相當於微軟的PowerPoint。不過我個人從來沒用Keynote做過簡報,而是把它當成排版軟體,排好了之後就儲存為圖片格式來使用。本文介紹的修圖功能,是我最近才發現的。把步驟記錄下來,哪一天忘了細節可以再翻出來看。


用Keynote剪裁圖片(去除背景)

1)開啟Keynote程式。新增文件,選擇任一主題。因為接下來的重點是P一張圖片,請先新增一張乾淨(無圖文框)的幻燈片來用。

2)點擊頂部選單「插入」,找到「選擇」並點擊,然後瀏覽電腦裡的檔案夾,找出你要P的圖片。

3)點擊頂部選單「插入」,找到「線條」,選擇「用筆描繪」,滑鼠的箭頭就會變成一個鋼筆頭的形狀。(另一個叫出鋼筆頭的方式是點選快捷列的「形狀」,選單下拉後,右上角有一個鋼筆頭形狀,就是它。)



4)沿著想要保留的物件(例如圖片中的貓)外圍,用鋼筆頭一點一點把物件圍起來。點與點之間的距離可長可短。注意,結束時需把第一個點再點一次,才會形成一個封閉的圍欄。過程當中,如果某個點的位置不理想,可以用鋼筆頭按住它再移動來改變位置。



點點的位置可以距離物件邊緣很近很近,也可以故意留一段距離。如果距離很近,(幾乎)不留任何背景,就等於俗稱的「去背景」或摳圖。如果故意留一段距離,等於保留了物件邊緣的一部分背景,則會產生一種用剪刀剪裁的有趣效果。

5)前一個步驟把物件圈出來並且形成封閉圍欄後,滑鼠在圖片上任一處點一下,會看到點點都不見了,變成一圈黑色線框。接著按Command + A(全選),此時會看到出現兩個方框,一個是原始圖片的圖框,一個是以圍欄物件為主體的方框。



6)點擊頂部選單「格式」,找到「影像」,點擊「以所選範圍進行遮罩裁切」。此時,圖片就會只剩下圍欄內的部分,外圍的「背景」被半透明的一層遮蔽掉了。此時還沒完成裁切。

7)在遮蔽狀態下,會出現一個裁切圖示,這裡可以讓你調整裁切的範圍,可以把原始圖片放大或縮小或移動位置。萬一前一步驟的裁切有些微誤差而不太理想的話,在這裡可以調整一下。調整完,按「完成」,背景就不見了。



8)裁切好的物件,可以直接在Keynote頁面當成簡報素材使用。而如果想要把這個物件單獨另存新檔,請繼續閱讀本文第二部分。




把裁切好的圖片物件儲存為PNG圖檔

經過裁切的圖片物件,如果覺得在別的地方還用得著,就可以把它單獨存為PNG格式的圖檔。PGN格式可以儲存透明背景的圖片,正好適合我們這個費心裁切的不規則形狀物件。

1)假設圖片物件已經裁切好了在Keynote的頁面上。在存檔之前,我們須先把Keynote頁面的「背景」去掉。做法是,在頁面上點一下,可以看到右側出現「幻燈片佈局」的標籤頁。找到「背景」的選項,把它改為「不填充」,此時頁面會變成黑色,代表背景沒顏色了。



2)點擊頂部選單「檔案」,找到「輸出至」,選擇「影像」。此時跳出「輸出您的簡報」,請輸入正確的頁碼,然後「格式」要選擇PNG,並勾選「輸出透明背景」,按「下一步」,輸入檔案名稱以及選擇存檔的位置即可。

9/04/2020

os, os.path模塊常用指令用法 | Python學習筆記

Python可以跨平台使用,在Linux、Windows、Mac的操作系統中都可安裝Python來使用,然而每種操作系統有各自不同的設定,os模塊可以幫助我們克服這些差異,遇到要操作系統中的檔案、目錄(文件夾)時,可以順暢無阻。

進入終端機後,啟動python(或python3),須先引入os模塊,才能執行以下指令。

>>>import os

>>>os.name
'posix'
指令會返回當前使用的操作系統名稱

>>>os.linesep
'\n'
指令會返回當前操作系統所使用的換行符號

>>os.sep
'/'
指令會返回當前操作系統的檔案路徑分隔符號

>>>os.pardir
'..'
指令會返回表示上一級目錄的符號

>>>os.curdir
'.'
指令會返回表示當前目錄的符號

-------------------------------------------

>>>os.getcwd()
'/Users/alice'
指令會返回目前所在的目錄名稱(含絕對路徑)

>>>os.listdir(path='.')
['dir1', 'dir2', 'dir3', 'Desktop', 'Applications']
指令會返回目前所在目錄裡的所有文件夾和文件的名稱,也可寫成os.listdir('.')或os.listdir()
>>>os.listdir(path='..')
指令會返回目前上一層目錄裡的所有文件夾和文件名稱,也可寫成os.listdir('..')
>>>os.chdir(path)
指令改變當前的目錄位置

>>>os.mkdir(path)
指令會新增一個文件夾(新增後不會返回任何東西)
path參數可以直接寫一個文件夾名稱,例如'dirname',或是path='dirname',代表在當前目錄裡新增文件夾。
path參數可以帶有路徑,例如'dirhere/dirname',或是path='dirhere/dirname',代表在dirhere目錄裡新增文件夾。

>>>os.path.isdir(path)
指令查詢path所指的目錄是否存在,結果返回True或False(不能查詢檔案名稱)
path參數的寫法同上

>>>os.path.isfile(path)
指令查詢path所指的檔案是否存在,結果返回True或False

>>>os.path.exists(path)
指令查詢path所指的目錄或檔案是否存在,結果返回True或False

>>>os.rename(src, dst)
指令將src改名為dst,可以改目錄或檔案的名稱

>>>os.rmdir(path)
指令移除path所指的目錄(不能用來移除檔案)

>>>os.remove(path)
指令移除path所指的檔案(不能用來移除文件夾)

-------------------------------------------

>>>os.system(command)
用來執行系統的指令

-------------------------------------------

>>>os.path.basename(path)
指令返回path參數的文件名稱(或目錄名稱),不帶路徑

>>>os.path.dirname(path)
指令返回path參數的路徑,不帶文件名稱

>>>os.path.split(path)
指令分割path參數為目錄(head)和檔案名稱(tail)兩部份
例如:os.path.split(os.getcwd()),返回('/Users', 'ellis')

>>>os.path.splitext(path)
指令分割path參數為目錄包括檔名(root),以及副檔名(ext)兩部份
例如:os.path.splitext(os.getcwd()),返回('/Users/ellis', '')

>>>os.path.join(dirpath, filename)
指令把路徑和檔名連結起來,中間自動加分割符號
例如:os.path.join(os.getcwd(), 'filename'),返回'/Users/ellis/filename'