快速學Python,走個捷徑~

蔡不菜丶發表於2021-11-21

大家好,我是小菜。
一個希望能夠成為 吹著牛X談架構 的男人!如果你也想成為我想成為的人,不然點個關注做個伴,讓小菜不再孤單!

本文主要介紹 Selenium

如有需要,可以參考

如有幫助,不忘 點贊

微信公眾號已開啟,小菜良記,沒關注的同學們記得關注哦!

哈嘍,大家好。這裡是小菜良記的前身菜農曰。不要因為名字改了,頭像換了,大家就迷路了哦~

最近為了擴充套件語言面,這周大概瞭解了一下 Python 的玩法,學完之後發現,哎嘛,真香。不知道大家剛學一門語言的時候有沒有覺得這語言有點意思,什麼都想試一試。

說到 Python 大家的反應可能就是 爬蟲自動化測試,比較少會說到用 python 來做 web 開發,相對來說,在國內 web 開發使用比較多的語言還是 java~ 但是並不是說 python 不適合用於做 web 開發,據我瞭解到常用的 web框架有Djangoflask 等~

Django 是一個很重的框架,它提供了很多很方便的工具,對很多東西也進行封裝,不需要自己過多的造輪子

Flask 的優點是小巧,但缺點也是小巧,靈活的同時意味著自己需要造更多的輪子,或者花更多的時間配置

但是我們們這篇的重點不是介紹 python 的 web 開發,也不是介紹 python 的基礎入門,而是聊聊 python 的自動化測試和爬蟲入門~

在我看來,如果你有其他語言的開發經驗,小菜還是比較建議直接從一個案例入手,一邊看一邊學,語法之類其實都是相同的(後面會出結合 java 去學 python 的內容),程式碼基本能讀個八九不離十,但是如果沒有任何語言開發經驗的同學,那小菜還是建議從頭系統的學習,視訊和書籍都是不錯的選擇,這裡推薦 廖雪峰老師 的部落格,內容相當不錯 Python教程

一、自動化測試

python 能幹的事情很多,能幹有趣的事情也很多

學習一門語言,當然得找興趣點才能學得更快,比如說你想要爬某某網站的圖片或視訊,是吧~

什麼是自動化測試?那就是 自動化 + 測試,只要你編寫好了一段指令碼(.py 檔案),執行後會自動幫你在後臺進行測試的流程執行,那麼使用自動化測試,有一個很好的工具可以幫助你完成,那就是 Selenium

Selenium 是一款 web 自動化測試工具,可以很方便地模擬真實使用者對瀏覽器的操作,它支援各種主流瀏覽器,比如IE、Chrome、Firefox、Safari、Opera 等,這裡使用 python 進行演示說明,並不是說 Selenium 只支援 python,它有多重程式語言的客戶端驅動,語法簡介~ 下面我們做一個簡單的示例演示!

1)前置準備

為了保證演示的順利,我們需要做一些前置準備,不然可能會造成瀏覽器無法正常開啟的情況~

步驟1

檢視瀏覽器版本,我們以下是使用 Edge,我們可在網址輸入框輸入 edge://version 檢視瀏覽器版本,然後到對應的驅動商店進行對應版本驅動的安裝 Microsoft Edge - Webdriver (windows.net)

步驟2

然後我們將下載好的驅動檔案解壓到你 python 的安裝目錄下的 Scripts資料夾下

image-20211119231250381

2)瀏覽器操作

做好前置準備,我們來看下面一段簡單程式碼:

加上導包總共也才 4 行程式碼,並在終端輸入 python autoTest.py,並得到了以下演示效果:

可以看到利用該指令碼已經實現了自動開啟瀏覽器自動放大視窗自動開啟百度網頁,三個自動化操作,將我們的學習向前拉近了一步,是不是覺得有點意思~ 下面讓你逐漸沉淪!

這裡介紹幾個針對瀏覽器操作的常用方法:

方法說明
webdriver.xxx()用於建立瀏覽器物件
maximize_window()視窗最大化
get_window_size()獲取瀏覽器尺寸
set_window_size()設定瀏覽器尺寸
get_window_position()獲取瀏覽器位置
set_window_position(x, y)設定瀏覽器位置
close()關閉當前標籤/視窗
quit()關閉所有標籤/視窗

這幾個當然是 Selenium 的基本常規操作,更出色的還在後面~

當我們開啟了瀏覽器,想做的當然不只是開啟網頁這種簡單的操作,畢竟程式設計師的野心是無限的!我們還想自動操作頁面元素,那麼這就需要說到 Selenium 的定位操作了

3)定位元素

頁面的元素定位對於前端來說並不陌生,用 JS 可以很輕鬆的實現元素定位,比如以下幾種:

  • 通過 id 進行定位

document.getElementById("id")

  • 通過 name 進行定位

