成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Python 從零開(kāi)始爬蟲(chóng)(八)——?jiǎng)討B(tài)爬取解決方案 之 selenium

fobnn / 2095人閱讀

摘要:然而讓蟲(chóng)師們垂涎的并不是以上的種種,而是其通過(guò)驅(qū)動(dòng)瀏覽器獲得的解析的能力。所以說(shuō)這貨在動(dòng)態(tài)爬取方面簡(jiǎn)直是掛逼級(jí)別的存在,相較于手動(dòng)分析更簡(jiǎn)單易用,節(jié)省分析打碼時(shí)間。一旦設(shè)置了隱式等待時(shí)間,它的作用范圍就是對(duì)象實(shí)例的整個(gè)生命周期。

selenium——自動(dòng)化測(cè)試工具,專(zhuān)門(mén)為Web應(yīng)用程序編寫(xiě)的一個(gè)驗(yàn)收測(cè)試工具,測(cè)試其兼容性,功能什么的。然而讓蟲(chóng)師們垂涎的并不是以上的種種,而是其通過(guò)驅(qū)動(dòng)瀏覽器獲得的解析JavaScript的能力。所以說(shuō)這貨在動(dòng)態(tài)爬取方面簡(jiǎn)直是掛逼級(jí)別的存在,相較于手動(dòng)分析更簡(jiǎn)單易用,節(jié)省分析打碼時(shí)間。

雖然selenium因其“超能力”被不少人吹上天了,但是認(rèn)清利弊,根據(jù)需求來(lái)選擇爬蟲(chóng)工具,還是挺重要的,所以這里簡(jiǎn)單說(shuō)下以供參考:

selenium無(wú)腦解決動(dòng)態(tài)難題

selenium更耐網(wǎng)頁(yè)變動(dòng)

selenium極大提升開(kāi)發(fā)效率,但極大降低爬取效率(規(guī)模一大就明顯了)。

selenium更占用資源(cpu,內(nèi)存,網(wǎng)絡(luò))

理由:打開(kāi)一個(gè)/多個(gè)瀏覽器,瀏覽器里還有n個(gè)窗口.....
下面不多說(shuō),進(jìn)入正題

前置

本體直接pip安裝pip install selenium

驅(qū)動(dòng)按需選擇:

chrome (內(nèi)核版本要對(duì)應(yīng),詳看其中的notes.txt)

firefox (相信各位的英文實(shí)力)

IE (很少用吧)

下載好后把解壓得到的驅(qū)動(dòng)放到設(shè)置了環(huán)境變量的路徑下就行了,如果你的python設(shè)置了環(huán)境變量,應(yīng)該丟到python目錄下就行了。

簡(jiǎn)單嘗試

照例貼上文檔,2.53舊版中文,想學(xué)更多就給我啃
選好瀏覽器就創(chuàng)建實(shí)例,之后的操作都在這個(gè)實(shí)例之上,并介紹一些有用的option,本文以Chrome為例。

from selenium import webdriver

#其他瀏覽器把Chrome換名就行
#option = webdriver.ChromeOptions()
#option.set_headless() 設(shè)置無(wú)頭瀏覽器,就是隱藏界面后臺(tái)運(yùn)行

driver = webdriver.Chrome() #創(chuàng)建driver實(shí)例
#driver = webdriver.Chrome(chrome_options=option)  創(chuàng)建實(shí)例并載入option

url = "**********"
driver.get(url)
#driver.maximize_window() 最大化窗口
#driver.set_window_size(width,height) 設(shè)置窗口大小

print(driver.page_source) #打印網(wǎng)頁(yè)源碼
driver.quit() # 關(guān)閉瀏覽器

