python爬蟲之動態渲染頁面抓取-(Selenium)的使用


  我們在爬蟲的過程中,有一些動態渲染的頁面,我們是請求不到數據的。因此,我們可以直接通過使用模擬瀏覽器運行的方式實現,那么就可以實現原本瀏覽器中可以看到的,抓取的數據就是什么樣,即所見即所"得"(爬);此時我們不用再去關心網頁中JS使用了什么算法或者結構實現了頁面渲染。

  Python提供了許多模擬瀏覽器運行的庫,如 Selenium、 Splash、 PyV8, Ghost等

Selenium 的使用

  Selenium是一個 自動化測試工具,利用它可以驅動瀏覽器執行特定的動作,如點擊、下拉等操作, 同時還可以獲取瀏覽器當前呈現的頁面的源代碼,做到可見即可爬。

1、基本使用

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

browser = webdriver.Chrome()
try:
    browser.get('https://www.baidu.com')
    # 找到輸入框,根據id獲取
    input = browser.find_element_by_id('kw')
    #輸入搜索關鍵字“python”
    input.send_keys('Python')
    #點擊搜索
    input.send_keys(Keys.ENTER)
    #等待十秒
    wait = WebDriverWait(browser, 10)
    # presence_of_element_located判斷某個元素是否被加到了 dom 樹里,並不代表該元素一定可見。
    # 里面要是一個元祖
    wait.until(EC.presence_of_element_located((By.ID, 'content_left')))
    #輸出當前url
    print('輸出當前url:\n',browser.current_url)
    #輸出頁面cookie
    print('輸出頁面cookie:\n',browser.get_cookies())
    #輸出頁面內容
    #print(browser.page_source)
except:
    print('Fail')
finally:
    #關閉瀏覽器
    browser.close()

輸出結果:

輸出當前url:
 https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=Python&fenlei=256&rsv_pq=cb2816e900015d95&rsv_t=b787r%2BVzA0qjW4QKdzHIo7fcG4iLmC6iSRyKMpiaMrmd7hA5tADIT4yrLIw&rqlang=cn&rsv_enter=1&rsv_dl=tb&rsv_sug3=6&rsv_sug2=0&rsv_btype=i&inputT=213&rsv_sug4=213
輸出頁面cookie:
 [{'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BDSVRTM', 'path': '/', 'secure': False, 'value': '174'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '32292_1441_32355_31253_32348_32045_32116_31321_32297_26350_22158'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'PSINO', 'path': '/', 'secure': False, 'value': '2'}, {'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_CK_SAM', 'path': '/', 'secure': False, 'value': '1'}, {'domain': '.baidu.com', 'expiry': 1627052281, 'httpOnly': False, 'name': 'BAIDUID', 'path': '/', 'secure': False, 'value': '6C9B8822C3C4362FD97A588E493398C8:FG=1'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'delPer', 'path': '/', 'secure': False, 'value': '0'}, {'domain': '.baidu.com', 'expiry': 3742999928, 'httpOnly': False, 'name': 'BIDUPSID', 'path': '/', 'secure': False, 'value': '6C9B8822C3C4362F3E16CA0A76797398'}, {'domain': '.baidu.com', 'expiry': 3742999928, 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': '1595516283'}, {'domain': 'www.baidu.com', 'expiry': 1595518875, 'httpOnly': False, 'name': 'H_PS_645EC', 'path': '/', 'secure': False, 'value': 'a511pVLQtJh0hvfLuFVtXamctKD8jDLY2Z%2F0BAk49CMoxm8HDM01bvGqCLk'}, {'domain': 'www.baidu.com', 'expiry': 1596380281, 'httpOnly': False, 'name': 'BD_UPN', 'path': '/', 'secure': False, 'value': '12314753'}, {'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_HOME', 'path': '/', 'secure': False, 'value': '1'}]

2、 聲明瀏覽器對象

from selenium import webdriver

browser = webdriver.Chrome()  # google
browser = webdriver.Firefox()  # 火狐
browser = webdriver.Edge() #edge
browser = webdriver.PhantomJS()  # 無界面
browser = webdriver.Safari()  # mac自帶瀏覽器

3、訪問頁面

from selenium import webdriver
browser = webdriver.Chrome()
# 通過get(url)
browser.get('https://www.taobao.com')
#打印淘寶首頁頁面內容
print(browser.page_source)
#關閉谷歌瀏覽器
browser.close()

結果:

………………(省略一萬字)
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="renderer" content="webkit">
  <title>淘寶網 - 淘!我喜歡</title>
………………(省略一萬字)

4、 查找節點

目的:找到輸入框

單個節點的情況

以淘寶為例:

代碼:

from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
#找搜索框--id方式
input_first = browser.find_element_by_id('q')
#找搜索框--css方式
input_second = browser.find_element_by_css_selector('#q')
#找搜索框--xpath方式
input_third = browser.find_element_by_xpath('//*[@id="q"]')
print(input_first)
print(input_second)
print(input_third)
browser.close()

結果:

<selenium.webdriver.remote.webelement.WebElement (session="21a8b4b733264fbcbd8b058a2b05bf9f", element="3de372cc-d9f3-49c7-b423-e586f6a225d1")>
<selenium.webdriver.remote.webelement.WebElement (session="21a8b4b733264fbcbd8b058a2b05bf9f", element="3de372cc-d9f3-49c7-b423-e586f6a225d1")>
<selenium.webdriver.remote.webelement.WebElement (session="21a8b4b733264fbcbd8b058a2b05bf9f", element="3de372cc-d9f3-49c7-b423-e586f6a225d1")>

多個節點的情況

find_element() 只能查找目標網頁中的一個,要查找多個要用find_elements()

代碼

from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
lis = browser.find_elements_by_css_selector('.service-bd li')
print(lis)
browser.close()

結果:

[<selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="68843b38-2f7a-4d6f-b600-a41709370931")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="ba76c6b5-8e5e-49e2-930c-31dd008746e4")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="39a9722b-d954-428a-b457-6f3b2e2ebc03")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="5ebb0c1e-a0e4-4b44-8d53-fc6fffddb54c")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="13abdd53-44ae-4664-a5ea-eab06fde3d8e")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="071103dd-db53-4c32-81ae-14fe2f260842")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="d2b29103-f42b-4417-bce2-23fac105f117")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="d43cb5a5-2543-4da0-8e5b-5044f17b53f4")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="577b5b36-e836-4d8d-94cd-e84f9ea06d96")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="10850d3c-f7dd-4a7f-9691-362464092fa9")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="358a0778-591b-427d-aa61-c2b910ba35d1")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="7db19a0b-f4dd-476e-9d93-54a1ffb44468")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="ce274c07-94f1-4b4e-8f9c-0fd4d993a7c3")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="358aad1b-8fa4-48f7-8424-3720e48925eb")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="b5d4a744-9b88-493e-8343-b57b74ca1030")>, <selenium.webdriver.remote.webelement.WebElement (session="bdc3c2c445ccff47c45a623f6de58563", element="d709c785-03b3-4cf2-9c98-af3eff5381a1")>]

