1. 程式人生 > >python+selenium功能強大的爬蟲操作

python+selenium功能強大的爬蟲操作

1.宣告瀏覽器物件

selenium支援多個瀏覽器,也支援手機端的瀏覽器,除此之外還有Phantomjs,下面舉一個簡單的例子,建立一個谷歌瀏覽器物件,依次類推可以得到其他瀏覽器物件

from selenium import webdriver

chrome_driver = "C:\Users\zhongchengbin\Documents\chromedriver\chromedriver.exe"(注意要下載對應的chrome的版本,設定路徑)
browser = webdriver.Chrome(executable_path=chrome_driver)


2.請求頁面

# 使用get方法請求百度網頁
browser.get('https://www.baidu.com')
# page_source屬性用於獲取網頁的原始碼,然後就可以使用正則表示式,css,xpath,bs4來解析網頁
print(browser.page_source)
browser.close()
3.查詢單個節點和多個節點

尋找單個節點的多有方法,返回的結果是WebElement型別的
browser.find_element_by_id()
browser.find_element_by_name()
browser.find_element_by_xpath()
browser.find_element_by_tag_name()
browser.find_element_by_link_text()
browser.find_element_by_class_name()
browser.find_element_by_css_selector()
browser.find_element_by_partial_link_text()
如果是找多個節點,在element後面加s,結果是列表型別


當我們要定位到百度的搜尋框時,我們可以看到,檢查元素中,input這個節點裡有class,id 等等屬性,我們通過定位相關屬性,就能定位到想要的節點

from selenium import webdriver
chrome_driver = "C:\Users\zhongchengbin\Documents\chromedriver\chromedriver.exe"(注意要下載對應的chrome的版本,設定路徑)

browser = webdriver.Chrome(executable_path=chrome_driver)
browser.get('https://www.baidu.com')
input = browser.find_element_by_id('kw')
browser.close()
4模擬瀏覽器進行操作

在開啟瀏覽器之後,我們往往需要在一些搜尋框裡輸入文字,刪除文字,點選一些按鈕等等,這時我們需要用到一下幾種方法

send_keys():輸入文字
clear():清除文字
click():點選按鈕
舉個例子,我們開啟百度瀏覽器,然後輸入一些關鍵字,刪除,再次輸入一些關鍵字,然後點選回車然後搜尋

import time
from selenium import webdriver
chrome_driver = "C:\Users\zhongchengbin\Documents\chromedriver\chromedriver.exe"(注意要下載對應的chrome的版本,設定路徑)

browser = webdriver.Chrome(executable_path=chrome_driver)
browser.get('https://www.baidu.com')
input = browser.find_element_by_id('kw')
input.send_keys('許嵩')
time.sleep(3)
input.clear()
input.send_keys('python')
input.send_keys(Keys.ENTER)
# button = browser.find_element_by_class_name('btn self_btn')
# button.click()
browser.close()
5.模擬滑鼠移動,鍵盤按鍵等沒有特定的執行物件的操作

模擬瀏覽器的時候,我們可能會使用到一些拖動的操作,比如需要將某一個點拖到另外一個地方去,這種方法我們可以稱之為動作鏈。

首先開啟網頁http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable中的一個例項,選中要拖動的節點以及拖動到哪裡的節點,使用ActionChains物件使它變成一個變數,再呼叫drag_and_drop方法以及perform方法來執行該過程。

