Selenium實戰案例1:論文pdf自動下載

????????在上一篇文章中,我們介紹了Selenium的基礎用法和一些常見技巧。今天,我們將通過中國科學:信息科學網站內當前目錄論文下載這一實戰案例來進一步展示Selenium的web自動化流程。

目錄

中國科學:信息科學當期目錄論文下載

1.網頁內容分析

2.下載流程

檢測瀏覽器內文件下載完畢后退出webdriver? ? ? ??

解壓下載的zip文件

完整代碼


中國科學:信息科學當期目錄論文下載

https://www.sciengine.com/SSI/issuehttps://www.sciengine.com/SSI/issue中國科學:信息科學官網。

1.網頁內容分析

????????網頁內容的分析是web自動化中的關鍵一步。通過分析網頁結構,我們可以確定需要抓取的數據位置以及操作元素的方式。

? ? ? ? 與爬蟲不同的是,web自動化通常是對瀏覽器渲染后的html網頁直接進行操作,因此,我們不需要像爬蟲那樣進行抓包分析,只需要在原網頁中定位元素并進行相應的操作即可。


?中國科學信息科學網頁源代碼

? ? ??

?????????觀察網頁源代碼,可以發現,下載時我們主要用到的兩個組件是全選下載pdf,且這兩個組件均為div元素,具有class_name屬性,那么在代碼中,我們便可以先定位到全選下載pdf 這兩個div,接著按照順序點擊即可。

2.下載流程

????????先不著急寫代碼,我們先手動操作一番,看一下整個流程是什么樣子。

????????

? ? ? ? 按下全選后,所有文章被選中,且會在下方出現已選中13結果的字樣,表示待下載的文件數量。

????????每個文章的標題都在classname為title的div內的span標簽下,我們分別復制第一個文章與最后一個文章的標題的XPATH:

'//*[@id="journal-list"]/div[1]/div[1]/div[4]/div/div[1]/div/div[2]/div[2]/a/span'
'//*[@id="journal-list"]/div[1]/div[1]/div[4]/div/div[13]/div/div[2]/div[2]/a/span'

??????不難發現,對于第i個文章的標題,其XPATH應該為:

'//*[@id="journal-list"]/div[1]/div[1]/div[4]/div/div[{i}]/div/div[2]/div[2]/a/span'

? ? ?

? 那么,為了功能更完善一些,我們還可以在點擊全選之后按照出現的數量,遍歷查找上述的XPATH下的內容的text屬性,這些text便是所有的論文標題,我們還可以將其寫入到txt中,與下載的論文一起保存到本地。

essay_titles=[]
total_number=browser.find_element(By.XPATH,'//*[@id="selectedArticleNum"]/strong')#定位全選之后彈出的已選中之后的數字total_number=int(total_number.text)#################################查找文章標題for i in range(1,total_number+1):essay_title=browser.find_element(By.XPATH,f'//*[@id="journal-list"]/div[1]/div[1]/div[4]/div/div[{i}]/div/div[2]/div[2]/a/span')essay_titles.append(essay_title.text)#################################將查找到的文章標題寫入到與下載文件同路徑的位置的txt內full_path=os.path.join(self.download_path,'下載論文列表.txt')with open(full_path,'w',encoding='utf-8') as file:for essay_title in self.essay_titles: file.write(essay_title+'\n')

??在按下下載PDF按鈕后,頁面會暫時的跳轉到一個其他url下的空白頁面,過一會兒后,文件開始下載,且下載到本地的格式為zip。

??????

? 按下下載pdf按鈕后頁面變化


檢測瀏覽器內文件下載完畢后退出webdriver? ? ? ??

對于上述兩個流程,倘若我們在代碼中不加任何等待機制:即等待頁面跳轉完畢,文件開始下載至文件下載完畢的等待機制

即使我們在代碼中沒有寫browser.quit()這樣的命令,webdriver也會自動關閉的。

????????這是因為我們的代碼中涉及到自動化流程的只有點擊全選下載pdf這兩個按鈕以及查找文章標題,一旦這三個任務完成后,webdriver是會自動關閉的。

? ? ? ? 對于上述問題,最簡單的思路是使用time.sleep()函數,設置足夠多的秒數,保證點擊下載pdf按鈕后,從文件開始下載至文件下載完畢webdriver不會關閉,這里我已經測試過,使用time.sleep(30)足矣。


但是,這樣有點太過于勉強,且不夠優雅,有沒有更好的解決方案呢?

答案是:有的。???????