5、節點交互

輸入文字:send_keys()

清空文字:clear()

點擊按鈕:click()

from selenium import webdriver
import time

browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
input = browser.find_element_by_id('q')
#輸入文字‘iPhone’
input.send_keys('iphone')
#睡1秒
time.sleep(1)
#清空
input.clear()
#輸入文字‘iPad’
input.send_keys('ipad')
#找到class='btn-search'的按鈕
button = browser.find_element_by_class_name('btn-search')
#點擊它
button.click()

結果:

淘寶要登錄,這里無法返回結果

6、動作鏈

執行鼠標拖曳 、 鍵盤按鍵等動作

from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
browser.switch_to.frame('iframeResult')
source = browser.find_element_by_css_selector('#draggable')
target = browser.find_element_by_css_selector('#droppable')
actions = ActionChains(browser)
actions.drag_and_drop(source, target)
actions.perform()

結果

 

 7、執行javascript

對於沒有提供的操作,如下拉進度條,可以使用excute_script()方法實現。

from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
# 下拉到底部后,談出alert提示框
browser.execute_script('alert("To Bottom")') 

 8、獲取節點信息

page_source 屬性可以獲取網頁的源代碼,然后通過Beautiful soup pyquery進行信息提取

也可以使用selenium自帶的獲取屬性、文本等

· 獲取屬性

get_attribute()方法來獲取節點的屬性

from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
url = 'https://www.zhihu.com/explore'
browser.get(url)
#輸出搜索框內容
logo = browser.find_element_by_id('Popover1-toggle')
print(logo)
#輸出class="Input"的值
print(logo.get_attribute('class'))

結果:

<selenium.webdriver.remote.webelement.WebElement (session="f6ae22acea8757f858eb2c7939c2ee8b", element="0060864e-d6ed-4690-a481-e093da6b0254")>
Input

· 獲取文本值

text()

·獲取 id、位置、 標簽名和大小

id 屬性可以獲取節點 id, location 屬性可以獲取該節點在頁面中的相對位置, tag_name 屬性可以獲取標簽名稱, 就是寬高

9、延時等待

get()方法會在網頁框架加載結束后結束執行,此時如果獲取page_source,可能並不是瀏覽器完全加載完全的頁面,如果有頁面有額外的Ajax請求,在網頁源代碼中並不一定能成功獲取,所以需要延時等待一下。

·隱式等待

from selenium import webdriver
browser = webdriver.Chrome()
# 隱式等待,默認等待0秒,找不到繼續等一會在找,容易受到頁面加載時間的影響
browser.implicitly_wait(10)
browser.get('https://www.zhihu.com/explore')
input = browser.find_element_by_class_name('Input')
print(input)

結果:

<selenium.webdriver.remote.webelement.WebElement (session="318f4d1c97b1ecec3d8043cdf957e054", element="888440c5-9c7b-42d6-9be2-3bab91a59d98")>

·顯式等待

指定一個最長等待時間

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/')
wait = WebDriverWait(browser, 10)
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)

結果:

<selenium.webdriver.remote.webelement.WebElement (session="ac8a2a732adbaf4571fbb92e17fe5889", element="9ef29720-d902-42b6-94d4-54868739ad94")> <selenium.webdriver.remote.webelement.WebElement (session="ac8a2a732adbaf4571fbb92e17fe5889", element="ea01d031-dc8e-4cb4-9703-fadb51ff33de")>

 

 10、前進和后退 

forword() 前進下一個頁面,back() 返回前一個頁面

11、Cookies 

get_cookies() 方法獲取所有的 Cookie 

add_cookies() 方法添加cookies

delete_all_cookies()方法刪除所有的 Cookies 


免責聲明!

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



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