from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
browser.get('http:www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
browser.switch_to.frame('iframeResult')
yuanlai = browser.find_element_by_css_selector('#draggable')
mubiao = browser.find_element_by_css_selector('#droppable')
a = ActionChains(browser)
a.drag_and_drop(yuanlai,mubiao)
a.perform()
6.拖動滑動條

使用爬蟲爬取網頁時,經常會看到使用滑動條的頁面,然後會顯示載入中,沒多久就會加載出新的頁面出來。如果直接爬取,往往只能爬到一頁甚至是前幾頁的資訊。

在此可以直接模擬執行JavaScript,滑到網頁的最底下。使用的是execute_script(),並且可以設定一個網頁提示框

from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.toutiao.com/search/?keyword=街拍')
# execute_script()將進度條拉到最下面,然後彈出提示框
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
browser.execute_script('alert("已經到最下面了")')
7.獲取節點資訊

獲取節點資訊與兩種方法,第一種是使用page_source屬性,獲取到目標網頁的原始碼之後,使用正則表示式,css,xpath ,bs4等工具進行抓取資訊。第二種就是直接使用selenium的一些方法和屬性。

① 獲取屬性

首先選中要匹配解析的節點,然後呼叫get_attribute方法來獲取節點的屬性。

from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
input = browser.find_element_by_id('kw')
print(input)
print(input.get_attribute('class'))
② 獲取文字

依然是先代開網址,然後定位到目標節點,再使用text屬性來獲取文字

from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
input = browser.find_element_by_id('kw')
print(input)
print(input.text)
③ 獲取ID,位置,標籤名和大小

方法和前兩個類似,直接呼叫即可獲得相關的值

from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
input = browser.find_element_by_id('kw')
print(input)
# 獲取節點id
print(input.id)
# 獲取節點在頁面的相對位置
print(input.location)
# 獲取節點標籤名稱
print(input.tag_name)
# 獲取節點大小
print(input.size)
8.切換frame

網頁有一種很常見的節點叫做iframe,相當於是子frame,也就是頁面的子頁面。

結構和外部網頁的結構一致,當我們使用selenium開啟頁面,預設是在父頁面裡執行的,但是呢,這種網頁我們往往是獲取不到子頁面的節點,所以要使用switch_to.frame()來跳轉頁面,然後再進行相對應的操作

然後嘗試獲取父頁面的某個節點,如果獲取不到就報錯,接下來就換回父頁面去獲取該節點,就能成功了。

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
 
browser = webdriver.Chrome
browser.get('https://www.toutiao.com')
browser.switch_to.frame('tanxssp-tuwen-iframemm')#具體是什麼,要看節點frame的id是什麼
try:
    title = browser.find_element_by_id('tanx-a-mm_32479643_3494618_81668314')
except NoSuchElementException:
    print('沒有這個節點')
browser.switch_to.parent_frame()
title = browser.find_element_by_id('tanx-a-mm_32479643_3494618_81668314')
print(title)
print(title.text)
9.延時等待

有些時候,網頁有額外的Ajax請求,並沒有那麼快就能加載出來,所以我們要有耐心地等待一下。

等待分為兩種,隱式等待和顯式等待

隱式等待,查詢某個節點的時候,隱式等待就會等待固定的時間,如果到了時間你還沒有來,他就會發脾氣,然後向上級打小報告說你沒有出現。

from selenium import webdriver
browser = webdriver.Chrome
browser.implicitly_wait(10)
browser.get('https://www.baidu.com')
input = browser.find_element_by_id('kw')
print(input)
顯式等待就顯得比較有人情味一點,會做人。當她準備等你的時候,她會溫馨地提示你,她最多等你多久,如果你在規定的時間內到了,那好,就一起接著做其他事。如果你超過了時間沒來,那也沒辦法了,只能向上級報告這個問題了。

# 顯式等待
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
 
browser = webdriver.Chrome
browser = get('https://www.taobao.com')
# 引入WWebDriverWait物件,指定等待的最長時間
wait = WebDriverWait(browser,10)
# 呼叫unti方法,然後設定等待的條件,表示直到這個節點出現的意思。引數是節點的定位元組,也就是說ID為q的節點搜尋框
# 成功就返回,不成功就丟擲異常
input = wait.until(EC,presence_of_element_located((By.ID,'q')))
button = wait.until(EC,element_to_be_clickable((By.CSS_SELECTOR,'btn-search')))
print(input,button)
'''
所有的等待條件
title_is                                 標題是某內容
title_contains                           標題包含某內容
presence_of_element_located              節點加載出來,傳入定位元組
visibility_of_element_located            節點可見,傳入定位元組
visibility_of                            可見,傳入節點物件
presence_of_all_element_located          所有節點加載出來
text_to_be_present_in_element            某個節點文字包含某文字
text_to_be_present_in_element_value      某個節點值包含某文字
frame_to_be_available_and_switch_to_it   載入並且切換
invisibility_of_element_located          節點不可見
element_to_be_clickable                  節點可點選
staleness_of                             判斷一個節點是否在DOM,可判斷頁面是否已經重新整理
element_to_be_selected                   節點可選擇,傳節點物件
element_located_to_be_selected           節點可選擇,傳定位元組
element_selection_state_to_be            傳入節點物件以及狀態,相等返回true,否則返回false
element_located_selection_state_to_be    傳入定位元組以及狀態,相等返回true,否則返回false
alert_is_present                         是否出現警告  
'''
10.後退前進

使用瀏覽器都有前進後退的功能,在selenium中,back()表示後退,forward()表示前進

# 後退前進
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser .get('https://www.baidu.com')
browser.back()
time.sleep(3)
browser.forward()
browser.close()
11.獲取cookies

from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
print(browser.get_cookies())
browser.add_cookie({'name':'name','domain':'www.baidu.com','value':'germey'})
print(browser.get_cookies())
browser.delete_all_cookies()
print(browser.get_cookies())
12.選項卡管理

import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
# window.open()新開啟一個選項卡
browser.execute_script('window.open()')
# window_handles 用於獲取當前開啟的所有選項卡,返回的是選項卡的代號列表
print(browser.window_handles)
# switch_to_window用於切換選項卡
browser.switch_to_window(browser.window_handles[1])
browser.get('https://www.taobao.com')
time.sleep(3)
browser.switch_to_window(browser.window_handles[0])
browser.get(