動態渲染頁面爬取(Python 網絡爬蟲) ---Selenium的使用

Selenium 的使用php

Selenium 是一個自動化測試工具,利用它能夠驅動瀏覽器執行特定的動做,如點擊、下拉等操做,同時還能夠獲取瀏覽器當前呈現的頁面的源代碼,作到可見便可爬。對於一些JavaScript 動態渲染的頁面來講,此種抓取方式很是有效。css

好處:不用再分析網站複雜的通訊流程了html

壞處:效率低python

通常用在登陸環節。jquery

 

一、準備工做web

安裝Chrome瀏覽器正則表達式

配置ChromeDriver api

另外安裝Python的Selenium庫瀏覽器

 

二、基本使用cookie

Selenium一些功能,示例以下:

from selenium import webdriver        #用來驅動瀏覽器驅動
from selenium.webdriver import ActionChains    #滑動驗證碼的時候用。拖拽滑動驗證碼進行移動
from selenium.webdriver.common.by import By    #指定查找的方式 提交請求的過程中,定位到頁面中某一個標籤。好比輸入,就要找到輸入的標籤,往輸入標籤丟一些值給它,
from selenium.webdriver.common.keys import Keys   #鍵盤操做,好比回車操做
from selenium.webdriver.support import expected_conditions as EC  #跟WebDriverWait連在一塊兒用
from selenium.webdriver.support.wait import WebDriverWait      #跟EC連在一塊兒用 等頁面加載

 

程序運行關掉了,瀏覽器也要關掉,否則後臺會運行一堆瀏覽器。

也有可能用驅動發起請求的時候遇到錯誤了,出錯可能在某一行拋異常了,就執行不到關掉瀏覽器的那行代碼。因此try把爬取的邏輯放到裏面去。示例以下:

from selenium import webdriver        #用來驅動瀏覽器驅動

import time brower = webdriver.Chrome() try: brower.get('https://baidu.com') time.sleep(6) finally: brower.close()

 

基本使用演示:

from selenium import webdriver        #用來驅動瀏覽器驅動
from selenium.webdriver import ActionChains    #滑動驗證碼的時候用。拖拽滑動驗證碼進行移動
from selenium.webdriver.common.by import By    #指定查找的方式 提交請求的過程中,定位到頁面中某一個標籤。好比輸入,就要找到輸入的標籤,往輸入標籤丟一些值給它,
from selenium.webdriver.common.keys import Keys   #鍵盤操做,好比回車操做
from selenium.webdriver.support import expected_conditions as EC  #跟WebDriverWait連在一塊兒用
from selenium.webdriver.support.wait import WebDriverWait      #跟EC連在一塊兒用 等頁面加載


import time browser = webdriver.Chrome() try: wait = WebDriverWait(browser,4)   #     #發請求
    browser.get('https://baidu.com') #獲取輸入框
    input_tag = wait.until(EC.presence_of_element_located((By.ID,'kw'))) #輸入內容
    input_tag.send_keys('種花') #鍵盤操做回車
 input_tag.send_keys(Keys.ENTER) time.sleep(6) finally: browser.close()

運行代碼後發現,會自動彈出一個Chrome瀏覽器。瀏覽器首先會跳到百度,而後在搜索框中輸入種花,接着跳轉到搜索結果頁,如圖

 

在控制檯分別會輸出當前的URL、當前的Cookies和網頁源代碼,而後發現跟瀏覽器中的如出一轍。

print(browser.current_url) print(browser.get_cookies()) print(browser.page_source)

因此說,若是用Selenium 來驅動瀏覽器加載網頁的話,就能夠直接拿到JavaScript渲染的效果了,不用擔憂使用的什麼加密系統。

 

下面來詳細介紹Selenium 的用法:

三、聲明瀏覽器對象

Selenium 支持很是多的瀏覽器。如Chrome,Firefox,Edge等,還有Android,BlackBerry等手機端的瀏覽器。另外還支持無界面瀏覽器PhantomJS。

此外,咱們能夠用以下方式初始化:

from selenium import webdriver
browser=webdriver.Chrome() browser=webdriver.Firefox() browser=webdriver.PhantomJS() browser=webdriver.Safari() browser=webdriver.Edge() 

這樣就完成了瀏覽器對象的初始化並將其賦值爲browser對象。接下來,咱們要作的就是調用browser對象,讓其執行各個動做以模擬瀏覽器操做。

 

四、訪問頁面

咱們能夠用get()方法來請求網頁,參數傳入連接URL 便可。好比,在這裏用get()方法訪問京東,而後打印出源代碼,代碼以下:

from selenium import webdriver browser = webdriver.Chrome() browser.get('https://www.jd.com') print(browser.page_source) browser.close()

運行後發現,彈出了Chorme瀏覽器而且自動訪問了京東,而後控制檯輸出了京東頁面的源代碼,隨後瀏覽器關閉。

經過這幾行簡單的代碼,咱們能夠實現瀏覽器的驅動並獲取網頁源碼,很是便捷。

 

五、查找節點

Selenium 能夠驅動瀏覽器完成各類操做,好比填充表單、模擬點擊等。好比,咱們想要完成向某個輸入框輸入文字的操做,總須要知道這個輸入框在那裏吧?而Selenium 提供了一系列查找節點的方法,咱們能夠用這些方法來獲取想要的節點,以便下一步執行一些動做或者提取信息。

5.一、單個節點

好比,想要從淘寶頁面中提取搜索框這個節點,首先要觀察它的源代碼,以下圖所示:

能夠發現,它的id是q,name也是q。此外,還有許多其餘屬性,此時咱們就能夠用多種方式獲取它了。好比,find_elemene_by_name()是根據 name 值獲取,find_element_by_id()是根據id獲取。另外,還有根據XPath、CSS選擇器等獲取的方式。

咱們用代碼實現一下:

from selenium import webdriver import time browser = webdriver.Chrome() try: browser.get('https://www.taobao.com') input_tag_first = browser.find_element_by_id('q') input_tag_second = browser.find_element_by_css_selector('#q') input_tag_third = browser.find_element_by_xpath('//*[@id="q"]') time.sleep(6) print(input_tag_first, input_tag_second, input_tag_third) finally: browser.close()

這裏咱們使用三種方式獲取輸入框,分別是根據ID、CSS選擇器和XPath獲取,它們返回結果徹底一致。運行結構以下:

<selenium.webdriver.remote.webelement.WebElement (session="2972957e8503390420728c4a4168e46b", element="0.45122930131287853-1")> 
<selenium.webdriver.remote.webelement.WebElement (session="2972957e8503390420728c4a4168e46b", element="0.45122930131287853-1")> 
<selenium.webdriver.remote.webelement.WebElement (session="2972957e8503390420728c4a4168e46b", element="0.45122930131287853-1")>

能夠看到,這三個節點都是WebElement類型,是徹底一致的。

這裏列出全部獲取單個節點的方法:

 
 
find_element意思是尋找元素,
find_element_by_id 經過id找 find_element_by_name 按照name屬性找 find_element_by_xpath find_element_by_link_text 經過連接的文本內容找(徹底匹配)
find_element_by_pqrtial_link_text 經過連接的文本內容查找(部分匹配)
find_element_by_tag_name 經過標籤名找
find_element_by_class_name 經過類名找
find_element_by_css_selector 經過css選擇器.id#class

另外,Selenium還提供了通用方法find_element(),它須要傳入兩個參數:查找方式By和值。實際上,它就是find_element_by_id()這種方法的通用函數版本,好比find_element_by_id(id)就等價於find_element(By.ID,id),兩者獲得的結果徹底一致。咱們用代碼實現如下:

from selenium import webdriver from selenium.webdriver.common.by import By browser = webdriver.Chrome() try: browser.get('https://www.taobao.com') input_first = browser.find_element(By.ID,'q') input_second = browser.find_element_by_id('q') print(input_first) print(input_second) finally: browser.close()

 

