Puppeteer介紹

從Node.js中以程式化方式控制Chrome。 Puppeteer是一個我們可以使用的Node庫,用於控制一個無界面Chrome實例。我們基本上是使用Chrome,但以JavaScript進行程式化操作。 使用它,我們可以: 爬取網頁 自動化表單提交 執行任何種類的瀏覽器自動化 追蹤頁面加載性能 創建使用服務器端渲染的單頁應用程序的版本 生成網頁的截圖 創建自動化測試 從網頁生成PDF文件 它是由Google開發的。它本身並不會解鎖任何新功能,但它將我們需要處理的許多細節抽象出來,而不使用它。 簡而言之,它讓事情變得非常簡單。 由於它在初始化時啟動一個新的Chrome實例,它可能不是最高效的。然而,它是使用實際瀏覽器(在幕後)進行自動測試的最準確的方法。 準確地說,它使用的是Chromium,也就是Chrome的開源部分。這意味著您沒有Google許可的專有編解碼器(MP3,AAC,H.264等),也沒有與Google服務(如崩潰報告,Google更新等)的集成,但從編程的角度來看,它應該與Chrome完全相似(除了媒體播放,如前所述)。 安裝Puppeteer 首先要使用以下命令安裝: npm install puppeteer 這將下載並打包最新版本的Chromium。 您也可以選擇安裝puppeteer-core,讓puppeteer運行您已安裝的本地Chrome。在某些特殊情況下這很有用(參見[puppeteer vs puppeteer-core](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteer-vs-puppeteer-core))。通常,您只需選擇puppeteer。 使用Puppeteer 在一個Node.js文件中,引入它: const puppeteer = require('puppeteer'); 然後,我們可以使用launch()方法創建一個瀏覽器實例: (async () => { const browser = await puppeteer.launch() })() 我們也可以這樣寫: puppeteer.launch().then(async browser => { //... }) 您可以將選項對像傳遞給puppeteer.launch()。最常見的選項是: puppeteer.launch({ headless:false }) 以在Puppeteer執行操作時顯示Chrome。這樣可以方便地查看正在發生的事情並進行調試。 我們使用await,所以我們必須將此方法調用包裹在一個異步函數中,我們會立即調用它(/ javascript-iife /)。 接下來,我們可以使用browser對像上的newPage()方法獲取page對象: (async () => { const browser = await puppeteer.launch() const page = await browser....

Python 2 vs Python 3

從一開始就有一個重要的主題需要討論,那就是 Python 2 和 Python 3 的比較。 Python 3 於 2008 年推出,並成為主要的 Python 版本,而 Python 2 則繼續維護修復錯誤和安全漏洞,直到 2020 年初。 在那個日期之後,終止了對 Python 2 的支援。 許多程式仍然使用 Python 2 來撰寫,且組織仍然積極地在進行這方面的工作,因為將程式遷移到 Python 3 不是一個簡單的任務,而且這些程式需要大量的工作才能進行升級。此外,重要的遷移總是會引入新的錯誤。 但是,除非您必須遵守組織設定的規則,強制使用 Python 2,否則所有新的程式都應該使用 Python 3 來撰寫。

Python Docstrings

文檔是非常重要的,不僅可以與其他人溝通函數/類/方法/模塊的目標,也可以幫助自己記住這些知識。 當你6個月或12個月後回到你的代碼時,你可能不記得心中所保存的所有知識,通讀代碼並理解其目的將變得困難得多。 註釋(Comments)是一種方式: num = 1 #這是另一個註釋 另一種方式是使用文檔字符串(docstrings)。 文檔字符串的好處在於它們遵循慣例,因此可以自動處理。 這是如何為函數定義文檔字符串: def increment(n): """增加一個數字""" return n + 1 這是如何為類和方法定義文檔字符串: class Dog: """表示一只狗的類""" def __init__(self, name, age): """初始化一只新狗""" self.name = name self.age = age def bark(self): """讓狗叫""" print('WOF!') 通過在文件頂部放置一個文檔字符串來為模塊進行文檔,例如假設這是dog.py: """狗模塊 這個模塊做...佈拉佈拉佈拉,並提供以下類: - Dog ... """ class Dog: """表示一只狗的類""" def __init__(self, name, age): """初始化一只新狗""" self.name = name self.age = age def bark(self): """讓狗叫""" print('WOF!') 文檔字符串可以跨越多行: def increment(n): """增加 一個數字 """ return n + 1 Python會處理這些文檔字符串,你可以使用help()全局函數來獲取類/方法/函數/模塊的文檔。...

Python Lambda 函數

Lambda 函數(也稱為匿名函數)是沒有名字且只有一個表達式作為其函體的小型函數。 在 Python 中,它們使用 lambda 關鍵字來定義: lambda <參數> : <表達式> 函體必須是單個表達式。注意,這是表達式,而不是語句。 這個差異很重要。一個表達式返回一個值,而一個語句則不會。 最簡單的 lambda 函數示例是將數字的值加倍: lambda num : num * 2 Lambda 函數可以接受多個參數: lambda a, b : a * b Lambda 函數不能直接調用,但可以將它們分配給變量: multiply = lambda a, b : a * b print(multiply(2, 2)) # 4 Lambda 函數在與其他 Python 功能(例如 map()、filter() 和 reduce())結合使用時非常有用。

Python List Comprehensions

Python 列表推導式 列表推導式(List comprehensions)是一種非常簡潔的方法來創建列表。 假設你有一個列表: numbers = [1, 2, 3, 4, 5] 你可以使用列表推導式來創建一個新的列表,該列表由 numbers 列表元素的平方組成: numbers_power_2 = [n**2 for n in numbers] 在某些情況下,列表推導式的語法比循環更易讀,特別是當操作可以寫在一行上時: numbers_power_2 = [] for n in numbers: numbers_power_2.append(n**2) 也比 map() 函數更易讀: numbers_power_2 = list(map(lambda n: n**2, numbers))

Python 元組

元組是另一種基本的 Python 數據結構。 它們允許你創建不可變的對象組。這意味著一旦創建了元組,它就無法被修改。你無法添加或刪除項目。 它們的創建方式與列表類似,但使用圓括號而不是方括號: names = ("Roger", "Syd") 元組是有序的,就像列表一樣,所以你可以通過索引值獲取它的值: names[0] # "Roger" names[1] # "Syd" 你還可以使用 index() 方法: names.index('Roger') # 0 names.index('Syd') # 1 與字符串和列表一樣,使用負索引將從末尾開始搜索: names[-1] # True 你可以使用 len() 函數計算元組中的項目數量: len(names) # 2 你可以使用 in 運算符檢查一個項目是否包含在元組中: print("Roger" in names) # True 你還可以使用切片提取元組的一部分: names[0:2] # ('Roger', 'Syd') names[1:] # ('Syd',) 使用 len() 全局函數獲取元組中的項目數量,與我們用於獲取字符串的長度相同: len(names) #2 你可以使用 sorted() 全局函數創建元組的排序版本: sorted(names) 你可以使用 + 運算符從現有元組中創建新的元組: newTuple = names + ("Vanille", "Tina")

Python 內省

使用 內省(introspection) 可以分析函數、變量和物件。 首先,可以使用 help() 全域函數以文件字串(docstrings)的形式獲取文件。 然後,可以使用 print() 函數來獲取關於函數的資訊: def increment(n): return n + 1 print(increment) 或者物件的資訊: class Dog(): def bark(self): print('WOF!') roger = Dog() print(roger) type() 函數可以提供物件的類型: print(type(increment)) print(type(roger)) print(type(1)) print(type('test')) dir() 全域函數可以查找物件的所有方法和屬性: print(dir(roger)) id() 全域函數可以顯示任何物件在記憶體中的位置: print(id(roger)) # 140227518093024 print(id(1)) # 140227521172384 這可以用來檢查兩個變數是否指向同一個物件。 Python 的標準庫模組 inspect 提供了更多獲取物件資訊的工具,可以在這裡查看詳細內容:https://docs.python.org/3/library/inspect.html

Python 布林值

Python 提供了 bool 型別,它可以有兩個值:True 和 False(大小寫有別)。 done = False done = True 布林值在條件控制結構(如 if 語句)中尤其有用: done = True if done: # 在這裡運行一些程式碼 else: # 在這裡運行一些其他程式碼 在評估一個值是 True 還是 False 時,如果該值不是布林值,我們有一些規則,取決於我們要檢查的型別: 數字除了數字 0 外,都是 True 空字串是 False 列表、元組、集合、字典只有在空的時候才是 False 你可以這樣檢查一個值是否為布林值: done = True type(done) == bool #True 或者使用 isinstance() 函數,傳入兩個參數:變數和 bool 類: done = True isinstance(done, bool) #True 全局函數 any() 在處理布林值時也非常有用,它在傳入的可迭代物(例如列表)中的任何值為 True 時返回 True: book_1_read = True book_2_read = False read_any_book = any([book_1_read, book_2_read]) 全局函數 all() 類似,但它只有在傳入的所有值都為 True 時返回 True:...

Python 列舉

列舉是綁定到常量值的可讀名稱。 要使用列舉,請從 enum 標準庫模塊中導入 Enum : from enum import Enum 然後可以以此方式初始化一個新的列舉: class State(Enum): INACTIVE = 0 ACTIVE = 1 一旦這樣做了,您就可以引用 State.INACTIVE 和 State.ACTIVE,它們扮演常量的角色。 現在,如果您嘗試打印 State.ACTIVE,例如: print(State.ACTIVE) 它不會返回 1,而是返回 State.ACTIVE。 可以通過列舉分配的數字來達到相同的值:print(State(1)) 將返回 State.ACTIVE。使用方括號表示法 State['ACTIVE'] 也是如此。 但是您可以使用 State.ACTIVE.value 來獲取值。 您可以列出列舉的所有可能值: list(State) # [<State.INACTIVE: 0>, <State.ACTIVE: 1>] 您可以計算個數: len(State) # 2

Python 多型

多型(Polymorphism)是一種將功能泛化至不同類型的重要概念,它在物件導向程式設計中扮演著重要的角色。 我們可以在不同的類別上定義相同的方法: class Dog: def eat(): print('吃狗食') class Cat: def eat(): print('吃貓食') 然後我們可以建立物件並呼叫 eat() 方法,不論物件屬於哪個類別,都能得到不同的結果: animal1 = Dog() animal2 = Cat() animal1.eat() animal2.eat() 我們建立了一個泛用的介面,現在不需要知道動物是貓還是狗。