document.getElementByName("name")

  • 通過標籤名進行定位

document.getElementByTagName("tagName")

  • 通過 class 類進行定位

document.getElementByClassName("className")

  • 通過 css 選擇器進行定位

document.querySeletorAll("css selector")

以上幾種方式都能實現元素的選取定位,當然我們這節的主角是 Selenium,作為主推的自動化測試工具,怎麼能示弱呢~ 它實現頁面元素定位的方式有 8 種,如下:

  1. id定位

driver.find_element_by_id("id")

我們開啟百度頁面,可以發現該輸入框的 id 是 kw,

在清楚了元素 ID 之後,我們就可以使用 id 進行元素定位,方式如下

from selenium import webdriver

# 載入 Edge 驅動
driver = webdriver.ChromiumEdge()
# 設定最大視窗化
driver.maximize_window()
# 開啟百度網頁
driver.get("http://baidu.com")

# 通過 id 定位元素
i = driver.find_element_by_id("kw")
# 往輸入框輸入值
i.send_keys("菜農曰")

  1. name屬性值定位

driver.find_element_by_name("name")

name 定位的方式與 id 相似,都是需要通過查詢name的值,然後呼叫對應的 api,使用方式如下:

from selenium import webdriver

# 載入 Edge 驅動
driver = webdriver.ChromiumEdge()
# 設定最大視窗化
driver.maximize_window()
# 開啟百度網頁
driver.get("http://baidu.com")

# 通過 id 定位元素
i = driver.find_element_by_name("wd")
# 往輸入框輸入值
i.send_keys("菜農曰")
  1. 類名定位

driver.find_element_by_class_name("className")

與 id 和 name 定位方式一致,需要找到對應的 className 然後進行定位~

  1. 標籤名定位

driver.find_element_by_tag_name("tagName")

這種方式我們在日常中使用還是比較少的,因為在 HTML 是通過 tag 來定義功能的,比如 input 是輸入,table 是表格... 每個元素其實都是一個 tag,一個 tag 往往用來定義一類功能,在一個頁面中可能存在多個 div,input,table 等,因此使用 tag 很難精準定位元素~

  1. css選擇器

driver.find_element_by_css_selector("cssVale")

這種方式需要連線 css 的五大選擇器

五大選擇器

  1. 元素選擇器

最常見的css選擇器便是元素選擇器,在HTML文件中該選擇器通常是指某種HTML元素,例如:

html {background-color: black;}
p {font-size: 30px; backgroud-color: gray;}
h2 {background-color: red;}
  1. 類選擇器

.加上類名就組成了一個類選擇器,例如:

.deadline { color: red;}
span.deadline { font-style: italic;}
  1. id 選擇器

ID選擇器和類選擇器有些類似,但是差別又十分顯著。首先一個元素不能像類屬性一樣擁有多個類,一個元素只能擁有一個唯一的ID屬性。使用ID選擇器的方法為井號#加上id值,例如:

#top { ...}
  1. 屬性選擇器

我們可以根據元素的屬性及屬性值來選擇元素,例如:

a[href][title] { ...}
  1. 派生選擇器

它又名上下文選擇器,它是使用文件DOM結構來進行css選擇的。例如:

body li { ...}
h1 span { ...}

當然這邊選擇器只是做一個簡單的介紹,更多內容自行文件查閱~

在瞭解選擇器之後我們就可以愉快的進行 css 選擇器 定位了:

from selenium import webdriver

# 載入 Edge 驅動
driver = webdriver.ChromiumEdge()
# 設定最大視窗化
driver.maximize_window()
# 開啟百度網頁
driver.get("http://baidu.com")

# 通過 id選擇器 定位元素
i = driver.find_elements_by_css_selector("#kw")
# 往輸入框輸入值
i.send_keys("菜農曰")
  1. 連結文字定位

driver.find_element_by_link_text("linkText")

這種方式是專門用來定位文字連結的,比如我們可以看到百度的首頁上有個 新聞hao123地圖... 等連結元素

那麼我們就可以利用連結文字來進行定位

from selenium import webdriver

# 載入 Edge 驅動
driver = webdriver.ChromiumEdge()
# 設定最大視窗化
driver.maximize_window()
# 開啟百度網頁
driver.get("http://baidu.com")

# 通過 連結文字 定位元素並 點選
driver.find_element_by_link_text("hao123").click()

  1. 部分連結文字

driver.find_element_by_partial_link_text("partialLinkText")

這種方式是對 link_text 的輔助,有時候可能一個超連結文字特別長,如果我們全部輸入既麻煩又不美觀

那其實我們只需要擷取一部分字串讓 selenium 理解我們要選取的內容即可,那麼就是使用 partial_link_text 這種方式~

  1. xpath 路徑表示式

driver.find_element_by_xpath("xpathName")