<selenium.webdriver.remote.webelement.WebElement (session="e7d7f0eb547ed6c0d5f38a8101ce1d50", element="0.3574977265796484-1")>
<selenium.webdriver.remote.webelement.WebElement (session="e7d7f0eb547ed6c0d5f38a8101ce1d50", element="0.3574977265796484-1")>

實際上,這兩種查找方式的功能和上面列舉的查找函數徹底一致,不過參數更加靈活。

 

5.二、多個節點

若是查找的目標在網頁中只有一個,那麼徹底能夠用find_element()方法。但若是有多個節點,再用find_element()方法查找,就只能獲得第一個節點了。若是要查找全部知足條件的節點,須要用find_elements()這樣的方法。注意,在這個方法的名稱中,element多了個s,注意區分。

好比,要查找淘寶左側導航條的全部條目,以下圖所示:

 

就能夠這樣來實現:

from selenium import webdriver browser = webdriver.Chrome() # 多個節點
try: browser.get('https://www.taobao.com') list = browser.find_elements_by_css_selector('.service-bd li') print(list) finally: browser.close()

運行結果以下:

 
 

[

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-1")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-2")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-3")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-4")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-5")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-6")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-7")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-8")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-9")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-10")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-11")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-12")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-13")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-14")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-15")>,

<selenium.webdriver.remote.webelement.WebElement (session="d4ab52370cc5c90b5da37185a382c3bb", element="0.2937235535196494-16")>

]

 

能夠看到,獲得的內容變成了列表類型,列表中的每一個節點都是WebElement類型。

也就是說,若是咱們用find_element()方法,只能獲取匹配的第一個節點,結果是WebElement類型。若是用find_elements()方法,則結果是列表類型,列表中的每一個節點是WebElement類型。

這裏列出全部獲取多個節點的方法:

find_elements_by_id find_elements_by_name find_elements_by_xpath find_elements_by_link_text find_elements_by_pqrtial_link_text find_elements_by_tag_name find_elements_by_class_name find_elements_by_css_selector

 

固然,咱們也能夠直接用find_elements()方法來選擇,這時能夠這樣寫:

list = browser.find_elements(By.CSS_SELECTOR,'.service-bd li')

 

六、節點交互

Selenium 能夠驅動瀏覽器來執行一些操做,也就是說可讓瀏覽器模擬執行一些動做。比較常見的用法有:輸入文字時用send_keys()方法,清空文字時用clear()方法,點擊按鈕時使用click()方法。示例以下:

from selenium import webdriver import time browser = webdriver.Chrome() # 節點交互
 browser.get('https://www.taobao.com') input_tag = browser.find_element_by_id('q') input_tag.send_keys('手機殼') time.sleep(1) input_tag.clear() input_tag.send_keys('多肉') button = browser.find_element_by_class_name('btn-search') button.click()

這裏首先驅動瀏覽器打開淘寶,而後用find_element_by_id()方法獲取輸入框,而後用senf_keys()方法輸入手機殼文字,等待一秒後用clear()方法清空輸入框,再次調用senf_keys()方法輸入多肉文字,以後再用find_element_by_class_name()方法獲取搜索按鈕,最後調用click()方法完成搜索動做。

經過上面的方法,咱們就完成了一些常見節點的動做操做,更多的操做能夠參見官方文檔的交互動做介紹:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement

 

 

 

七、動做鏈

 在上面的實例中,一些交互動做都是針對某個節點執行的。好比,對於輸入框,咱們就調用它的輸入文字和清空文字的方法;對於按鈕,就調用它的點擊方法。其實,還有另一些操做,它們沒有特定的執行對象,好比鼠標拖拽。鍵盤按鍵等,這些動做用另外一種方式來執行,那就是動做鏈。

好比,如今實現一個節點的拖拽動做,將某個節點從一處拖拽到另一處,能夠這樣實現:

from selenium import webdriver from selenium.webdriver import ActionChains import time browser = webdriver.Chrome() try: 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()

    # 方式二
 distance = target.location['x']-source.location['x'] ActionChains(browser).click_and_hold(source).perform() s = 0 while s < distance: ActionChains(browser).move_by_offset(xoffset=2,yoffset=0).perform() # time.sleep(0.2)
        s+=2 ActionChains(browser).release().perform() time.sleep(4) finally: browser.close()

 

首先,打開網頁中的一個拖拽實例,而後依次選中要拖拽的節點和拖拽的目標節點,接着聲明ActionChains 對象並將其賦值爲actions 變量,而後經過調用actions變量的drag_and_drop()方法,再調用perform()方法來執行操做,此時就完成了拖拽操做。

更多的動做連操做能夠參考官方文檔:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.action_chains

 

 

八、執行JavaScript

 執行某些操做,Selenium API並無提供。好比。下拉進度條,它能夠直接模擬運行JavaScript,此時使用execute_script()方法便可實現,代碼以下:

from selenium import webdriver browser = webdriver.Chrome() try: browser.get('https://www.zhihu.com/explore') browser.execute_script('window.scrollTo(0,document.body.scrollHeight)') browser.execute_script('alert("To Bittom")') finally: browser.close()

這裏利用了excute_script()方法將進度條下拉到最底部,而後彈出alert提示框。

因此說有了這個方法,基本上API沒有提供的所用功能均可以用JavaScript的方式來實現了。

 

九、獲取節點信息

 前面說過,經過page_source屬性能夠獲取網頁的源代碼,接着就可使用解析庫(如正則表達式、Beautiful Soup、pyquery等)來提取消息了。

 不過,既然Selenium 已經提供了了選擇節點的方法,返回的是WebElement類型,那麼它也有相關的方法和屬性來直接提取節點信息,好比屬性、文本等。這樣的話,咱們就能夠不用經過解析源代碼來提取消息了,很是方便。

接下來,就看看經過怎樣的方式獲取節點信息吧。

 

9.1 獲取屬性

咱們可使用get_attribute()方法來獲取節點的屬性,可是其前提是先選中這個節點,示例以下:

 

from selenium import webdriver import time browser = webdriver.Chrome() try: url = 'https://www.zhihu.com/explore' browser.get(url) zh_logo = browser.find_element_by_id('zh-top-link-logo') print(zh_logo) print(zh_logo.get_attribute('class')) time.sleep(4) finally: browser.close()

運行以後,程序便會驅動瀏覽器打開知乎頁面,而後獲取知乎的logo節點,最後打印出它的class。

控制檯的輸出結果爲:

<selenium.webdriver.remote.webelement.WebElement (session="a014d9de06bbb4bebeb1d6bf50cdfab9", element="0.6635784736572936-1")> zu-top-link-logo

經過get_attribute()方法,而後傳入想要獲取的屬性名,就能夠獲得它的值了。 

 

9.2 獲取文本值

每一個WebElement 節點都有 text 屬性,直接調用這個屬性就能夠獲得節點內部的文本信息,這至關於Beautiful Soup的get_text()方法、pyquery的text()方法,示例以下: 

 

from selenium import webdriver import time browser = webdriver.Chrome() # 獲取文本值
try: url = 'https://www.zhihu.com/explore' browser.get(url) input_tag = browser.find_element_by_class_name('zu-top-add-question') print(input_tag.text) time.sleep(4) finally: browser.close()

這裏依然是先打開知乎頁面,而後獲取‘提問’按鈕這個節點,再將其文本內容值打印出來。

控制檯顯示結果以下:

 

9.3 獲取id、位置、標籤名和大小

 另外,WebElement 節點還有一些其餘屬性,好比id屬性能夠獲取節點id,location 屬性能夠獲取該節點在頁面的相對位置,tag_name 屬性能夠獲取標籤名稱,size屬性能夠獲取節點的大小,也就是寬高,這些屬性有時候仍是頗有用的。示例以下:

from selenium import webdriver import time browser = webdriver.Chrome() try: url = 'https://www.zhihu.com/explore' browser.get(url) input_tag = browser.find_element_by_class_name('zu-top-add-question') print(input_tag.id) print(input_tag.location) print(input_tag.tag_name) print(input_tag.size) finally: browser.close()

