2020年8月6日 星期四

Word / 檔案救援

word有時候會突然當掉

然後通常會自動重新開啟並且自動復原

但是,當你以為自己在這之前曾經有儲存過檔案而按下刪除復原檔

然而,發現結果卻不是的時候

這時候,就要去資源回收桶

找找看有沒有 *.asd    (*表示要尋找的檔案名稱)

如果有的話,還有機會救回最近版本的檔案

假如檔案開啟的時間夠久的話

可能會有兩個.asd檔

一個是「即時復原儲存關於*.asd」→當掉重啟的復原檔案

另一個是「儲存自動回復*.asd」→自動儲存的檔案

這兩個檔案都可以試試看

檔案救援的方法是將副檔名.asd改成 .wbk

就能夠在word開啟,順利的話就可以另存成新檔

救回最近版本的檔案

 

參考:Word 如何建立和復原自動回復檔案

2020年8月4日 星期二

VBA / 使用Excel VBA批次寄信

每個電子信箱當然都可以寄出大量信件

但是很容易會被當成寄出廣告信件

解決的辦法之一就是要有寄件間隔時間

只是要控制寄件間隔就要額外想辦法

在網路上找到一個很厲害的老師-彰化一整天所寫的excel VBA程式

補充:原作者說明-https://www.youtube.com/watch?v=mmYejL3ABcc 原始程式

可以實現批次寄信,並且設定每封信的寄出間隔時間

相關資訊可以直接用關鍵字拜谷狗大神

嘗試將固定間隔時間改為亂數5~10秒

實際使用之後,是可以正常運作

主要調整的內容如下

' 每封間格時間(單位:秒) 5<= delaysec <= 10'          Int( (上限-下現+1) * Rnd() + 下限 )delaysec = Int((10 - 5 + 1) * Rnd() + 5)' MsgBox (delaysec)Application.Wait (Now + TimeValue("0:00:" & delaysec))

說明:

delaysec是間隔時間的變數,並且將變數移到寄出信件的While迴圈之內

這樣就能夠每跑一次迴圈,重新取得一個5~10之內的亂數值

而程式便是透過暫停時間來達成每封信寄出的間隔時間

取得一個範圍亂數值的方式是參考 Excel VBA 產生隨機亂數教學與範例

參考資料

Application.Wait

TimeValue()

TimeSerial()

Excel VBA 產生隨機亂數教學與範例

2020年6月29日 星期一

網站 / 莊生趣味 tricohobby手動更新Let’s Encrypt的免費SSL憑證(2021/10/10修改)(2022/06/03修改)(2022/06/07修改)(2023/06/01修改)

現在只有一個網站

https://tricohobby.net/ 回到GCP


現在同時有兩個網站

一個在GCP  暫時用 https://backup.tricohobby.net/

一個在BlueHost 用 https://tricohobby.net/


因為網站主機改到BlueHost

BlueHost有提供SSL

所以就不用特別需要設定了


Let’s Encrypt的免費SSL憑證快到期了

可以參考下面網站的說明讓主機排程90天自動更新

在GCP上安裝WordPress with NGINX and SSL Certified by Bitnami and Automattic,並設定Let’s Encrypt SSL憑證

Generate And Install A Let’s Encrypt SSL Certificate For A Bitnami Application

自動排程執行緒


#!/bin/bash

sudo /opt/bitnami/ctlscript.sh stop nginx
sudo /opt/bitnami/letsencrypt/lego --tls --email="你的信箱" --domains="你的網域" --path="/opt/bitnami/letsencrypt" renew --days 90
sudo /opt/bitnami/ctlscript.sh start nginx


手動更新的方式

直接在主機端執行以下程式碼(從Google Cloud Platform-Compurer Engine-SSH連線)

sudo /opt/bitnami/ctlscript.sh stop nginx
sudo /opt/bitnami/letsencrypt/lego --tls --email="你的信箱" --domains="你的網域" --path="/opt/bitnami/letsencrypt" renew
sudo /opt/bitnami/ctlscript.sh start nginx
 

備註

之前無法自動排程的原因可能是權限設定的問題

參考這個網站的說明linux下chmod +x的意思?为什么要进行chmod +x

透過 ls 指令顯示的檔案資訊

執行緒必須是顯示成綠色

當初只是照著說明執行程式碼

所以根本不知道chmod +x 指令的功能,所以也不知道到底有沒有設定成功

sudo chmod +x /opt/bitnami/letsencrypt/scripts/renew-certificate.sh

現在看起來當初只是在這個步驟沒設定好

2020年5月29日 星期五

Gg / 使用GoogleCharts快速製作QrCode

