前言 ´・ᴗ・`
- 本節主要來個對著名自動化測試工具selenium 有個感性的認知“Getting started” 算作爬蟲篇的開頭
- 案例就是 讓selenium幫我自動登錄 csdn網站
- 實現方法很多 這裏只是演示用selenium 大神不喜勿噴:)
- 注意 爬蟲的前提在於你對web運作有足夠的瞭解 否則一出問題 google stackoverflow 你連問題都問不出來:)
- 實驗採用Chrome 78之前的版本測試 注意
建議你參考一下我的一些文章(前五篇就夠了 後面就是設計後端開發了)然後對web有些大概瞭解
服務端編程專欄
或者你也可以自行查詢 祝你能夠找到系統講解這方面知識的大佬(我找不到2333) - 本篇內容將會幫您…
- 瞭解selenium的大概工作原理
- 從而瞭解selenium的優缺點 使用場景
- 介紹selenium運行的必備組件
- 瞭解webdriver是什麼
- 學習如何創建瀏覽器webdriver實例
- 如何找到控件的xpath地址
- 如何通過xpath定位控件的對象
- 如何點擊控件
- 如何向控件輸入字符
selenium 原理講解
selenium 這個詞很裝逼 硒元素的意思
他的牛逼之處在於 直接模仿我們用戶 操作瀏覽器
也就是說 他就是通過瀏覽器獲取信息的 意味着根本不需要防止反爬蟲策略——他就是一個通過瀏覽器訪問頁面的客戶啊:)
當然了 弊端很明顯——我們訪問頁面速度快嘛 相對於一般的爬蟲
當然不怎麼快 所以可能彌補的方法就是 多線程 開很多的瀏覽頁面 當然對系統資源佔用很大——瀏覽器還要負責渲染頁面(當然你可以做點優化讓他別加載你不感興趣的內容)
所以用在那種需要複雜認證的場合 尤其是限制流量 固定時間訪問次數的服務器——我們本來就快不了 selenium慢 反而一定程度上是件好事
當然有其他方式 弄代理也是ok的 問題是免費 穩定的代理真心不好找 找到了速度也不夠 需要大量線程支持 這個沒點基礎搞不來 畢竟爬一天不到你就看到滿屏幕的Exception:)
另外 這個 人擋殺人佛擋殺佛的神器 一般也用於做web頁面的自動化測試 原因你懂的
好奇嘛?爲啥他就能夠模擬用戶點擊網頁.輸入賬號密碼自動登錄.和各種神奇的功能
他最初的版本是通過注入js腳本(Hook in)的方法,然而太不穩定了 於是就針對市面上通行的幾個瀏覽器,利用瀏覽器的API來操作
優點就是更加穩定 當然問題就是 更慢了 而且每種瀏覽器 套路不同
所以我們使用的時候 需要給每種瀏覽器創造實例 稱爲web driver 實例
那麼 這項神器的工作原理是什麼呢?
下面我畫一張圖你就明白了:
可見 有三個關鍵部分:
- 自己的代碼code
- web driver
- 還有自己的瀏覽器browser
web driver的配置
web driver是什麼呢?你可以理解爲 他就是一個封裝了各種能夠控制瀏覽器的工具的一個程序
當然你需要指定好 控制的是什麼瀏覽器(chrome 還是 火狐 還是 IE edge還是…)
我們需要下載各種類型的web driver並且安裝
這裏提供
- chrome driver
對於chrome 版本對應問題 參考:
https://blog.csdn.net/huilan_same/article/details/51896672 - firefox driver geckodriver
- IE IEdriver
下載解壓後,將chromedriver.exe , geckodriver.exe , Iedriver.exe發到Python的安裝目錄,然後再將Python的安裝目錄添加到系統環境變量的Path下面。(這個相信你已經做過了:)
回到我們代碼上
控制瀏覽器 我們需要指定瀏覽器 方法就是 創造對應瀏覽器的實例 我們
這麼寫:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.python.org")
這個driver就是chrome瀏覽器的實例
而driver.get
操作流程是:會先等待你的目標網頁加載完 然後再把控制權移交到你的控制代碼上(就是模擬點擊 爬取信息什麼的 重頭戲)
因此 對於AJAX太多的1網頁 可能對selenium不是很友好(不知道那玩意加載完了沒 當然 網速不太慢都問題不大 比如有個50兆)
不懂AJAX可以參考我的這篇文章:服務端編程(五)——AJAX
我們運行一下 就能看到:
csdn加載出來了
locate element 鎖定控件
接下來 我們用xpath(一種標記網頁控件位置的方法 可以當做是地址)地址來鎖定“登錄”按鈕
xpath是用於標記XML的節點的 類似於HTML文件中DOM節點的標記方式
第一步 F12 然後用圈起來的工具
第二步 點擊所需要鎖定的控件
第三步 找到高亮顯示的代碼 就是對應控件的代碼啦
第四步 找到其xpath地址 我們右鍵 點擊“copy xpath”
然後我們就可以用selenium封裝好的 通過xpath找element的方法啦
注意 別的索引方式(找element地址)的方式比如css選擇器(selector)或者DOM節點尋找都是可行的
而且selenium有封裝
但是xpath也是常規爬蟲常見的元件鎖定方式 這裏就用xpath 有興趣的可以瞭解py的xpath庫
其他鎖定element的方式 我後面會更新相應文章 畢竟很多時候 一個鎖定方式不管用
login_button = driver.find_element_by_xpath('//*[@id="csdn_container_tool"]/div/ul/li[3]/a')
往函數find_element_by_xpath裏面放 xpath就行了
如何點擊控件
很簡單 調用click()方法就行了
找到登錄按鈕對象 我們就可以點擊了:
login_button.click()
注意1 事實上 這麼寫會更加保險 這個後面會講到 善用等待, 以防止頁面還沒有加載出來,你點空了的情況
wait_para = WebDriverWait(driver, 10)
login_button = wait_para.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="csdn_container_tool"]/div/ul/li[3]/a')))
注意2 另外 這個點擊的強大之處在於 當頁面跳轉 他只管當前的頁面 不會說你重定向了 就沒辦法定位了
然後我們進到這個頁面
向控件輸入字符
調用 send.keys 方法:
login_input_user = wait_para.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="all"]')))
login_input_user.send_keys('2333')
# 手機號
login_input_psw = wait_para.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="password-number"]')))
login_input_psw.send_keys('2333')
# 密碼
login_button_3 = wait_para.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="app"]/div/div/div[1]/div[2]/div[5]/div/div[6]/div/button')))
login_button_3.click()
效果如下:
然後點擊登錄即可
其他細節等以後我們學習深入了再講 這裏填代碼完事
完整代碼:
#-*- utf-8 -*-
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from time import sleep
from selenium.webdriver import Chrome
from selenium.webdriver import ChromeOptions
# 防止用selenium 被識別
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
driver = Chrome(options=option)
driver.get("http://www.csdn.net")
wait_para = WebDriverWait(driver, 10)
login_button = wait_para.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="csdn_container_tool"]/div/ul/li[3]/a')))
login_button.click()
login_button_2 = wait_para.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="app"]/div/div/div[1]/div[2]/div[5]/ul/li[2]/a')))
login_button_2.click()
login_input_user = wait_para.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="all"]')))
login_input_user.send_keys('13713524786')
login_input_psw = wait_para.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="password-number"]')))
login_input_psw.send_keys('137135Rzx8170069')
login_button_3 = wait_para.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="app"]/div/div/div[1]/div[2]/div[5]/div/div[6]/div/button')))
login_button_3.click()
# 找到“嵌套”的iframe 也就是滑塊頁
try:
iframe = driver.find_element_by_xpath('//iframe')
except Exception as e:
print('get iframe failed: ', e)
iframe = 0
sleep(2)
driver.switch_to.frame(iframe)
try:
button = driver.find_element_by_xpath('//*[@id="nc_8_n1z"]')
except Exception as e:
print('get button failed: ', e)
button = 0
sleep(1)
action = ActionChains(driver)
action.click_and_hold(button).perform()
action.reset_actions()
for m in range(-20,20):
action.move_by_offset(m, 0).perform()
sleep(0.1)
注意 採用chrome78 以前的版本使用!
總結 ´◡`
另外,
- python專欄正在持續更新 想要深入學習python 並且繼續瞭解爬蟲的同學可以看我專欄:
python應用 - 想學習數據庫嘛? 不妨從MySQL入手
MySQL專欄 - 小孩子才做選擇 大人全都要!對後端感興趣嗎?收下它吧:)
手把手帶你學後端(服務端) - 謝謝大佬你的支持