?????????大家在使用谷歌或者Edge瀏覽器下載文件時,如果在文件下載過程中,中途退出會發現源文件下載取消且中斷,并且在下載文件的位置有一個 文件名.crdownload的文件,這是一個臨時文件,表示文件在瀏覽器下載過程中未完全下載完畢,在下載完畢后文件名后綴中的.crdownload會消失。

????????那么,我們便可以按照下邊的方式來進行等待,這樣等待的好處是只要文件下載完畢,webdriver立即關閉,不會等待多余時長。

import os
import time
def is_download_finished(download_path):files=os.listdir(download_path)for file in files:if file.endswith('crdownload'):#判斷文件夾內是否存在crdownload結尾文件,如果有說明還webdriver內還有文件在下載中return Falsereturn True
while not is_download_finished(download_path):#while循環輪詢time.sleep(1)#這里以1s為單位,若對等待時間要求較高,可以更換為0.1-0.5的小數
webdriver.quit()#關閉先前打開的webdriver

?等待文件下載完畢代碼


????????到這里就萬事大吉了嗎?No,No,No。還記得我們前邊我們說到的,我們在點擊下載pdf后,會有大概5s左右的空閑時間,在這5s內我們會臨時跳轉到一個新的網頁,然后又跳轉回到原來的網頁,文件開始下載嗎?

點擊下載pdf后,跳轉到空白網頁?

大概5s后,返回原網頁,文件開始下載

????????對于上述現象,倘若我們在點擊下載pdf后,直接使用上邊的等待文件下載完畢的代碼的話,由于文件還沒開始下載,文件夾內也根本沒有crdownload結尾的文件,此時代碼中is_download_finishe函數會直接返回True,while循環一次也不執行,webdriver直接就退出了。

????????所以,我們應該等待文件正式下載后再調用上邊的代碼,這里可以使用time.sleep函數,等待幾秒鐘頁面跳轉完畢,當然也可以使用webdriver的current_url屬性,先臨時保存原先網頁url,然后一個while循環判斷webdriver.current_url是否等于原來的網頁的url來進行判斷。為了省事,我們這里就直接使用time.sleep函數進行等待了。


解壓下載的zip文件

解壓已經下載好的zip文件,我們只需要使用python標準庫內置的zipfile模塊即可

import os
import zipfile
def extract_zip_file(download_path):#解壓zip文件filelist=os.listdir(download_path)for file in filelist:if file.endswith('.zip'):zip_file_path=os.path.join(download_path,file)with zipfile.ZipFile(zip_file_path,'r') as zip:zip.extractall(download_path)

運行上述代碼后,給定文件夾下的后綴為zip的文件夾內的內容將被解壓到原路徑下,注意:若你需要解壓指定的zip文件夾,只需要將? if file.endswith('.zip'):更換為if file=='指定的zip文件名':即可。

完整代碼

import os
import time
import zipfile
from selenium import webdriver
from selenium.webdriver.edge.options import Options
from selenium.webdriver.common.by import By
class 中國科學():def __init__(self,download_path:str,headless:bool=False):'''Args:download_path:下載文件保存路徑headless:是否開啟無頭模式'''self.download_path=download_pathself.headless=headlessself.essay_titles=[]def extract_zip_file(self):#解壓zip文件filelist=os.listdir(self.download_path)for file in filelist:if file.endswith('.zip'):zip_file_path=os.path.join(self.download_path,file)with zipfile.ZipFile(zip_file_path,'r') as zip:zip.extractall(self.download_path)def is_download_finished(self):#判斷是否下載完畢files=os.listdir(self.download_path)for file in files:if file.endswith('crdownload'):return Falsereturn Truedef download(self):#下載文件prefs = {'download.default_directory': self.download_path,  # 設置默認下載路徑"profile.default_content_setting_values.automatic_downloads": True  # 允許多文件下載} self.Options=Options()self.Options.add_argument('--disable-blink-features=AutomationControlled')#隱藏自動化控制self.Options.add_argument('--ignore-ssl-errosr')#忽略ssl錯誤self.Options.add_argument('--ignore-certificate-errors')#忽略證書錯誤self.Options.add_experimental_option("prefs", prefs)self.Options.add_experimental_option('excludeSwitches', ['enable-logging'])self.Options.add_experimental_option('excludeSwitches',['enable-automation'])#隱藏自動化控制if self.headless:#無頭模式運行自動化代碼self.Options.add_argument('--headless')self.Options.add_argument('--disable-gpu')else:passself.browser=webdriver.ChromiumEdge(self.Options)self.browser.maximize_window()#webdriver全屏self.browser.get('https://www.sciengine.com/SSI/issue')self.browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {#執行一段js代碼,隱藏自動化控制"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"""})select_all=self.browser.find_element(By.CLASS_NAME,'select.borderC2')download_pdf=self.browser.find_element(By.CLASS_NAME,'download.borderC2')self.browser.execute_script('arguments[0].click()',select_all)total_number=self.browser.find_element(By.XPATH,'//*[@id="selectedArticleNum"]/strong')#定位全選之后彈出的已選中之后的數字total_number=int(total_number.text)#################################查找文章標題for i in range(1,total_number+1):essay_title=self.browser.find_element(By.XPATH,f'//*[@id="journal-list"]/div[1]/div[1]/div[4]/div/div[{i}]/div/div[2]/div[2]/a/span')self.essay_titles.append(essay_title.text)#################################將查找到的文章標題寫入到與下載文件同路徑的位置的txt內full_path=os.path.join(self.download_path,'下載論文列表.txt')with open(full_path,'w',encoding='utf-8') as file:for essay_title in self.essay_titles: file.write(essay_title+'\n')##################################點擊下載按鈕,等待下載完畢后退出webdriverself.browser.execute_script('arguments[0].click()',download_pdf)time.sleep(7)#等待7s頁面跳轉完畢while not self.is_download_finished():time.sleep(1)self.browser.quit()self.extract_zip_file()
中國科學(r"E:\OneDrive\Desktop\中國科學信息科學",headless=False).download()