許多要公開的資訊除了放上網之外,還要有方便讓人取得的管道

像是縮網址,可以方便記憶,也可以讓資訊量精簡一點

現在也常使用QrCode,手機一掃就可以快速取得資訊

最近在規劃辦理研習,需要用到進修網的報名網址與QrCode

但是,報名網址跟QrCode 卻無法從業務承辦人權限帳號的頁面功能中取得

之前我的作法是用一般帳號查詢研習,再進到報名頁面

 

這樣就可以知道網址

而網址結構是:https://inservice.edu.tw/NAPP/CourseView.aspx?cid=研習課程代碼

之後也可以直接帶入新的研習課程代碼來取得報名網址

同時這個報名頁面上也會出現QrCode

但是能進到報名頁面,看得到QrCode,其實這個QrCode就什麼沒必要了~~

好處反而在於業務承辦人可以從這邊抓到QrCode的圖檔

不過在之前抓QrCode的圖檔時,發現這個圖檔並不是實際存在的檔案(因為按右鍵無法另存新檔圖檔)

 

另存新檔,會存到網頁

 

利用Chrome的「檢查-內容」功能可以看到是完整的網址

https://chart.googleapis.com/chart?chs=120×120&cht=qr&chld=M|3&chl=https://inservice.edu.tw/NAPP/CourseView.aspx?cid=2861727

註:120×120,中間是英文小寫 x ,不知道為什麼wordpress會轉成×;兩者的字碼不一樣 x →  120,× → 41425

從網址結構可以看出來是https://chart.googleapis.com/chart?加上一連串傳遞的參數組合而成

拜谷狗大神得知這是GoogleCharts的功能,雖然官方網頁上寫不推薦使用

但我猜測這是因為無法透過帳號後台紀錄這個QrCode使用情況

官方網站詳細說明了這些參數的設定

https://developers.google.com/chart/infographics/docs/qr_codes?hl=zh-tw#syntax

簡單說明如下:

至少要有這三個參數 chs cht chl

chs=120x120 → QrCode圖檔大小,可以自行設定大小,寬x高,中間是英文字小寫 x (不知道為什麼wordpress會轉成×)

cht=qr → 這是固定的設定

chl=https://inservice.edu.tw/NAPP/CourseView.aspx?cid=2861727 → QrCode的內容

而進修網有再設定chld=M|3→QrCode的容錯率與版本,進修網設定的是 M 或( | )  第3版,預設第4版
 

綜合這些

1.以後要取得新課程的報名頁面網址

可以直接套用https://inservice.edu.tw/NAPP/CourseView.aspx?cid=研習課程代碼

2.要取得QrCode

可以直接套用https://chart.googleapis.com/chart?chs=120x120&cht=qr&chld=M|3&chl=報名頁面網址

取得的圖檔是png格式,24位元全彩,而不是32位元(背景透明)

當然這個方式也適用於取得其他網址/字串訊息的QrCode

2020年5月27日 星期三

Py / 透過selenium-webdriver爬youtube的介紹資訊(2021/10/28修改)

原本是透過Python 跟 selenium-webdriver抓取Html

但是後來網頁原始檔都變成JavaScript程式碼

影片資訊是寫在< meta name=’description’ content=’影片資訊’>

於是改變搜尋的方式

利用 find_element_by_xpath 定位搜尋頁面元素

tagX = browser.find_element_by_xpath("//meta[@name='description']") # meta標籤 name屬性值為'description'的元素
#tag = browser.find_element_by_id('description') #資訊所在的DIV id 現在不能直接抓Html
#print(tagX.get_attribute("content")) #取出其中的content屬性值
tag = tagX.get_attribute("content")
tag2 = tag.replace('\n','').replace('\r','') #用空字串取代所有換行符號 ,不能用strip刪除
#tag2=tag.text.replace('\n','').replace('\r','') #用空字串取代所有換行符號 ,不能用strip刪除

 

這次是要抓之前計畫放在youtube示例影片的介紹資訊

其實也是透過Python來爬資料

 

由於youtube很多內容是寫在JavaScript裡

 

用內容-檢查的方式找到的html標籤是 id名稱為 description的DIV

 

如果是用requests 跟 BeautifulSoup會爬不到這個DIV

嘗試抓取script

只能抓到整個script,之後的資料清理就會卡住

應該也有抓取、清理JavaScript資料內容的方式

因為其實內容是 json的格式

但是我還沒找到看得懂的教學,之後再嘗試看看

於是改用selenium-webdriver的方式

先讓瀏覽器載完html資料之後,這樣就能順利抓到內容資訊所在的DIV

完成之後的程式碼如下

 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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