對(duì)付低級(jí)的動(dòng)態(tài)網(wǎng)頁(yè)(ajax較少)就是這么簡(jiǎn)單,基本不用考慮動(dòng)態(tài)問(wèn)題,徒手?jǐn)]動(dòng)態(tài)的人表示羨慕。然而更多時(shí)候并不像這樣簡(jiǎn)單,直接套用的話很容易導(dǎo)致源碼所見(jiàn)非所得,而且很多爬蟲(chóng)并沒(méi)有簡(jiǎn)單到拿個(gè)源碼就走的程度,它還要交互,模擬點(diǎn)擊滾動(dòng)等等。所以還請(qǐng)往下看,不要看到這就投入實(shí)戰(zhàn)啦

定位

selenium提供多種方法對(duì)元素進(jìn)行定位,返回WebElement對(duì)象,而上面提到的driver就相當(dāng)于最大的WebElement對(duì)象

#以下都是單次定位,返回第一個(gè)定位到的。如果想多次定位,給element加個(gè)s就行,返回的是符合元素的列表
element = driver.find_element_by_id() # 通過(guò)標(biāo)簽的id定位,接收id屬性值

driver.find_element_by_name() # 通過(guò)標(biāo)簽的name定位,接收name屬性值

driver.find_element_by_xpath() # 通過(guò)xpath定位,接收xpath表達(dá)式

driver.find_element_by_link_text() # 通過(guò)標(biāo)簽的完全文本定位,接收完整的文本

driver.find_element_by_partial_link_text() # 通過(guò)標(biāo)簽的部分文本定位,接收部分文本

driver.find_element_by_tag_name() # 通過(guò)標(biāo)簽名定位,接收標(biāo)簽名

driver.find_element_by_class_name() # 通過(guò)標(biāo)簽的class定位,接收class屬性值

driver.find_element_by_css_selector() # 通過(guò)css選擇器定位,接收其語(yǔ)法
#返回的WebElement對(duì)象可以繼續(xù)往下定位

xpath和css就不展開(kāi)講了,能實(shí)現(xiàn)精確定位,一定要學(xué)其中一個(gè),不知道的小伙伴們上網(wǎng)自學(xué)吧,不難


除了上面這些公有的方法,還有2個(gè)私有的方法來(lái)幫助頁(yè)面對(duì)象的定位。 這兩個(gè)方法就是 find_element 和 find_elements,需要導(dǎo)入By類(lèi)輔助,接收一個(gè)By類(lèi)屬性及其對(duì)應(yīng)語(yǔ)法/值

from selenium.webdriver.common.by import By
driver.find_element(By.XPATH,"http://a[text()="dark"]")
driver.find_elements(By.XPATH,"http://a[text()="dark"]")
"""By類(lèi)有以下屬性
ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag_name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"
"""
frame切換

很多人在用selenium會(huì)遇到所見(jiàn)非所得,或者定位頁(yè)面元素的時(shí)候會(huì)定位不到的問(wèn)題,這種情況很有可能是frame在搞鬼,必須切換到相應(yīng)frame中再進(jìn)行定位。如果遇到以上問(wèn)題,第一時(shí)間F12看下你所要的信息是否在frame標(biāo)簽里面。
frame標(biāo)簽有frameset、frame、iframe三種,frameset跟其他普通標(biāo)簽沒(méi)有區(qū)別,不會(huì)影響到正常的定位,而frame與iframe對(duì)selenium定位而言是一樣的。

selenium提供了4種方法定位iframe并切換進(jìn)去:

#對(duì)于
driver.switch_to_frame(0)  # 用frame的index來(lái)定位,第一個(gè)是0,以此類(lèi)推
driver.switch_to_frame("frame1")  # 用id來(lái)定位
driver.switch_to_frame("dark")  # 用name來(lái)定位
driver.switch_to_frame(driver.find_element_by_tag_name("iframe"))  # 用WebElement對(duì)象來(lái)定位

通常通過(guò)id和name就能實(shí)現(xiàn),無(wú)此屬性時(shí)可以通過(guò)WebElement對(duì)象,即用find_element系列方法所取得的對(duì)象來(lái)定位。如果你確定每個(gè)目標(biāo)frame都是固定第幾個(gè),那也可以用index定位