這裏依然先打開知乎頁面,而後獲取 ‘提問’按鈕這個節點,而後調用其id、liocation、tag_name、size屬性來獲取對贏得屬性值。 

 

 

10、切換Frame

 

咱們知道網頁中有一種節點叫作iframe,也就是子Frame,至關於頁面的子頁面,它的結構和外部網頁的結構徹底一致。Selenium打開頁面後,它默認是在父集Frame裏面操做,而此時若是頁面中還有子Frame,它是不能獲取到 子Frame裏面節點的。這時就須要使用switch_to.frame()方法來切換Frame。示例以下:

 

import time from selenium import webdriver from selenium.common.exceptions import NoSuchElementException browser = webdriver.Chrome() try: url = 'http://www.runoob.com/try/try/.php?filename=jqueryui-api-droppable' browser.get(url) browser.switch_to.frame('iframeResult') try: logo = browser.find_element_by_class_name('logo') except NoSuchElementException: print('NO LOGO') browser.switch_to.parent_frame() logo = browser.find_element_by_class_name('logo') print(logo) print(logo.text) finally: browser.close()

 

這裏仍是之前面演示動做鏈操做的網頁爲實例,首先經過switch_to.frame()方法切換到子Frame裏面,而後嘗試獲取子Frame裏的logo節點(這是不能找到的),若是找不到的話,就會拋出NoSuchElementException異常,異常被捕捉以後,就會輸出NO LOGO,接下來,從新切換到父級Frame,而後再次從新獲取節點,發現此時能夠成功獲取了。

因此,當頁面包含子Frame時,想要獲取子Frame中的節點,須要調用switch_to.frame()方法切換到對應的,而後在進行操做。

 

 

十一、延時等待

在Selenium中,get()方法會在網頁框架加載結束後結束執行,此時若是獲取page_source,可能並非;瀏覽器徹底加載完成的頁面,若是某些頁面有額外的Ajax 請求,咱們在網頁代碼中也不必定能獲取成功。因此,這裏須要延時等待必定時間,確保節點已經加載出來。

這裏等待的方式有兩種:一種是隱式等待,一種是顯式等待。

 

11.一、隱式等待

當使用隱式等待執行測試的時候,若是Selenium沒有在DOM中找到節點,將繼續等待,超出設定時間後,則拋出找不到節點的異常。換句話說,當查找節點而節點並無當即出現的時候,隱式等待將等待一段時間再查找DOM,默認時間是0。示例以下:

from selenium import webdriver browser = webdriver.Chrome() browser.implicitly_wait(10) browser.get('https://www.zhihu.com/explore') button_tag = browser.find_element_by_class_name('zu-top-add-question') print(button_tag)

這裏咱們用implicitly_wait(10)方法實現了隱式等待。

 

11.二、顯式等待

隱式等待的效果並無那麼好,由於咱們只規定了一個固定時間,而頁面的加載時間會受到網絡條件的影響。

這裏還有一個更合適的顯式等待方法,它指定要查找的節點,而後制定一個最長等待時間。若是在規定時間內加載出來這個節點,就返回查找的節點;若是到了規定時間依然沒有加載出該節點,則拋出超時異常。示例以下:

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() try: browser.get('https://www.taobao.com/') wait = WebDriverWait(browser,10) input_tag = 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_tag,button) finally: browser.close()

 

這裏首先引入WebDriverWait這個對象,指定最長等待時間,而後調用它的until()方法,傳入要等待條件expected_conditions。好比,這裏傳入了presence_of_element_located這個條件,表明節點出現的意思,其參數是節點的定位元組,也就是ID爲q的節點搜索框。

這樣能夠作到的效果就是,在10秒內若是ID爲q的節點(即搜索框)成功加載出來。就返回該節點;若是超過10秒尚未加載出來,就拋出異常。