前面介紹的幾種定位方法都是在理想狀態下,每個元素都有一個唯一的id或name或class或超連結文字的屬性,那麼我們就可以通過這個唯一的屬性值來定位他們。但是有時候我們要定位的元素並沒有id,name,class屬性,或者多個元素的這些屬性值都相同,又或者重新整理頁面,這些屬性值都會變化。那麼這個時候我們就只能通過xpath或者CSS來定位了。當然 xpath 的值並不需要你去計算我們只需要開啟頁面然後在 F12 中找到對應元素,右擊複製 xpath 即可

然後在程式碼中進行定位:

from selenium import webdriver

# 載入 Edge 驅動
driver = webdriver.ChromiumEdge()
# 設定最大視窗化
driver.maximize_window()
# 開啟百度網頁
driver.get("http://www.baidu.com")

driver.find_element_by_xpath("//*[@id='kw']").send_keys("菜農曰")

4)元素操作

我們想做的當然不只是元素的選取,而是選取元素後的操作,我們在上面演示中其實就已經進行了兩種操作 click()send_keys("value"),這裡繼續介紹幾種其他操作~

方法名說明
click()點選元素
send_keys("value")模擬按鍵輸入
clear()清除元素的內容,比如 輸入框
submit()提交表單
text獲取元素的文字內容
is_displayed判斷元素是否可見

看完是不是有一種似曾相似的感覺,這不就是 js 的基本操作嗎~!

5)實操練習

學完以上操作,我們就可以模擬一個小米商城的購物操作,程式碼如下:

from selenium import webdriver

item_url = "https://www.mi.com/buy/detail?product_id=10000330"

# 載入 Edge 驅動
driver = webdriver.ChromiumEdge()
# 設定最大視窗化
driver.maximize_window()
# 開啟商品購物頁
driver.get(item_url)
# 隱式等待 設定 防止網路阻塞頁面未及時載入
driver.implicitly_wait(30)

# 選擇地址
driver.find_element_by_xpath("//*[@id='app']/div[3]/div/div/div/div[2]/div[2]/div[3]/div/div/div[1]/a").click()
driver.implicitly_wait(10)
# 點選手動選擇地址
driver.find_element_by_xpath("//*[@id='stat_e3c9df7196008778']/div[2]/div[2]/div/div/div/div/div/div/div["
                             "1]/div/div/div[2]/span[1]").click()
# 選擇福建
driver.find_element_by_xpath("//*[@id='stat_e3c9df7196008778']/div[2]/div[2]/div/div/div/div/div/div/div/div/div/div["
                             "1]/div[2]/span[13]").click()
driver.implicitly_wait(10)
# 選擇市
driver.find_element_by_xpath("//*[@id='stat_e3c9df7196008778']/div[2]/div[2]/div/div/div/div/div/div/div/div/div/div["
                             "1]/div[2]/span[1]").click()
driver.implicitly_wait(10)
# 選擇區
driver.find_element_by_xpath("//*[@id='stat_e3c9df7196008778']/div[2]/div[2]/div/div/div/div/div/div/div/div/div/div["
                             "1]/div[2]/span[1]").click()
driver.implicitly_wait(10)
# 選擇街道
driver.find_element_by_xpath("//*[@id='stat_e3c9df7196008778']/div[2]/div[2]/div/div/div/div/div/div/div/div/div/div["
                             "1]/div[2]/span[1]").click()
driver.implicitly_wait(20)

# 點選加入購物車
driver.find_element_by_class_name("sale-btn").click()
driver.implicitly_wait(20)

# 點選去購物車結算
driver.find_element_by_xpath("//*[@id='app']/div[2]/div/div[1]/div[2]/a[2]").click()
driver.implicitly_wait(20)

# 點選去結算
driver.find_element_by_xpath("//*[@id='app']/div[2]/div/div/div/div[1]/div[4]/span/a").click()
driver.implicitly_wait(20)

# 點選同意協議
driver.find_element_by_xpath("//*[@id='stat_e3c9df7196008778']/div[2]/div[2]/div/div/div/div[3]/button[1]").click()

效果如下:

這便是我們學習成果的實踐,當然如果遇到秒殺情況不妨也可以寫個指令碼練練手~ ,如果無貨的情況我們可以加個 while 迴圈去輪詢訪問!

二、爬蟲測試

上面我們實現瞭如何使用 Selenium 來實現自動化測試,使用須合法~ 接下來我們來展示 python 另一個強大的功能,那就是用於 爬蟲

在學習爬蟲之前,我們需要了解幾個必要的工具

1)頁面下載器

python 標準庫中已經提供了 :urlliburllib2httplib 等模組以供 http 請求,但是 api 不夠好用優雅~,它需要巨量的工作,以及各種方法的覆蓋,來完成最簡單的任務,當然這是程式設計師所不能忍受的,各方豪傑開發除了各種好用的第三方庫以供使用~

  • request