from selenium import webdriver
import time
#chromedriver.exe執行檔所存在的路徑  須配合電腦上的chrome版本
# chrome_path =r"C:\Users\trico\Desktop\chromedriver\chromedriver.exe"
chrome_path =r"D:\chromedriver_win32\chromedriver.exe"  
options = webdriver.ChromeOptions() #透過options紀錄webdriver.ChromeOptions()的設定
options.add_argument("--headless") #增加啟動參數,瀏覽器頁面不可視化(背景執行)
browser = webdriver.Chrome(chrome_path,options=options) #webdriver.Chrome的設定選項
# browser = webdriver.Chrome(chrome_path)
#讀取資料
f = open("url.csv","r") #如果檔案編碼是utf-8 要再加上 ,encoding="utf-8"
s = f.readlines()
c = "科目,示例名稱,網址,介紹\n" #設定寫出檔案的第一行
for i in range(1,len(s)):
    url=s[i]
    list=url.split(",") #分割串列
#     print(list[2].replace('\n','')) #第3筆是最後1筆資料會有換行符號,須去掉
    browser.get(list[2].replace('\n','')) #載入網址
    time.sleep(3) #等待3秒載入網頁
    tag = browser.find_element_by_id('description') #資訊所在的DIV id
    tag2=tag.text.replace('\n','').replace('\r','') #用空字串取代所有換行符號 ,不能用strip刪除
#     print(tag2)
#     print(len(tag2))  
#     因為沒有資訊也同樣能抓到空字串,不會出現錯誤
#     try: 
#         tag = browser.find_element_by_id('description')
#         tag2=tag.text.replace('\n', '').replace('\r', '') 
#         c +="{},{},{},{}".format(list[0],list[1],list[2],tag2)
#         print(c)
#     except:
#         c +="{},{},{},{}".format(list[0],list[1],list[2],"無說明")
#         continue
#         print(c)
#      改用 if判斷 len(tag2)是否>0
    if i < len(s)-1: #如果不是最後一筆才加分行符號
        if len(tag2) > 0 :
            #print(tag2)
            c +="{},{},{},{}\n".format(list[0],list[1],list[2].replace('\n',''),tag2)
        else:
            tag2="無內容資訊"
            c +="{},{},{},{}\n".format(list[0],list[1],list[2].replace('\n',''),tag2)
            #print(tag2)
    else:
        if len(tag2) > 0 :
            #print(tag2)
            c +="{},{},{},{}".format(list[0],list[1],list[2].replace('\n',''),tag2)
        else:
            tag2="無內容資訊"
            c +="{},{},{},{}".format(list[0],list[1],list[2].replace('\n',''),tag2)
            #print(tag2)
#寫出資料
fw=open("c.txt","w",encoding="utf8")
fw.write(c)
fw.close()
#print(c)
browser.close() #關閉 瀏覽器
print("完成")

 

除了 selenium-webdriver之外,也用到time外掛程式來設定間隔時間,讓網頁有時間可以載入

selenium本身也是可以設定等待時間,但是我看不懂說明

於是還是土法煉鋼讓程式直接停止3秒再繼續

細節都寫在程式碼註解了,整體流程大致有四個部分

1.透過 selenium-webdriver 載入網頁並下載頁面原始檔

url.csv的資料結構,網址是第3欄 ( list[2] )

2.利用browser.find_element_by_id取得內容資訊所在的DIV

3.取出資料內容與資料清理

取出的字串有很多換行符號,一開始使用strip的方式來刪除,但都是失敗

後來谷狗大神說字串內只能取代,於是用replace的方式將所有換行符號取代為空字串

4.寫出資料

python在windows系統寫出檔案時,是透過cmd(命令提示字元)執行,而cmd預設的編碼是ANSI

所以當寫出的字串之中有無法在ANSI編碼時,寫出就會出現錯誤

比較好的方式是以UTF-8編碼寫出資料

但是,如果寫出檔案採用CSV,並且用excel開啟時就會出現亂碼

同樣是因為excel預設ANSI編碼

解決方式有3種

4-1用記事本另存成ANSI,再用excel開啟

4-2不要直接用excel開啟,而是先開新的excel空白活頁簿,再到資料分頁→取得外部資料-從文字檔,再依據匯入字串精靈的引導步驟匯入

4-3直接寫出純文字檔(*.txt)再用記事本開啟,或者用記事本開啟csv檔

 

參考資料

selenium啓動Chrome的進階配置參數

【Selenium學習筆記】測試中如何設定等待時間

Python中字符串String去除出换行符和空格的问题(\n,\r)

[EXCEL] Excel打開是亂碼?快速找回資料的最好方法!