【教程】利用Selenium爬取數據


Selenium簡介

Selenium是一個web的自動化測試工具,最初是為網站自動化測試而開發的,Selenium可以直接運行在瀏覽器上,它支持所有主流的瀏覽器,可以接收指令,讓瀏覽器自動加載頁面,獲取需要的數據,甚至頁面截屏。【爬蟲效率比較低
安裝方法如下:

pip install selenium

當然,使用Selenium需要瀏覽器的驅動程序才能驅動瀏覽器。安裝驅動程序的方法也很簡單,下載驅動程序並安裝,然后配置環境變量即可。

使用Selenium爬蟲

1.與瀏覽器建立連接

# 1.加載網頁
from selenium import webdriver
driver = webdriver.PhantomJS(executable_path=r'"安裝目錄") # 注意:這里用到的是PhantomJS瀏覽器
driver.get("https://www.baidu.com") # 請求
driver.save_screenshot("baidu.png") # 截圖
# 退出
driver.quit() 

2.定位元素

  • find_element_by_id:根據id來查找某個元素
submitTag = driver.find_element_by_id('su')
submitTag1 = driver.find_element(By.ID,'su')
  • find_element_by_class_name:根據類名查找元素
submitTag = driver.find_element_by_class_name('su')
submitTag1 = driver.find_element(By.CLASS_NAME,'su')
  • find_element_by_name:根據name屬性的值來查找元素
submitTag = driver.find_element_by_name('email')
submitTag1 = driver.find_element(By.NAME,'email')
  • find_element_by_tag_name:根據標簽名來查找元素
submitTag = driver.find_element_by_tag_name('div')
submitTag1 = driver.find_element(By.TAG_NAME,'div')
  • find_element_by_xpath:根據xpath語法來獲取元素
submitTag = driver.find_element_by_xpath('//div')
submitTag1 = driver.find_element(By.XPATH,'//div')

要注意,find_element是獲取第一個滿足條件的元素。find_elements是獲取所有滿足條件的元素

3.操作瀏覽器

from selenium import webdriver
# 實例化瀏覽器
c = webdriver.Chrome()
# 發送請求
c.get('https://www.baidu.com')
  • 1.獲取本頁面URL
c.current_url
  • 2.獲取日志
c.log_types  #獲取當前日志類型
c.get_log('browser')#瀏覽器操作日志
c.get_log('driver') #設備日志
c.get_log('client') #客戶端日志
c.get_log('server') #服務端日志
  • 3.窗口操作
c.maximize_window()#最大化
c.fullscreen_window() #全屏
c.minimize_window() #最小化
c.get_window_position() #獲取窗口的坐標
c.get_window_rect()#獲取窗口的大小和坐標
c.get_window_size()#獲取窗口的大小
c.set_window_position(100,200)#設置窗口的坐標
c.set_window_rect(100,200,32,50)    #設置窗口的大小和坐標
c.set_window_size(400,600)#設置窗口的大小
c.current_window_handle   #返回當前窗口的句柄
c.window_handles         #返回當前會話中的所有窗口的句柄
  • 4.設置延時
c.set_script_timeout(5) #設置腳本延時五秒后執行
c.set_page_load_timeout(5)#設置頁面讀取時間延時五秒
  • 5.關閉
c.close() #關閉當前標簽頁
c.quit() #關閉瀏覽器並關閉驅動
  • 6.打印網頁源代碼
c.page_source
  • 7.屏幕截圖操作
c.save_screenshot('1.png')#截圖,只支持PNG格式
c.get_screenshot_as_png() #獲取當前窗口的截圖作為二進制數據
c.get_screenshot_as_base64() #獲取當前窗口的截圖作為base64編碼的字符串
  • 8.前進后退刷新
c.forward() #前進
c.back()  #后退
c.refresh()#刷新
  • 9.Cookies操作
c.get_cookie('BAIDUID') #獲取指定鍵的Cookies
c.get_cookies()         #獲取所有的Cookies
for y in c.get_cookies():
   x=y
   if x.get('expiry'):
       x.pop('expiry')     
   c.add_cookie(x) #添加Cookies  
c.delete_cookie('BAIDUID') #刪除指定鍵的Cookies內容
c.delete_all_cookies() #刪除所有cookies

4.操作表單元素

  • 1.使用clear方法可以清除輸入框中的內容
inputTag.clear()
  • 2.操作checkbox
rememberTag = driver.find_element_by_name("rememberMe")
rememberTag.click()
  • 3.操作按鈕
inputTag = driver.find_element_by_id('su')
inputTag.click()
  • 4.選擇select
    select元素不能直接點擊。因為點擊后還需要選中元素。這時候selenium就專門為select標簽提供了一個類selenium.webdriver.support.ui.Select。將獲取到的元素當成參數傳到這個類中,創建這個對象。

  • 5.切換iframe
    iFrame,相當於頁面的子頁面,它的結構和外部網頁的結構完全一致。Selenium打開頁面后,默認是在父級 Frame 里面操作,而此時如果頁面中還有子 Frame,Selenium是不能獲取到子 Frame 里面的節點的。這時就需要使用 switch_to.frame 方法來切換Frame。
    接下來通過豆瓣模擬登錄來切換iframe,示例如下:

from selenium import webdriver
import time


url = 'https:www.douban.com'
driver = webdriver.Chrome()

driver.get(self.url)

time.sleep(3)
# 定位iframe標簽
login_iframe = self.driver.find_element_by_xpath('//*[@id="anony-reg-new"]/div/div[1]/iframe')
# 切換iframe標簽
driver.switch_to.frame(login_iframe)

5.行為鏈

有時候在頁面中的操作可能要有很多步,那么這時候可以使用鼠標行為鏈類ActionChains來完成。比如現在要將鼠標移動到某個元素上並執行點擊事件

actions = ActionChains(driver)
actions.move_to_element(inputTag)
actions.send_keys_to_element(inputTag,'python')
actions.move_to_element(submitTag)
actions.context_click()
actions.click(submitTag)
actions.perform()
# 其他,參考http://selenium-python.readthedocs.io/api.html
click_and_hold(element):點擊但不松開鼠標。
context_click(element):右鍵點擊。
double_click(element):雙擊。

模擬豆瓣登錄

from selenium import webdriver
import time

class Douban():

    def __init__(self):
        self.url = 'https:www.douban.com'
        self.driver = webdriver.Chrome()

    def login(self):
        self.driver.get(self.url)
        time.sleep(3)
        # 定位iframe標簽
        login_iframe = self.driver.find_element_by_xpath('//*[@id="anony-reg-new"]/div/div[1]/iframe')
        # 切換iframe標簽
        self.driver.switch_to.frame(login_iframe)
        # 第一張截圖(登錄前)
        self.driver.save_screenshot('db1.png')
        # 定位密碼輸入框
        self.driver.find_element_by_class_name('account-tab-account').click()
        # 輸入手機號
        self.driver.find_element_by_id('username').send_keys('156xxxxxx26')
        # 輸入密碼
        self.driver.find_element_by_id('password').send_keys('.......')
        # 點擊登錄按鈕
        self.driver.find_element_by_class_name('btn-account').click()
        time.sleep(3)
        # 第二張截圖(登陸后)
        self.driver.save_screenshot('db2.png')

    def out(self):
        '''調用內建的稀構方法,在程序退出的時候自動調用
        類似的還可以在文件打開的時候調用close,數據庫鏈接的斷開
        '''
        self.driver.quit()

if __name__ == '__main__':
    db = Douban() # 實例化
    db.login() # 之后調用登陸方法

6.Selenium頁面等待

  • Cookie操作
# 獲取所有的cookie
cookies = driver.get_cookies()
# 根據cookie的name獲取cookie
value = driver.get_cookie(key)
# 刪除某個cookie
driver.delete_cookie('key')
  • 頁面等待
    現在的網頁越來越多采用了 Ajax 技術,這樣程序便不能確定何時某個元素完全加載出來了。如果實際頁面等待時間過長導致某個dom元素還沒出來,但是你的代碼直接使用了這個WebElement,那么就會拋出NullPointer的異常。為了解決這個問題。所以 Selenium 提供了兩種等待方式:一種是隱式等待、一種是顯式等待。
# 隱式等待:調用driver.implicitly_wait。那么在獲取不可用的元素之前,會先等待10秒中的時間
driver.implicitly_wait(10)
# 顯示等待:顯示等待是表明某個條件成立后才執行獲取元素的操作。也可以在等待的時候指定一個最大的時間,如果超過這個時間那么就拋出一個異常。顯示等待應該使用# selenium.webdriver.support.excepted_conditions期望的條件和selenium.webdriver.support.ui.WebDriverWait來配合完成
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

driver = webdriver.Chrome()
driver.get("https://www.baidu.com/")

try:
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "myDynamicElement"))
 )