對於按鈕,能夠更改一下等待條件,好比改成element_to_be_clickable,也就是可點擊,因此查找按鈕時查找CSS選擇器爲的按鈕,若是10秒內它是可點擊的,也就是成功加載出來了,就返回這個按鈕節點;若是超過10秒尚未加載出來,就拋出異常。

運行代碼,在網速較佳的狀況下是能夠成功加載出來的。

控制檯的輸出以下:

<selenium.webdriver.remote.webelement.WebElement (session="7d8b894316bbc39ff3a124a2976202eb", element="0.004489568003788413-1")> 
<selenium.webdriver.remote.webelement.WebElement (session="7d8b894316bbc39ff3a124a2976202eb", element="0.004489568003788413-2")>

能夠看到,控制檯成功輸出了兩個節點,它們都是WebElement類型。

 

若是失敗的話會拋出異常。

 

十二、前進和後退

日常使用瀏覽器時都有前進和後退功能,Selenium也能夠完成這個操做,它使用back()方法後退,使用forward()方法前進。示例以下:

 

import time from selenium import webdriver browser = webdriver.Chrome() try: browser.get('https://www.baidu.com/') browser.get('https://www.taobao.com/') browser.get('https://www.jd.com/') browser.back() time.sleep(2) browser.forward() finally: browser.close()

 

這裏咱們連續訪問三個頁面,而後調用back()方法回到第二個頁面,接下來再調用forward()方法又能夠前進到第三個頁面內。

 

1三、Cookies

使用Selenium,還能夠方便地對Cookies進行操做,例如獲取、添加、刪除Cookies等。示例以下:

from selenium import webdriver browser = webdriver.Chrome() try: browser.get('https://www.zhihu.com/explore') print(browser.get_cookies()) browser.add_cookie({'name':'name','domain':'www.zhihu.com','value':'germey'}) print(browser.get_cookies()) print(browser.delete_all_cookies()) print(browser.get_cookies()) finally: browser.close()

首先,咱們訪問了知乎。加載完成後,瀏覽器實際上已經生成了Cookies了。接着咱們調用get_cookies()方法獲取全部的Cookies。而後咱們添加一個Cookies,這裏傳入一個字典,有name、domain和value等內容。接下來,再次獲取全部的Cookies。能夠發現,結果就多了這一項新加的Cookie。最後調用delete_all_cookies()方法刪除全部的Cookies。從新獲取,發現結果就爲空了。

控制檯輸出結果以下:

[{'domain': '.zhihu.com', 'expiry': 1567877193, 'httpOnly': False, 'name': '__utmz', 'path': '/', 'secure': False, 'value': '51854390.1552109194.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)'}, {'domain': '.zhihu.com', 'expiry': 1552110993, 'httpOnly': False, 'name': '__utmb', 'path': '/', 'secure': False, 'value': '51854390.0.10.1552109194'}, {'domain': '.zhihu.com', 'expiry': 1646717185.745797, 'httpOnly': False, 'name': 'q_c1', 'path': '/', 'secure': False, 'value': 'c1be5730838e4961a9c0ea0af241acf3|1552109185000|1552109185000'}, {'domain': '.zhihu.com', 'expiry': 1615181193, 'httpOnly': False, 'name': '_zap', 'path': '/', 'secure': False, 'value': '329f49a1-d78e-4e05-9bd6-54e78fcc8b1a'}, {'domain': '.zhihu.com', 'expiry': 1554701185.745947, 'httpOnly': False, 'name': 'l_cap_id', 'path': '/', 'secure': False, 'value': '"NzhlMjcyNjg0OTUyNDk2NmEwZjAzNzNmNDZjNGUwZjQ=|1552109185|4cd1bcfd1b23d2e8478b9a6ee1cc61386e586841"'}, {'domain': 'www.zhihu.com', 'expiry': 1552110085.745695, 'httpOnly': False, 'name': 'tgw_l7_route', 'path': '/', 'secure': False, 'value': '060f637cd101836814f6c53316f73463'}, {'domain': '.zhihu.com', 'expiry': 1554701185.745898, 'httpOnly': False, 'name': 'cap_id', 'path': '/', 'secure': False, 'value': '"NWUxZGQzZTEwMjU4NGIwMmJmMDliMzVlMTc2Zjg5Yjg=|1552109185|ba3e32ca8fcf86e0cc39c4822b3998afdd05c7e8"'}, {'domain': '.zhihu.com', 'expiry': 1615181193, 'httpOnly': False, 'name': '__utmv', 'path': '/', 'secure': False, 'value': '51854390.000--|3=entry_date=20190309=1'}, {'domain': '.zhihu.com', 'httpOnly': False, 'name': 'n_c', 'path': '/', 'secure': False, 'value': '1'}, {'domain': '.zhihu.com', 'expiry': 1615181193, 'httpOnly': False, 'name': '__utma', 'path': '/', 'secure': False, 'value': '51854390.1872266721.1552109194.1552109194.1552109194.1'}, {'domain': '.zhihu.com', 'httpOnly': False, 'name': '__utmc', 'path': '/', 'secure': False, 'value': '51854390'}, {'domain': '.zhihu.com', 'expiry': 1646717192.357061, 'httpOnly': False, 'name': 'd_c0', 'path': '/', 'secure': False, 'value': '"ADAiXVxOGA-PTnrcZaT_2bgcCujQ0Jzk-bY=|1552109192"'}, {'domain': '.zhihu.com', 'expiry': 1554701185.745854, 'httpOnly': False, 'name': 'r_cap_id', 'path': '/', 'secure': False, 'value': '"Y2E5NmY2MzdmOWU4NDI2ZGFhZTBhMTgxNDBkYWIxOGM=|1552109185|4f456af38fccd5e4920de3751616d1fcfb604ad8"'}, {'domain': 'www.zhihu.com', 'httpOnly': False, 'name': '_xsrf', 'path': '/', 'secure': False, 'value': 'ffa701e12b2e436beef359522f1283dc'}, {'domain': '.zhihu.com', 'httpOnly': False, 'name': 'l_n_c', 'path': '/', 'secure': False, 'value': '1'}] [{'domain': 'www.zhihu.com', 'expiry': 2182829193, 'httpOnly': False, 'name': 'name', 'path': '/', 'secure': True, 'value': 'germey'}, {'domain': '.zhihu.com', 'expiry': 1567877193, 'httpOnly': False, 'name': '__utmz', 'path': '/', 'secure': False, 'value': '51854390.1552109194.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)'}, {'domain': '.zhihu.com', 'expiry': 1552110993, 'httpOnly': False, 'name': '__utmb', 'path': '/', 'secure': False, 'value': '51854390.0.10.1552109194'}, {'domain': '.zhihu.com', 'expiry': 1646717185.745797, 'httpOnly': False, 'name': 'q_c1', 'path': '/', 'secure': False, 'value': 'c1be5730838e4961a9c0ea0af241acf3|1552109185000|1552109185000'}, {'domain': '.zhihu.com', 'expiry': 1615181193, 'httpOnly': False, 'name': '_zap', 'path': '/', 'secure': False, 'value': '329f49a1-d78e-4e05-9bd6-54e78fcc8b1a'}, {'domain': '.zhihu.com', 'expiry': 1554701185.745947, 'httpOnly': False, 'name': 'l_cap_id', 'path': '/', 'secure': False, 'value': '"NzhlMjcyNjg0OTUyNDk2NmEwZjAzNzNmNDZjNGUwZjQ=|1552109185|4cd1bcfd1b23d2e8478b9a6ee1cc61386e586841"'}, {'domain': 'www.zhihu.com', 'expiry': 1552110085.745695, 'httpOnly': False, 'name': 'tgw_l7_route', 'path': '/', 'secure': False, 'value': '060f637cd101836814f6c53316f73463'}, {'domain': '.zhihu.com', 'expiry': 1554701185.745898, 'httpOnly': False, 'name': 'cap_id', 'path': '/', 'secure': False, 'value': '"NWUxZGQzZTEwMjU4NGIwMmJmMDliMzVlMTc2Zjg5Yjg=|1552109185|ba3e32ca8fcf86e0cc39c4822b3998afdd05c7e8"'}, {'domain': '.zhihu.com', 'expiry': 1615181193, 'httpOnly': False, 'name': '__utmv', 'path': '/', 'secure': False, 'value': '51854390.000--|3=entry_date=20190309=1'}, {'domain': '.zhihu.com', 'httpOnly': False, 'name': 'n_c', 'path': '/', 'secure': False, 'value': '1'}, {'domain': '.zhihu.com', 'expiry': 1615181193, 'httpOnly': False, 'name': '__utma', 'path': '/', 'secure': False, 'value': '51854390.1872266721.1552109194.1552109194.1552109194.1'}, {'domain': '.zhihu.com', 'httpOnly': False, 'name': '__utmc', 'path': '/', 'secure': False, 'value': '51854390'}, {'domain': '.zhihu.com', 'expiry': 1646717192.357061, 'httpOnly': False, 'name': 'd_c0', 'path': '/', 'secure': False, 'value': '"ADAiXVxOGA-PTnrcZaT_2bgcCujQ0Jzk-bY=|1552109192"'}, {'domain': '.zhihu.com', 'expiry': 1554701185.745854, 'httpOnly': False, 'name': 'r_cap_id', 'path': '/', 'secure': False, 'value': '"Y2E5NmY2MzdmOWU4NDI2ZGFhZTBhMTgxNDBkYWIxOGM=|1552109185|4f456af38fccd5e4920de3751616d1fcfb604ad8"'}, {'domain': 'www.zhihu.com', 'httpOnly': False, 'name': '_xsrf', 'path': '/', 'secure': False, 'value': 'ffa701e12b2e436beef359522f1283dc'}, {'domain': '.zhihu.com', 'httpOnly': False, 'name': 'l_n_c', 'path': '/', 'secure': False, 'value': '1'}] None []

 

 

1四、選項卡管理

 

在訪問網頁的時候,會開啓一個個選項卡。在Selenium中,咱們也能夠對選項卡進行操做。示例以下:

 

 

1五、異常處理

 

 

 

爬京東信息

from selenium import webdriver from selenium.webdriver import ActionChains from selenium.webdriver.common.by import By #按照什麼方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys #鍵盤按鍵操做
from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait #等待頁面加載某些元素
import time def get_goods(driver): try: goods=driver.find_elements_by_class_name('gl-item') for good in goods: detail_url=good.find_element_by_tag_name('a').get_attribute('href') p_name=good.find_element_by_css_selector('.p-name em').text.replace('\n','') price=good.find_element_by_css_selector('.p-price i').text p_commit=good.find_element_by_css_selector('.p-commit a').text msg = ''' 商品 : %s 連接 : %s 價錢 :%s 評論 :%s ''' % (p_name,detail_url,price,p_commit) print(msg,end='\n\n') button=driver.find_element_by_partial_link_text('下一頁') button.click() time.sleep(1) get_goods(driver) except Exception: pass

def spider(url,keyword): driver = webdriver.Chrome() driver.get(url) driver.implicitly_wait(3)  # 使用隱式等待
    try: input_tag=driver.find_element_by_id('key') input_tag.send_keys(keyword) input_tag.send_keys(Keys.ENTER) get_goods(driver) finally: driver.close() if __name__ == '__main__': spider('https://www.jd.com/',keyword='iPhone8手機')
爬取京東商品信息

 

 

 

破解極驗滑動驗證(博客園)

流程:

一、拿到瀏覽器驅動,而後請求地址,而後隱式等待,找到輸入框輸入帳號密碼而後點擊登陸。

二、點擊按鈕彈出圖(沒有缺口的圖片)---截圖

三、點擊滑動按鈕,彈出有缺口的圖     -----截圖

四、對比兩張圖片,找到缺口,就是要移動的位移

五、按照人的行爲習慣,把總的位移切成一段段小的位移 ********()

六、按照位移移動

相關文章
相關標籤/搜索