request 是使用 apaches2 許可證的基於 python 開發的http庫,它在 python 內建模組的基礎上進行了高度的封裝,從而使使用者在進行網路請求時可以更加方便的完成瀏覽器可有的所有操作~

  • scrapy

request 和 scrapy 的區別可能就在於,scrapy 是一個比較重量級的框架,它屬於網站級爬蟲,而 request 是頁面級爬蟲,併發數和效能沒有 scrapy 那麼好

2)頁面解析器

  • BeautifulSoup

BeautifulSoup是一個模組,該模組用於接收一個HTML或XML字串,然後將其進行格式化,之後遍可以使用他提供的方法進行快速查詢指定元素,從而使得在HTML或XML中查詢指定元素變得簡單。

  • scrapy.Selector

Selector 是基於parsel,一種比較高階的封裝,通過特定的 XPath 或者 CSS 表示式來選擇HTML檔案中的某個部分。它構建於 lxml 庫之上,這意味著它們在速度和解析準確性上非常相似。

具體使用可以查閱Scrapy 文件,介紹的相當詳細

3)資料儲存

當我們爬下來內容後,這個時候就需要有一個對應的儲存源進行儲存

具體資料庫操作會在後續的 web 開發博文中進行介紹~
  • txt 文字

使用檔案 file 的常用操作

  • sqlite3

SQLite,是一款輕型的資料庫,是遵守ACID的關係型資料庫管理系統,它包含在一個相對小的C庫中

  • mysql

不做過多介紹,懂的都懂,web 開發老情人了

4)實操練習

網路爬蟲,其實叫作網路資料採集更容易理解。它就是通過程式設計向網路伺服器請求資料(HTML表單),然後解析HTML,提取出自己想要的資料。

我們可以簡單分為 4 個步驟:

  • 根據給定 url 獲取 html 資料
  • 解析 html,獲取目標資料
  • 儲存資料

當然這一切需要建立在你懂 python 的簡單語法和 html 的基本操作~

我們接下來使用 request + BeautifulSoup + text 的組合進行操作練習,假定我們想要爬取廖雪峰老師的python教程內容~

# 匯入requests庫
import requests
# 匯入檔案操作庫
import codecs
import os
from bs4 import BeautifulSoup
import sys
import json
import numpy as np
import importlib

importlib.reload(sys)

# 給請求指定一個請求頭來模擬chrome瀏覽器
global headers
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36'}
server = 'https://www.liaoxuefeng.com/'
# 廖雪峰python教程地址
book = 'https://www.liaoxuefeng.com/wiki/1016959663602400'
# 定義儲存位置
global save_path
save_path = 'D:/books/python'
if os.path.exists(save_path) is False:
    os.makedirs(save_path)


# 獲取章節內容
def get_contents(chapter):
    req = requests.get(url=chapter, headers=headers)
    html = req.content
    html_doc = str(html, 'utf8')
    bf = BeautifulSoup(html_doc, 'html.parser')
    texts = bf.find_all(class_="x-wiki-content")
    # 獲取div標籤id屬性content的內容 \xa0 是不間斷空白符  
    content = texts[0].text.replace('\xa0' * 4, '\n')
    return content


# 寫入檔案
def write_txt(chapter, content, code):
    with codecs.open(chapter, 'a', encoding=code)as f:
        f.write(content)


# 主方法
def main():
    res = requests.get(book, headers=headers)
    html = res.content
    html_doc = str(html, 'utf8')
    # HTML解析
    soup = BeautifulSoup(html_doc, 'html.parser')
    # 獲取所有的章節
    a = soup.find('div', id='1016959663602400').find_all('a')
    print('總篇數: %d ' % len(a))
    for each in a:
        try:
            chapter = server + each.get('href')
            content = get_contents(chapter)
            chapter = save_path + "/" + each.string.replace("?", "") + ".txt"
            write_txt(chapter, content, 'utf8')
        except Exception as e:
            print(e)


if __name__ == '__main__':
    main()

當我們執行程式後便可以在 D:/books/python 位置看到我們所爬取到的教程內容!

這樣子我們就已經簡單的實現了爬蟲,不過爬蟲需謹慎~!

我們們這篇以兩個維度 自動化測試爬蟲 認識了 python的使用,希望能夠激發出你的興趣點~

不要空談,不要貪懶,和小菜一起做個吹著牛X做架構的程式猿吧~點個關注做個伴,讓小菜不再孤單。我們們下文見!

今天的你多努力一點,明天的你就能少說一句求人的話!
我是小菜,一個和你一起變強的男人。 ?
微信公眾號已開啟,小菜良記,沒關注的同學們記得關注哦!

相關文章