finally:
    driver.quit()

7.打開多窗口和切換頁面

# 打開一個新的頁面
driver.execute_script("window.open('url')")
print(driver.current_url)
# 切換到這個新的頁面中
driver.switch_to_window(self.driver.window_handles[1])

8.案例

from selenium import webdriver
from tools import *
import time

# 實例化瀏覽器
driver = webdriver.Chrome()

# 發送請求
driver.get('http://www.netbian.com/fengjing/')
# 最大化窗口
driver.maximize_window()

for i in range(100):
    img_list = driver.find_elements_by_xpath('//*[@id="main"]/div[3]/ul/li')
    for img in img_list[:-1]:
        img.click()
        try:
            driver.switch_to.window(driver.window_handles[-1])
            driver.find_element_by_xpath('//*[@id="main"]/div[3]/div/p/a/img').click()
            driver.switch_to.window(driver.window_handles[-1])
            time.sleep(1)
            url = driver.find_element_by_xpath('//*[@id="endimg"]/tbody/tr/td/a/img').get_attribute('src')
            title = driver.find_element_by_xpath('//*[@id="endimg"]/tbody/tr/td/a/img').get_attribute('title')
            download_img('./圖片/風景/'+title+'.jpg', url)
            driver.close()
            driver.switch_to.window(driver.window_handles[-1])
            time.sleep(1)
            driver.close()
            driver.switch_to.window(driver.window_handles[-1])
            time.sleep(1)
        except:
            driver.switch_to.window(driver.window_handles[-1])
            driver.close()
            driver.switch_to.window(driver.window_handles[-1])
            time.sleep(1)
    img_list[-1].click()
    time.sleep(1)

爬蟲結果:::

學習文章來源:https://mp.weixin.qq.com/s/qzXHzcT5urGeFEKwga7dhA


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM