1.簡介:
常規情況下,我們藉助 requests 庫爬取不加密的網站,使用 Selenium 庫爬取加密的網站。requests 效率高,但是解密難度大。Selenium 庫可以實現網頁自動化,不用解密,但是爬蟲效率不高。那有沒有什麼庫既效率高,又可以網頁自動化。DrissionPage 庫他來了,號稱可以把 Selenium 按在地上摩擦!DrissionPage 庫結合了 requests 和 selenium 的特長,既實現了和 Selenium 庫類似的網頁自動化效果,又提升了爬蟲效率。同時實現代碼“寫得快”和“跑得快”。
2.chromiumpage的使用方法:
-
導入drissionpage庫
# 安裝 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple Drissionpage # 升級最新穩定版 pip install DrissionPage --upgrade # 指定版本升級 pip install DrissionPage==4.0.0b17 -
使用chromiumpage模塊
from DrissionPage import ChromiumPage # 創建一個頁面 page = ChormiumPage() -
頁面截圖
# 對整頁截圖並保存 page.get_screenshot(path='D:\\page.png', full_page=True) -
頁面跳轉
back(),此方法用於在瀏覽歷史中後退若干步。 page.back(2) # 後退兩個網頁 forward(),此方法用於在瀏覽歷史中前進若干步。 page.forward(2) # 前進兩步 refresh(),此方法用於刷新當前頁面。 page.refresh() # 刷新頁面 -
窗口管理
page.set.window.maximized() # 窗口最大化 page.set.window.minimized() # 窗口最小化 page.set.window.fullscreen() # 用於使窗口切換到全屏模式 page.set.window.normal() # 用於使窗口切換到普通模式 page.set.window.size(500, 500) # 用於設置窗口大小。 page.set.window.location(500, 500) # 用於設置窗口位置 -
頁面滾動
page.scroll.to_top() # 用於滾動頁面到頂部,水平位置不變 page.scroll.to_bottom() # 用於滾動頁面到底部,水平位置不變 page.scroll.to_half() # 用於滾動頁面到垂直中間位置,水平位置不變 page.scroll.to_rightmost() # 用於滾動頁面到最右邊,垂直位置不變 page.scroll.to_leftmost() # 用於滾動頁面到最左邊,垂直位置不變 page.scroll.to_location(300, 50) # 用於滾動頁面到滾動到指定位置 page.scroll.up(30) # 用於使頁面向上滾動若干像素,水平位置不變 page.scroll.down(30) # 用於使頁面向下滾動若干像素,水平位置不變 page.scroll.right(30) # 用於使頁面向右滾動若干像素,垂直位置不變 page.scroll.left(30) # 用於使頁面向左滾動若干像素,垂直位置不變scroll.to_see(),用於滾動頁面直到元素可見
# 滾動到某個已獲取到的元素 ele = page.ele('tag:div') page.scroll.to_see(ele) # 滾動到按定位符查找到的元素 page.scroll.to_see('tag:div') - 跳轉到下一個標籤頁
tab = page.get_tab(1)
3.元素定位及常見語法
-
元素定位查找
# 根據屬性查找,@ 後面可跟任意屬性 page.ele('@id:ele_id', timeout=2) # 查找 id 為 ele_id 的元素,設置等待時間2秒 page.eles('@class') # 查找所有擁有 class 屬性的元素 page.eles('@class:class_name') # 查找所有 class 含有 ele_class 的元素 page.eles('@class=class_name') # 查找所有 class 等於 ele_class 的元素 # 根據 class 或 id 查找 page.ele('#ele_id') # 等價於 page.ele('@id=ele_id') page.ele('#:ele_id') # 等價於 page.ele('@id:ele_id') page.ele('.ele_class') # 等價於 page.ele('@class=ele_class') page.ele('.:ele_class') # 等價於 page.ele('@class:ele_class') # 根據 tag name 查找 page.ele('tag:li') # 查找第一個 li 元素 page.eles('tag:li') # 查找所有 li 元素 # 根據 tag name 及屬性查找 page.ele('tag:div@class=div_class') # 查找 class 為 div_class 的 div 元素 page.ele('tag:div@class:ele_class') # 查找 class 含有 ele_class 的 div 元素 page.ele('tag:div@class=ele_class') # 查找 class 等於 ele_class 的 div 元素 page.ele('tag:div@text():search_text') # 查找文本含有 search_text 的 div 元素 page.ele('tag:div@text()=search_text') # 查找文本等於 search_text 的 div 元素 # 根據文本內容查找 page.ele('search text') # 查找包含傳入文本的元素 page.eles('text:search text') # 如文本以 @、tag:、css:、xpath:、text: 開頭,則應在前加上 text: 避免衝突 page.eles('text=search text') # 文本等於 search_text 的元素 # 根據 xpath 或 css selector 查找 page.eles('xpath://div[@class="ele_class"]') page.eles('css:div.ele_class') # 根據 loc 查找 loc1 = By.ID, 'ele_id' loc2 = By.XPATH, '//div[@class="ele_class"]' page.ele(loc1) page.ele(loc2) # 查找下級元素 element = page.ele('@id:ele_id') element.ele('@class:class_name') # 在 element 下級查找第一個 class 為 ele_class 的元素 element.eles('tag:li') # 在 ele_id 下級查找所有li元素 # 根據位置查找 element.parent # 父元素 element.next # 下一個兄弟元素 element.prev # 上一個兄弟元素 # 獲取 shadow-root,把它作為元素對待。只支持 open 的 shadow-root ele1 = element.shadow_root.ele('tag:div') # 串連查找 page.ele('@id:ele_id').ele('tag:div').next.ele('some text').eles('tag:a') # 簡化寫法 eles = page('@id:ele_id')('tag:div').next('some text').eles('tag:a') ele2 = ele1('tag:li').next('some text') -
元素操作
element.click(by_js) # 點擊元素,可選擇是否用 js 方式點擊 element.input(value) # 輸入文本 element.run_script(js) # 對元素運行 JavaScript 腳本 element.submit() # 提交 element.clear() # 清空元素 element.screenshot(path, filename) # 對元素截圖 element.select(text) # 根據文本選擇下拉列表 element.set_attr(attr, value) # 設置元素屬性值 element.remove_attr(attr) # 刪除屬性 element.drag(x, y, speed, shake) # 拖動元素相對距離,可設置速度和是否隨機抖動 element.drag_to(ele_or_loc, speed, shake) # 拖動元素到另一個元素或某個座標,可設置速度和是否隨機抖動 element.hover() # 在元素上懸停鼠標 -
獲取元素屬性
element.html # 返回元素 outerHTML element.inner_html # 返回元素 innerHTML element.tag # 返回元素 tag name element.text # 返回元素 innerText 值 element.comments # 返回元素內註釋列表 element.link # 返回元素 href 或 src 絕對 url element.texts() # 返回元素內所有直接子節點的文本,包括元素和文本節點,可指定只返回文本節點 element.attrs # 返回元素所有屬性的字典 element.attr(attr) # 返回元素指定屬性的值 element.css_path # 返回元素絕對 css 路徑 element.xpath # 返回元素絕對 xpath 路徑 element.parent # 返回元素父元素 element.next # 返回元素後一個兄弟元素 element.prev # 返回元素前一個兄弟元素 element.parents(num) # 返回第 num 級父元素 element.nexts(num, mode) # 返回後面第幾個元素或節點 element.prevs(num, mode) # 返回前面第幾個元素或節點 element.ele(loc_or_str, timeout) # 返回當前元素下級第一個符合條件的子元素、屬性或節點文本 element.eles(loc_or_str, timeout) # 返回當前元素下級所有符合條件的子元素、屬性或節點文本
4.實用案例
-
系統登錄
import time from DrissionPage import ChromiumPage # from DrissionPage.easy_set import set_paths # set_paths(browser_path=r'C:\Program Files\Google\Chrome\Application\chrome.exe') page = ChromiumPage() page.get('https://designer.vivo.com.cn/#/login') ele = page.ele("@placeholder=支持郵箱/用户名登錄").input('yourname') page.ele('@placeholder=請輸入密碼').input("yourpassword") page.ele("登錄").click() time.sleep(1000) -
模式切換
用瀏覽器登錄網站,然後切換到 requests 讀取網頁。兩者會共享登錄信息from DrissionPage import WebPage from time import sleep # 創建頁面對象,默認 d 模式 page = WebPage() # 訪問個人中心頁面(未登錄,重定向到登錄頁面) page.get('https://gitee.com/profile') # 輸入賬號密碼登錄 page.ele('@id:user_login').input('your_user_name') page.ele('@id:user_password').input('your_password\n') page.wait.load_start() # 切換到 s 模式 page.change_mode() # 登錄後 session 模式的輸出 print('登錄後title:', page.title, '\n') #獲取登錄後的元素 foot = page.ele('#footer-left') # 用 id 查找元素 first_col = foot.ele('css:>div') # 使用 css selector 在元素的下級中查找元素(第一個) lnk = first_col.ele('text:命令學') # 使用文本內容查找元素 text = lnk.text # 獲取元素文本 href = lnk.attr('href') # 獲取元素屬性值 print(text, href, '\n') # 簡潔模式串聯查找 text = page('@id:footer-left')('css:>div')('text:命令學').text print(text) -
獲取新窗口句柄,無需切入切出,邏輯清晰
#登錄百度爬取 from DrissionPage import ChromiumPage import time page = ChromiumPage()這句意思是打開一個瀏覽器,這個瀏覽器是安裝DrissionPage時自動安裝的 # 跳轉百度頁面 page.get('https://www.baidu.com') time.sleep(1) page.ele('xpath://*[@id="kw"]').input("宿舍") time.sleep(1) page.ele('xpath://*[@id="su"]').click() time.sleep(1) page.ele('xpath://*[@id="3"]/div/div[1]/h3/a').click() #切換到新頁面 ab=page.get_tab(page.latest_tab) #獲取新窗口頁面句柄 # 等待頁面跳轉 page.wait.load_start() # ab = page.geqwt_tab(0) #這樣也可以獲取新框框頁面句柄 print(ab.title) #獲取頁面標題 # exit() #切換到新頁面 # ab=page.get_tab(1) # page.get_tab(page.latest_tab) # print(ab.title) # page.get_tab(page.latest_tab) # print(page.title) # exit() time.sleep(1) #通過用新窗口的句柄來進行操作 ab.ele('xpath:/html/body/div[1]/div[3]/form/div/input[4]').input("家") ab.ele('xpath:/html/body/div[1]/div[3]/form/div/span').click() lis = ab.ele('xpath:/html/body/div[2]/div[1]/div/div[2]/ul') # lis = page.ele('xpath://ul[@class="w4]') # print(lis) lis1 = lis.eles('tag:li') for i in lis1: lis2 = i.eles('tag:a') for j in lis2: href=j.attr('href') #獲取href屬性值 # title=i.text title=j.attr('title') #獲取title屬性值 print(href,title) time.sleep(4) # ab.close() #關閉當前頁面 (這樣也可以) page.close_tabs(ab) #關閉當前頁面 # ac=page.get_tab(-1) ac=page.get_tab(page.latest_tab) #將句柄調回原來的頁面中 print(ac.title) time.sleep(1) ac.ele('xpath://*[@id="6"]/div/div[1]/h3/a').click() time.sleep(2) page.quit() #退出瀏覽器
5.高級用法
-
瀏覽器下載功能,瀏覽器頁面對象可對瀏覽器下載任務進行控制
from DrissionPage import Chromium tab = Chromium().latest_tab tab.set.download_path('save_path') # 設置文件保存路徑 tab.set.download_file_name('file_name') # 設置重命名文件名 tab('t:a').click() # 點擊一個會觸發下載的鏈接 tab.wait.download_begin() # 等待下載開始 tab.wait.downloads_done() # 等待下載結束 -
配置文件的使用,可用於配置請求頭、代理、瀏覽器配置等參數
[paths] download_path = tmp_path = [chromium_options] address = 127.0.0.1:9222 browser_path = chrome arguments = ['--no-default-browser-check', '--disable-suggestions-ui', '--no-first-run', '--disable-infobars', '--disable-popup-blocking', '--hide-crash-restore-bubble', '--disable-features=PrivacySandboxSettings4'] extensions = [] prefs = {'profile.default_content_settings.popups': 0, 'profile.default_content_setting_values': {'notifications': 2}} flags = {} load_mode = normal user = Default auto_port = False system_user_path = False existing_only = False new_env = False [session_options] headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8', 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'connection': 'keep-alive', 'accept-charset': 'GB2312,utf-8;q=0.7,*;q=0.7'} [timeouts] base = 10 page_load = 30 script = 30 [proxies] http = https = [others] retry_times = 3 retry_interval = 2使用配置文件加載
from DrissionPage import ChromiumOptions, Chromium
co = ChromiumOptions(ini_path=r'D:\setting.ini')
browser = Chromium(addr_or_opts=co)
- 切換使用瀏覽器,deissionpage默認使用chrome瀏覽器
from DrissionPage import ChromiumOptions, Chromium
co = ChromiumOptions(ini_path=r'D:\setting.ini')
co.set_browser_path('C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe')
browser = Chromium(addr_or_opts=co)
-
使用無頭模式訪問網站
from drission import Drission # 創建 Drission 對象 drission = Drission() # 使用 Drission 對象初始化 ChromiumPage,並設置初始化配置 page = drission.use_chromium( headless=False, # 是否啓用無頭模式 args=["--window-size=1200,800"], # 設置窗口大小 proxy="127.0.0.1:8080", # 設置代理 user_agent="MyCustomUserAgent", # 自定義 User-Agent disable_image=True # 禁用圖片加載以加速頁面加載 ) page.get("https://example.com") page.wait_load() # 等待頁面加載完成 -
不打開瀏覽器設置
co = ChromiumOptions co.headless(True)