切到frame中之后,就不能繼續(xù)操作主文檔的元素了,這時(shí)如果想操作主文檔內(nèi)容,則需切回主文檔。

driver.switch_to_default_content()

嵌套frame的切換
如果frame里包著frame而你要的frame是后者,那么需要一層一層切換進(jìn)去,切換方法四選一

driver.switch_to_frame("frame1")
driver.switch_to_frame("frame2")

如果想回去上一個(gè)父frame,用driver.switch_to.parent_frame()

window 切換

有時(shí)候點(diǎn)開(kāi)一個(gè)鏈接就會(huì)彈出一個(gè)新窗口,如果要對(duì)其操作就要切換過(guò)去,方法和frame的切換差不多,但只接收window_handle(相當(dāng)于窗口的名字)來(lái)進(jìn)行切換。driver.switch_to_window("windowName")

切換前最好保存之前的handle和所有的handles以便于來(lái)回切換。

current_window = driver.current_window_handle  # 獲取當(dāng)前窗口handle name
all_windows = driver.window_handles  # 獲取所有窗口handle name

# 如果window不是當(dāng)前window,則切換到該window,即切換到新窗口
for window in all_windows:
    if window != current_window:
        driver.switch_to_window(window)
        #....
driver.switch_to_window(current_window)  # 返回之前的窗口
driver.close()  # 窗口的關(guān)閉用close()
頁(yè)面交互

常用的頁(yè)面交互有點(diǎn)擊,輸入文本等。交互的原則是先定位,后交互,比如你F12找到了某個(gè)文本框或某個(gè)可點(diǎn)擊項(xiàng)的標(biāo)簽,那就先定位到那,再用以下的交互方法

from selenium.webdriver.common.keys import Keys
# 首先定位到某個(gè)文本框或某個(gè)可點(diǎn)擊項(xiàng)(如超鏈接,按鈕),
element = driver.find_element_by_xpath("http://a[text()="dark"]")

element.send_keys("some text")  # 往文本框輸入文本
#element.send_keys("some text", Keys.ARROW_DOWN)  可以使用 Keys 類(lèi)來(lái)模擬輸入方向鍵
element.clear()  # 清空文本框

#element.click() 如果此元素可點(diǎn)擊,可用click()方法

要注意的一點(diǎn)是,不是定位到就必定能交互,有時(shí)候目標(biāo)會(huì)被網(wǎng)頁(yè)彈出來(lái)的東西覆蓋,導(dǎo)致無(wú)法交互,所以要確保頁(yè)面干凈無(wú)覆蓋

上下拉滾動(dòng)

selenium可以執(zhí)行js,下拉滾動(dòng)可以通過(guò)此實(shí)現(xiàn),因此就算不懂js也可以記一些有用的js代碼

#driver.execute_script("js_str")
driver.execute_script("window.scrollTo(0,10000)")  # 移動(dòng)到指定坐標(biāo)
driver.execute_script("window.scrollBy(0,10000)")  # 相對(duì)當(dāng)前坐標(biāo)移動(dòng)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")  # 相對(duì)當(dāng)前坐標(biāo)移動(dòng)
等待

現(xiàn)在不少web都都有使用ajax技術(shù),即異步加載,有時(shí)候你要的東西都還沒(méi)加載到你就去定位了,就會(huì)拋出異常。為了避免此等血淋淋的慘狀,必須要待其加載一段時(shí)間后再進(jìn)行后面的操作。這里付一張不等待就獲取page_source的后果

最粗暴的方法就是使用time.sleep(),這很笨,因?yàn)槟氵€要設(shè)置合適的時(shí)間,而不同網(wǎng)站加載的速度有異,容易造成時(shí)間的浪費(fèi)。所以最好還是使用selenium提供的兩種等待方法

顯式Wiats

顯式Wiats允許你設(shè)置一個(gè)加載時(shí)間的上限和一個(gè)條件,每隔0.5s就判斷一下所設(shè)條件,條件成立就繼續(xù)執(zhí)行下面的代碼,如果過(guò)了時(shí)間上限還是沒(méi)有成立,默認(rèn)拋出NoSuchElementException 異常。這種相對(duì)智能的等待方法能最大化地節(jié)省時(shí)間,應(yīng)該優(yōu)先選擇使用

selenium提供了多種expected_conditions(EC)來(lái)設(shè)置條件,但是要注意有定位時(shí)EC的方法接收的是定位信息的元組(locator_tuple)而不是兩個(gè)參數(shù),正確用法如 EC.presence_of_element_located((By.ID,"dark"))
這個(gè)條件檢測(cè)是否有id="dark"的元素

selenium提供的EC有以下方法,意思如其名,這里注釋一些易搞錯(cuò)的,選擇使用

title_is(str)
title_contains(str)
presence_of_element_located(locator_tuple)
visibility_of_element_located(locator_tuple) # 判斷某個(gè)元素是否可見(jiàn)
visibility_of(WebElement) # 同上,傳參不同
presence_of_all_elements_located(locator_tuple)
text_to_be_present_in_element(str) # 判斷某個(gè)元素中的text是否包含了指定字符串
text_to_be_present_in_element_value(str) # 判斷某個(gè)元素中的value屬性是否包含了預(yù)期的字符串
frame_to_be_available_and_switch_to_it
invisibility_of_element_located(locator_tuple)
element_to_be_clickable(locator_tuple)
staleness_of(WebElement) # 等待某個(gè)元素從的移除
element_to_be_selected(WebElement)
element_located_to_be_selected(locator_tuple)
element_selection_state_to_be(WebElement)
element_located_selection_state_to_be(locator_tuple)
alert_is_present() # 判斷頁(yè)面上是否存在alert

使用上通常搭配try語(yǔ)句

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait # 導(dǎo)入顯式等待
from selenium.webdriver.support import expected_conditions as EC # 導(dǎo)入EC
from selenium.common.exceptions import NoSuchElementException

# WebDriverWait(driver,time).until(EC) 顯式waits

try:
    element = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,"myDynamicElement")))
    
except NoSuchElementException:
    #.....
finally:
     driver.quit()
隱式等待

隱式等待是在嘗試定位某個(gè)元素的時(shí)候,如果沒(méi)能成功,就等待固定長(zhǎng)度的時(shí)間,默認(rèn)0秒。一旦設(shè)置了隱式等待時(shí)間,它的作用范圍就是Webdriver對(duì)象實(shí)例的整個(gè)生命周期。driver.implicitly_wait(10)

最后補(bǔ)充

這是用selenium幾分鐘弄出來(lái)的網(wǎng)易云音樂(lè)單曲評(píng)論爬蟲(chóng),而且還模擬了評(píng)論翻頁(yè),還截了圖。沒(méi)提取信息,提取的時(shí)候可以用BeautifulSoup或正則提取,

from selenium import webdriver
import time
from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

driver = webdriver.Chrome()
driver.maximize_window()
driver.get("http://music.163.com/#/song?id=31877470")
driver.switch_to_frame("contentFrame")
time.sleep(5)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
driver.save_screenshot("E:/python3/gg.png")  # 截圖
b = driver.find_element_by_xpath("http://a[starts-with(@class,"zbtn znxt")]")
b.click()
try:
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH,"http://a[@data-type="reply"]")))
    print(driver.page_source)
except NoSuchElementException:
    print("OMG")
finally:
        driver.quit()

短短二十行就能做到這種程度(而且不少還是import的),足以見(jiàn)得selenium強(qiáng)大。如果要手動(dòng)分析,你還要分析js加密算法,寫(xiě)上n倍的代碼。兩者相比起來(lái)selenium真的很吸引人,簡(jiǎn)直是懶人救星。大家權(quán)衡利弊按需選擇吧

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/42071.html

