selenium
-
什么是selenium
- 一款基於瀏覽器自動化的模塊
-
和爬蟲的關聯:
- 模擬登錄
- 便捷的獲取動態加載的數據
-
缺點:
- 爬取數據的效率底
- 環境部署繁瑣
-
模塊下載:
- pip install selenium
-
selenium如何獲取動態加載的數據
- 環境安裝:pip install selenium
- 基本的使用流程
- 結合着某一款瀏覽器驅動程序實例化一個瀏覽器對象
- 下載瀏覽器驅動程序:
- http://chromedriver.storage.googleapis.com/index.html
- 查看驅動和瀏覽器版本的映射關系:
- http://blog.csdn.net/huilan_same/article/details/51896672
- 編寫自動化操作代碼
- 結合着某一款瀏覽器驅動程序實例化一個瀏覽器對象
-
基本編碼流程
- 導包
- 創建一個瀏覽器對象,且在創建的過程中需要使用瀏覽器的驅動程序
- 使用get方法進行請求發送
- 指定其他的行為動作對應的代碼
- 關閉瀏覽器
-
演示程序
#模塊引入 from selenium import webdriver from time import sleep # 后面是你的瀏覽器驅動位置,記得前面加r'','r'是防止字符轉義的 driver = webdriver.Chrome(r'./chromedriver.exe') # 用get打開百度頁面 driver.get("http://www.baidu.com") # 查找頁面的“設置”選項,並進行點擊 driver.find_elements_by_link_text('設置')[0].click() sleep(2) # 打開設置后找到“搜索設置”選項,設置為每頁顯示50條 driver.find_elements_by_link_text('搜索設置')[0].click() sleep(2) # 選中每頁顯示50條 m = driver.find_element_by_id('nr') sleep(2) m.find_element_by_xpath('//*[@id="nr"]/option[3]').click() m.find_element_by_xpath('.//option[3]').click() sleep(2) # 點擊保存設置 driver.find_elements_by_class_name("prefpanelgo")[0].click() sleep(2) # 處理彈出的警告頁面 確定accept() 和 取消dismiss() driver.switch_to_alert().accept() sleep(2) # 找到百度的輸入框,並輸入 美女 driver.find_element_by_id('kw').send_keys('美女') sleep(2) # 點擊搜索按鈕 driver.find_element_by_id('su').click() sleep(2) # 在打開的頁面中找到“Selenium - 開源中國社區”,並打開這個頁面 driver.find_elements_by_link_text('美女_百度圖片')[0].click() sleep(3) # 關閉瀏覽器 driver.quit()selenium詳細用法
-
基礎案例
from selenium import webdriver from bs4 import BeautifulSoup #實例化一個瀏覽器對象 bro = webdriver.Chrome(executable_path='D:\爬蟲\谷歌訪問助手/chromedriver.exe') #發起一個get請求 bro.get(url='http://125.35.6.84:81/xk/') #獲取當前瀏覽器頁面的源碼數據 page_text = bro.page_source #使用bs4進行解析 soup = BeautifulSoup(page_text,'lxml') dl_list = soup.select('#gzlist>li>dl') for dl in dl_list: name = dl.string print(name)
-
selenium詳細用法
- 行為動作:
- 標簽定位:find系列的函數
- find_element_by_id()
- find_element_by_xpath()
- 節點交互
- 點擊:click()
- send_keys('xxx')
- 執行js:
- bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
- 動作鏈
- 導包:from selenium.webdriver import ActionChains
- 創建一個動作鏈對象:action = ActionChains(bro)
- 調用動作鏈對象中封裝的屬性和方法:
- action.click_and_hold(ele)
- move_by_offset(x,y)
- perform():立即執行動作鏈
- release()
- page_source:返回當前瀏覽器顯示頁面的全部頁面源碼數據
- 標簽定位:find系列的函數
- 瀏覽器無頭設置
- 規避檢測
- 截圖:save_screenshot('./1.png')
#通過selenium實現瀏覽器自動化訪問淘寶,並搜索關鍵字'華為' from time import sleep from selenium import webdriver #實例化一個瀏覽器對象 bro = webdriver.Chrome(executable_path='D:\爬蟲\谷歌訪問助手/chromedriver.exe') #獲取淘寶url bro.get('https://www.taobao.com/') #find系列的函數是用作於定位標簽 search_input = bro.find_element_by_id('q') #在淘寶首頁搜索框中錄入一個商品名稱 search_input.send_keys('華為') #阻塞兩秒,防止瀏覽器加載阻塞導致未獲取標簽 sleep(2) #執行JS代碼 #Js代碼,讓瀏覽器滾輪向下拖動一個屏的高度 bro.execute_script('window.scrollTo(0,document.body.scrollHeight)') sleep(2) bro.execute_script('window.scrollTo(0,document.body.scrollHeight)') sleep(2) btn = bro.find_element_by_xpath('//*[@id="J_TSearchForm"]/div[1]/button') #綁定事件 btn.click() sleep(2) #退出瀏覽器 bro.quit()
-
模擬登陸訪問QQ空間
from selenium import webdriver from lxml import etree from time import sleep #實例化一個瀏覽器對象 bro = webdriver.Chrome(executable_path='D:\爬蟲\谷歌訪問助手/chromedriver.exe') #獲取空間url bro.get('https://qzone.qq.com/') #switch_to操作切換frame,此時才能進行登陸頁面的操作 bro.switch_to.frame('login_frame') #點擊使用賬號密碼登陸,需要綁定click事件 bro.find_element_by_id('switcher_plogin').click() bro.find_element_by_id('u').send_keys('QQ賬號') bro.find_element_by_id('p').send_keys('QQ密碼') #點擊登陸,綁定click事件 bro.find_element_by_id('login_button').click() sleep(2) #獲取登陸頁面的所有的文本數據 page_text = bro.page_source # 進行數據解析 tree = etree.HTML(page_text) #獲取內容 data = tree.xpath('//*[@id="feed_3484622709_311_0_1560755089_0_1"]/div[1]//text()') print(data) sleep(3) bro.quit()
- 行為動作:
-
相關的網站會對爬蟲的請求實現監測,檢測請求是否為selenium進行的發送
-
如何讓selenium規避監測?
- 訪問美團網址(規避selenium監視)示例
from time import sleep
from selenium.webdriver import ChromeOptions
from selenium import webdriver
#實例化一個ChromeOptions對象
option = ChromeOptions()
#設置chromedriver啟動參數,規避對selenium的檢測機制
option.add_experimental_option('excludeSwitches', ['enable-automation'])
#設定url
url = 'https://bj.meituan.com/'
#實例化一個瀏覽器對象
bro = webdriver.Chrome(executable_path='D:\爬蟲\谷歌訪問助手/chromedriver.exe')
# 由於美團做了一定的設置,需要進行兩次get請求才可以訪問
bro.get(url)
sleep(2)
bro.get(url)
#屏幕截圖
bro.save_screenshot('1.png')
#打印當前瀏覽器頁面的源碼數據
print(bro.page_source)
-
如何設置瀏覽器無可視化界
from selenium.webdriver.chrome.options import Options from selenium import webdriver from time import sleep # 創建一個參數對象,用來控制chrome以無界面模式打開 chrome_options = Options() #設置谷歌瀏覽器的頁面無可視化 chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') #設定url url = 'https://bj.meituan.com/' #實例化一個瀏覽器對象,並把設置的無可視化傳入瀏覽器對象 bro = webdriver.Chrome(executable_path='D:\爬蟲\谷歌訪問助手/chromedriver.exe',chrome_options=chrome_options) bro.get(url) sleep(2) bro.get(url) bro.save_screenshot('2.png') print(bro.page_source)
-
phantomJs:
-
就是一款無可視化界面的瀏覽器,了解即可
-
由於已經停止更新維護,現在已經被棄用
-
多使用谷歌無頭瀏覽器
-
-
12306模擬登陸
from chaojiying_Python.chaojiying import Chaojiying_Client from selenium import webdriver from selenium.webdriver import ActionChains from PIL import Image from time import sleep #調用超級鷹獲取驗證碼 def get_codeImg_text(imgPath, imgType): chaojiying = Chaojiying_Client('loukunpeng813', 'nidayedeqQ123', ' 899991') #用戶中心>>軟件ID 生成一個替換 96001 im = open(imgPath, 'rb').read() #本地圖片文件路徑 來替換 a.jpg 有時WIN系統須要// # print(chaojiying.PostPic(im, 1902)) return chaojiying.PostPic(im, imgType)['pic_str'] #實例化一個瀏覽器對象,並把設置的無可視化傳入瀏覽器對象 bro = webdriver.Chrome(executable_path='D:\爬蟲\谷歌訪問助手/chromedriver.exe') #獲取12306的網站 bro.get('https://kyfw.12306.cn/otn/login/init') sleep(2) #賬號密碼進行模擬登陸 bro.find_element_by_id('username').send_keys('12306賬號') bro.find_element_by_id('password').send_keys('12306密碼') #想要獲取驗證碼圖片左上角和右下角亮點坐標,通過這亮點坐標可以形成一個裁剪的矩形區域 code_img_ele = bro.find_element_by_xpath('//*[@id="loginForm"]/div/ul[2]/li[4]/div/div/div[3]/img') location = code_img_ele.location # 驗證碼圖片左上角坐標 size = code_img_ele.size #驗證碼圖片的長寬 #指定矩形區域 rangle = (int(location['x']),int(location['y']),int(location['x']+size['width']),int(location['y']+size['height'])) #保存驗證碼 bro.save_screenshot('aa.png') i = Image.open('./aa.png') code_img_name = 'code.png' frame = i.crop(rangle) frame.save(code_img_name) #進行驗證碼的識別 result = get_codeImg_text(code_img_name,9004) print(result) # x1,y1|x2,y2|x3,y3 x,y #[[x1,y1],[x2,y2],[x3,y3]] [[x,y]] all_list = [] if '|' in result: list_1 = result.split('|') count_1 = len(list_1) for i in range(count_1): xy_list = [] x = int(list_1[i].split(',')[0]) y = int(list_1[i].split(',')[1]) xy_list.append(x) xy_list.append(y) all_list.append(xy_list) else: x = int(result.split(',')[0]) y = int(result.split(',')[1]) xy_list = [] xy_list.append(x) xy_list.append(y) all_list.append(xy_list) for l in all_list: #x,y就是需要點擊的某一個點的坐標 x = l[0] y = l[1] #move_to_element_with_offset就是將x,y的參照系轉移到指定的標簽中 #每一個動作連的操作都必須基於一個單獨的動作連 ActionChains(bro).move_to_element_with_offset(code_img_ele,x,y).click().perform() sleep(2) bro.find_element_by_id('loginSub').click() sleep(10) bro.quit()