?運行結果

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/70576.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/70576.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/70576.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《炒股養家心法.pdf》 kimi總結

《炒股養家心法.pdf》這篇文章詳細闡述了一位超級游資炒股養家的心得與技巧,展示了其從40萬到10億的股市傳奇。以下是文章中炒股技巧和心得的詳細總結: 1.核心理念 市場情緒的理解:炒股養家強調,股市的本質是群體博弈&#xff0c…

2025年華為手機解鎖BL的方法

注:本文是我用老機型測試的,新機型可能不適用 背景 華為官方已經在2018年關閉了申請BL解鎖碼的通道,所以華為手機已經無法通過官方獲取解鎖碼。最近翻出了一部家里的老手機華為暢玩5X,想著能不能刷個系統玩玩,但是卡…

Perfectly Clear WorkBench深度解析:專業圖像處理軟件的高效應用

在圖像處理領域,面對照片曝光不足、色彩失真、細節模糊等常見問題,一款專業且高效的圖像處理軟件顯得尤為重要。今天,本文將為大家詳細介紹Perfectly Clear WorkBench這款圖像處理軟件,幫助大家更好地了解并應用其功能,提升照片質量。 一、智能圖像校正,解決常見問題 Pe…

使用 DistilBERT 進行資源高效的自然語言處理

DistilBERT 是 BERT 的一個更小、更快的版本,在減少資源消耗的同時仍能保持良好性能。對于計算能力和內存受限的環境來說,它是一個理想的選擇。 在自然語言處理(NLP)中,像 BERT 這樣的模型提供了高精度和出色的性能。然…

【后端基礎】布隆過濾器原理

文章目錄 一、Bloom Filter(布隆過濾器)概述1. Bloom Filter 的特點2. Bloom Filter 的工作原理 二、示例1. 添加與查詢2. 假陽性 三、Bloom Filter 的操作1、假陽性概率2、空間效率3、哈希函數的選擇 四、應用 Bloom Filter 是一種非常高效的概率型數據…

Pytorch實現論文之三元DCGAN生成RGB圖像用于紅外圖像著色生成

簡介 簡介:采用了三次DCGAN單獨生成單通道圖像之后進行組成RGB圖像放入鑒別器中檢測,并在鑒別器和生成器的損失訓練中采用梯度方法來提升或者降低權重。該方法將用于獲得紅外圖像著色的生成。 論文題目:Infrared Image Colorization based on a Triplet DCGAN Architectur…

Qt中QDockWidget的使用方式

在PyQt5中使用QDockWidget可以創建靈活的停靠窗口,增強應用程序的多功能性。以下是詳細的步驟和示例代碼: 基本步驟 導入模塊:確保導入必要的PyQt5模塊。創建主窗口:繼承QMainWindow并初始化界面。設置中心部件:例如…

docker獨立部署milvus向量數據庫

milvus鏡像:國外封鎖,國內源也不好用。基本上所有源都不能用 首先想到阿里云服務,但是阿里云國外服務器便宜的300~400呢。 基于成本考慮終于裝上心心念念的milvus(*^▽^*) 安裝 Milvus 安裝 Milvus 獨立版 wget https://raw.githubuserco…

