1. 程式人生 > 實用技巧 >python selenium 關於將網頁打包為靜態網頁(mhtml)下載。

python selenium 關於將網頁打包為靜態網頁(mhtml)下載。

需求:單純的將page.source寫入檔案的方式,會導致一些圖片無法顯示,對於google瀏覽器,直接將頁面打包下載成一個mhtml格式的檔案,則可以進行離線下載。對應python selenium 微信公眾號歷史文章隨手一點就返回首頁?鬱悶之下只好將他們都下載下來。:https://www.cnblogs.com/cycxtz/p/13416245.html後續

遇到的問題:

1、單純使用webdriver.ActionChains無法完成下載動作,未能操作windows視窗。

2、沒有找到相關能直接下載.mhtml的命名介面。

3、pywin32置頂視窗的使用不順利。

解決思路:

1、使用selnium開啟瀏覽器,不要操作,讓其保持置頂

2、使用pyautogui、pyperclip操作鍵盤、滑鼠、剪下板進行下載檔案。

實現:

1、開啟爬取好的連結,遍歷所有需要下載的頁面

# 讀取檔案
filename = r'data/01 爬取微信公眾號歷史文章/urls 二律背反的一燈如豆-out.xlsx'
df = pd.read_excel(filename,dtype=object)
df = df.reindex(columns=['日期', '標題', '原創', '地址','完成情況','儲存地址'])
#df = df.head(5)
dfsel = (df['標題'] !='隨文') & (df['完成情況'] != 1)
save_folder 
= r"I:\code\python\data\01 爬取微信公眾號歷史文章\01 二律背反的一燈如豆" + "\\" # 設定儲存格式為 mhtml,減少要操作檔案儲存下拉框的情況 options = webdriver.ChromeOptions() options.add_argument('--save-page-as-mhtml') # 啟動瀏覽器 driver = webdriver.Chrome(options=options) wait = WebDriverWait(driver,10) df.loc[dfsel,"完成情況"],df.loc[dfsel,"儲存地址"] = zip(*df[dfsel].apply(download_mhtml_with_not_check, axis=1,args=(driver,wait)))

2、編寫相關下載頁面函式

# 在timeout秒內,返回中心值,間隔時長time_setp
# 封裝一個pyautogui限時查詢函式
#
def finde_gui_element(png,timeout = 5,time_setp=0.2):
    i = 1
    if timeout <=0 : timeout = 5
    if time_setp <=0 : time_setp = 0.2
    while True:
        if i > timeout/time_setp: return None
        center = pyautogui.locateCenterOnScreen(png,grayscale=False,confidence=0.9)
        if center == None:
            time.sleep(0.2)
        else:
            return center
        i = i + 1

主要自動化操作程式碼:

def download_mhtml_with_not_check(x,driver,wait):
    name = ''
    try:
        url = str(x['地址'])
        driver.get(url)
        # 獲取瀏覽器標題,用於檢測是否是置頂頁
        wait.until(EC.presence_of_element_located((By.XPATH,'//h2[@id="activity-name"]')))
        title = driver.find_element_by_xpath('//h2[@id="activity-name"]').text
        print('no:',x.name,'url:',url,'title:',title)
        wait.until(EC.presence_of_element_located((By.XPATH,'//div[@id="page-content"]')))
        
        #進入下載
        pyautogui.hotkey('ctrl', 's')
        # 等待一下對話方塊彈出
        time.sleep(1)
        bt = finde_gui_element(r'data\png\save.png') #查詢儲存按鍵
        if bt == None:
            return (0,'')
        else:
            # 根據標題組合成具體路徑
            name = save_folder + ' ' + title + '.mhtml'
            #print(name)
            pyperclip.copy(name)
            pyautogui.hotkey('ctrl', 'v')
            time.sleep(0.1)
            pyautogui.hotkey('Enter')
            # 檢查是否彈出另存為
            bt = finde_gui_element(r'data\png\confirmsaveas.png',timeout=0.5)
            if bt != None:
                # 說明出現重複明明,點選覆蓋
                pyautogui.hotkey('Tab')
                pyautogui.hotkey('Enter')
                return (1,name)
            bt = finde_gui_element(r'data\png\cancle.png',timeout=0.5)
            if bt != None:
                #還愛,說明出現了一些異常
                pyautogui.hotkey('esc')
                pyautogui.hotkey('esc')
                pyautogui.leftClick(bt)
                return (-1,name)
        # 加多一個esc防止出現視窗還在
        pyautogui.hotkey('esc')
    except Exception as e:
        print(str(e))
        return (-2,name)
    return (1,name)

最後寫入excel:

通過vba程式碼,將單元格地址新增上超連結:

Option Explicit

Sub add_hype()
    Dim ws As Worksheet, arr As Variant, i As Long
    Set ws = ThisWorkbook.Worksheets(1)
    arr = ws.UsedRange.Value
    ws.Cells.Hyperlinks.Delete
    For i = 2 To UBound(arr)
        If CStr(arr(i, 2)) = "隨文" Then
        
        Else
            If CStr(arr(i, 5)) = "1" Then
                ws.Hyperlinks.Add Anchor:=ws.Cells(i, 6), Address:=CStr(arr(i, 6))
            End If
        End If
    Next i
    
End Sub

完成。

不足之處:

1、通過autogui操作,難免會遇到彈窗的情況,需要增加活動窗體置頂,但是一直沒有找到有效的方法。