相關(guān)文章

  • Python 從零開(kāi)始爬蟲(chóng)(六)——動(dòng)態(tài)爬取解決方案 手動(dòng)分析

    摘要:之前提到動(dòng)態(tài)加載就兩個(gè)解決方案手動(dòng)分析和。背后有許多不為人知的交易進(jìn)行著,動(dòng)態(tài)爬取的任務(wù)就是攔截它們揭開(kāi)它們的真面目。在爬蟲(chóng)界有著霸王硬上弓的稱(chēng)號(hào),管它情不情愿,來(lái)了動(dòng)態(tài)加載也只有屈服的份了。 之前提到動(dòng)態(tài)加載就兩個(gè)解決方案——手動(dòng)分析和selenium。接下來(lái)的文章我們會(huì)來(lái)深入探討它們,本文將首先,重點(diǎn)介紹前者——手動(dòng)分析 手動(dòng)分析是一個(gè)比較有難度,比較麻煩的解決方案,但優(yōu)點(diǎn)也很明顯...

    rozbo 評(píng)論0 收藏0
  • 零基礎(chǔ)如何學(xué)爬蟲(chóng)技術(shù)

    摘要:楚江數(shù)據(jù)是專(zhuān)業(yè)的互聯(lián)網(wǎng)數(shù)據(jù)技術(shù)服務(wù),現(xiàn)整理出零基礎(chǔ)如何學(xué)爬蟲(chóng)技術(shù)以供學(xué)習(xí),。本文來(lái)源知乎作者路人甲鏈接楚江數(shù)據(jù)提供網(wǎng)站數(shù)據(jù)采集和爬蟲(chóng)軟件定制開(kāi)發(fā)服務(wù),服務(wù)范圍涵蓋社交網(wǎng)絡(luò)電子商務(wù)分類(lèi)信息學(xué)術(shù)研究等。 楚江數(shù)據(jù)是專(zhuān)業(yè)的互聯(lián)網(wǎng)數(shù)據(jù)技術(shù)服務(wù),現(xiàn)整理出零基礎(chǔ)如何學(xué)爬蟲(chóng)技術(shù)以供學(xué)習(xí),http://www.chujiangdata.com。 第一:Python爬蟲(chóng)學(xué)習(xí)系列教程(來(lái)源于某博主:htt...

    KunMinX 評(píng)論0 收藏0
  • 首次公開(kāi),整理12年積累的博客收藏夾,零距離展示《收藏夾吃灰》系列博客

    摘要:時(shí)間永遠(yuǎn)都過(guò)得那么快,一晃從年注冊(cè),到現(xiàn)在已經(jīng)過(guò)去了年那些被我藏在收藏夾吃灰的文章,已經(jīng)太多了,是時(shí)候把他們整理一下了。那是因?yàn)槭詹貖A太亂,橡皮擦給設(shè)置私密了,不收拾不好看呀。 ...

    Harriet666 評(píng)論0 收藏0
  • python爬蟲(chóng)學(xué)習(xí)教程,爬取網(wǎng)易云音樂(lè)!

    摘要:其次,使用后,還需要針對(duì)做特定處理??吹竭@就可以構(gòu)想一下爬蟲(chóng)的爬取邏輯了。 運(yùn)行環(huán)境 我的運(yùn)行環(huán)境如下: 系統(tǒng)版本 Windows10。 Python版本 Python3.5,推薦使用Anaconda 這個(gè)科學(xué)計(jì)算版本,主要是因?yàn)樗詭б粋€(gè)包管理工具,可以解決有些包安裝錯(cuò)誤的問(wèn)題。去Anaconda官網(wǎng),選擇Python3.5版本,然后下載安裝。 IDE 我使用的是PyCharm,是專(zhuān)...

    Olivia 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<