【SpringBoot整合系列】HttpClient遠程訪問的示例

前言 使用Apache的HttpClient庫,添加Apache HttpClient的依賴。工具類的封裝。通常,工具類需要處理GET、POST請求,可能還有其他方法如PUT、DELETE。需要設計一個工具類,提供靜態方法,可以發送請求,并處理響…

Git操作整體流程

文章目錄 1.Git創建個人倉庫2、Git全局配置3、Git本地管理4. Git本地管理常用命令匯總5、使用Git命令將項目提交到遠程碼云管理6.使用IDEA進行管理7、Idea里面的終端8、關于提交總結 1.Git創建個人倉庫 打開https://gitee.com/,登錄個人賬號,右上角加號…

MySQL MHA 部署全攻略:從零搭建高可用數據庫架構

文章目錄 1.MHA介紹2.MHA組件介紹3.集群規劃4.服務器初始化5.MySQL集群部署5.1 安裝MySQL集群5.2 配置一主兩從5.3 測試MySQL主從5.4 賦予MHA用戶連接權限 6.安裝MHA環境6.1 安裝MHA Node6.2 安裝MHA Manager 7.配置MHA環境8.MySQL MHA高可用集群測試8.1 通過VIP連接MySQL8.2模…

如何查看java的字節碼文件?javap?能用IDEA嗎?

編譯指令: javac YourProject.java 查看字節碼文件的指令: javap -c -l YourProject.class 不添加-c指令就不會顯示字節碼文件: 不添加 -l 就不會顯示源代碼和字節碼文件的對應關系: 添加-l之后多出來這些: IDEA不太…

1、Window Android 13模擬器 將編譯的映像文件導入Android Studio

1、環境準備 編譯環境:Ubuntu-18.04.5編譯版本:android13-release下載地址:清華大學開源軟件鏡像站AOSP # 下載repo # 同步代碼:repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android13-r…

JUC并發—9.并發安全集合三

大綱 1.并發安全的數組列表CopyOnWriteArrayList 2.并發安全的鏈表隊列ConcurrentLinkedQueue 3.并發編程中的阻塞隊列概述 4.JUC的各種阻塞隊列介紹 5.LinkedBlockingQueue的具體實現原理 6.基于兩個隊列實現的集群同步機制 1.并發安全的數組列表CopyOnWriteArrayList …

報錯:Cannot read properties of null (reading ‘ce‘)解決方法

背景 工作項目中要做右鍵菜單打開趨勢圖彈窗的需求,這個彈窗使用了vue-resizable的第三方插件,這個插件的主要作用是把彈窗設置為可拖拽的效果。這個用vue-resizable做的彈窗已經做好了,在別的項目中能夠正常的運行。但是我把它拿過來放在新…

Ubuntu 下 nginx-1.24.0 源碼分析 - ngx_process_options

ngx_process_options 聲明在 src\core\nginx.c static ngx_int_t ngx_process_options(ngx_cycle_t *cycle); 定義在 src\core\nginx.c static ngx_int_t ngx_process_options(ngx_cycle_t *cycle) {u_char *p;size_t len;if (ngx_prefix) {len ngx_strlen(ngx_prefix);p …

數據結構系列二:包裝類+泛型

包裝類泛型 一、包裝類(1)基本數據類型和對應的包裝類(2)裝箱和拆箱 二、泛型(1)什么是泛型(2)引出泛型(3)語法(4)泛型類的使用1.語法…

量子計算驅動的金融衍生品定價革命:突破傳統蒙特卡洛模擬的性能邊界

引言:金融計算的算力困局 某國際投行采用128量子位處理器對亞洲期權組合定價時,其量子振幅估計算法在2.7秒內完成傳統GPU集群需要68小時的計算任務。在蒙特卡洛路徑模擬實驗中,量子隨機游走算法將10,000維衍生品的價格收斂速度提升4個數量級…

Spring容器初始化擴展點:ApplicationContextInitializer

目錄 一、什么是ApplicationContextInitializer? 1、核心作用2、適用場景 二、ApplicationContextInitializer的使用方式 1、實現ApplicationContextInitializer接口2、注冊初始化器 三、ApplicationContextInitializer的執行時機四、實際應用案例 1、動態設置環境…

hive—常用的函數整理

1、size(split(...))函數用于計算分割后字符串數組的長度 實例1):由客戶編號列表計算客戶編號個數 --數據準備 with tmp_test01 as ( select tag074445270 tag_id,202501busi_mon , 012399931003,012399931000 index_val union all select tag07444527…