日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python爬取js动态网页_Python 从零开始爬虫(八)——动态爬取解决方案 之 selenium

發布時間:2025/3/15 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python爬取js动态网页_Python 从零开始爬虫(八)——动态爬取解决方案 之 selenium 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

selenium——自動化測試工具,專門為Web應用程序編寫的一個驗收測試工具,測試其兼容性,功能什么的。然而讓蟲師們垂涎的并不是以上的種種,而是其通過驅動瀏覽器獲得的解析JavaScript的能力。所以說這貨在動態爬取方面簡直是掛逼級別的存在,相較于手動分析更簡單易用,節省分析打碼時間。

雖然selenium因其“超能力”被不少人吹上天了,但是認清利弊,根據需求來選擇爬蟲工具,還是挺重要的,所以這里簡單說下以供參考:

selenium無腦解決動態難題

selenium更耐網頁變動

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

selenium更占用資源(cpu,內存,網絡)

理由:打開一個/多個瀏覽器,瀏覽器里還有n個窗口.....

下面不多說,進入正題

前置

本體直接pip安裝pip install selenium

驅動按需選擇:

chrome (內核版本要對應,詳看其中的notes.txt)

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

IE (很少用吧)

下載好后把解壓得到的驅動放到設置了環境變量的路徑下就行了,如果你的python設置了環境變量,應該丟到python目錄下就行了。

簡單嘗試

照例貼上文檔,2.53舊版中文,想學更多就給我啃

選好瀏覽器就創建實例,之后的操作都在這個實例之上,并介紹一些有用的option,本文以Chrome為例。

from selenium import webdriver

#其他瀏覽器把Chrome換名就行

#option = webdriver.ChromeOptions()

#option.set_headless() 設置無頭瀏覽器,就是隱藏界面后臺運行

driver = webdriver.Chrome() #創建driver實例

#driver = webdriver.Chrome(chrome_options=option) 創建實例并載入option

url = '**********'

driver.get(url)

#driver.maximize_window() 最大化窗口

#driver.set_window_size(width,height) 設置窗口大小

print(driver.page_source) #打印網頁源碼

driver.quit() # 關閉瀏覽器

對付低級的動態網頁(ajax較少)就是這么簡單,基本不用考慮動態問題,徒手擼動態的人表示羨慕。然而更多時候并不像這樣簡單,直接套用的話很容易導致源碼所見非所得,而且很多爬蟲并沒有簡單到拿個源碼就走的程度,它還要交互,模擬點擊滾動等等。所以還請往下看,不要看到這就投入實戰啦

定位

selenium提供多種方法對元素進行定位,返回WebElement對象,而上面提到的driver就相當于最大的WebElement對象

#以下都是單次定位,返回第一個定位到的。如果想多次定位,給element加個s就行,返回的是符合元素的列表

element = driver.find_element_by_id() # 通過標簽的id定位,接收id屬性值

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

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

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

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

driver.find_element_by_tag_name() # 通過標簽名定位,接收標簽名

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

driver.find_element_by_css_selector() # 通過css選擇器定位,接收其語法

#返回的WebElement對象可以繼續往下定位

xpath和css就不展開講了,能實現精確定位,一定要學其中一個,不知道的小伙伴們上網自學吧,不難

除了上面這些公有的方法,還有2個私有的方法來幫助頁面對象的定位。 這兩個方法就是 find_element 和 find_elements,需要導入By類輔助,接收一個By類屬性及其對應語法/值

from selenium.webdriver.common.by import By

driver.find_element(By.XPATH,'//a[text()="dark"]')

driver.find_elements(By.XPATH,'//a[text()="dark"]')

'''By類有以下屬性

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會遇到所見非所得,或者定位頁面元素的時候會定位不到的問題,這種情況很有可能是frame在搞鬼,必須切換到相應frame中再進行定位。如果遇到以上問題,第一時間F12看下你所要的信息是否在frame標簽里面。

frame標簽有frameset、frame、iframe三種,frameset跟其他普通標簽沒有區別,不會影響到正常的定位,而frame與iframe對selenium定位而言是一樣的。

selenium提供了4種方法定位iframe并切換進去:

#對于.....

driver.switch_to_frame(0) # 用frame的index來定位,第一個是0,以此類推

driver.switch_to_frame("frame1") # 用id來定位

driver.switch_to_frame("dark") # 用name來定位

driver.switch_to_frame(driver.find_element_by_tag_name("iframe")) # 用WebElement對象來定位

通常通過id和name就能實現,無此屬性時可以通過WebElement對象,即用find_element系列方法所取得的對象來定位。如果你確定每個目標frame都是固定第幾個,那也可以用index定位

切到frame中之后,就不能繼續操作主文檔的元素了,這時如果想操作主文檔內容,則需切回主文檔。

driver.switch_to_default_content()

嵌套frame的切換

如果frame里包著frame而你要的frame是后者,那么需要一層一層切換進去,切換方法四選一

driver.switch_to_frame("frame1")

driver.switch_to_frame("frame2")

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

window 切換

有時候點開一個鏈接就會彈出一個新窗口,如果要對其操作就要切換過去,方法和frame的切換差不多,但只接收window_handle(相當于窗口的名字)來進行切換。driver.switch_to_window("windowName")

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

current_window = driver.current_window_handle # 獲取當前窗口handle name

all_windows = driver.window_handles # 獲取所有窗口handle name

# 如果window不是當前window,則切換到該window,即切換到新窗口

for window in all_windows:

if window != current_window:

driver.switch_to_window(window)

#....

driver.switch_to_window(current_window) # 返回之前的窗口

driver.close() # 窗口的關閉用close()

頁面交互

常用的頁面交互有點擊,輸入文本等。交互的原則是先定位,后交互,比如你F12找到了某個文本框或某個可點擊項的標簽,那就先定位到那,再用以下的交互方法

from selenium.webdriver.common.keys import Keys

# 首先定位到某個文本框或某個可點擊項(如超鏈接,按鈕),

element = driver.find_element_by_xpath('//a[text()="dark"]')

element.send_keys("some text") # 往文本框輸入文本

#element.send_keys("some text", Keys.ARROW_DOWN) 可以使用 Keys 類來模擬輸入方向鍵

element.clear() # 清空文本框

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

要注意的一點是,不是定位到就必定能交互,有時候目標會被網頁彈出來的東西覆蓋,導致無法交互,所以要確保頁面干凈無覆蓋

上下拉滾動

selenium可以執行js,下拉滾動可以通過此實現,因此就算不懂js也可以記一些有用的js代碼

#driver.execute_script('js_str')

driver.execute_script('window.scrollTo(0,10000)') # 移動到指定坐標

driver.execute_script('window.scrollBy(0,10000)') # 相對當前坐標移動

driver.execute_script('window.scrollTo(0, document.body.scrollHeight)') # 相對當前坐標移動

等待

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

最粗暴的方法就是使用time.sleep(),這很笨,因為你還要設置合適的時間,而不同網站加載的速度有異,容易造成時間的浪費。所以最好還是使用selenium提供的兩種等待方法

顯式Wiats

顯式Wiats允許你設置一個加載時間的上限和一個條件,每隔0.5s就判斷一下所設條件,條件成立就繼續執行下面的代碼,如果過了時間上限還是沒有成立,默認拋出NoSuchElementException 異常。這種相對智能的等待方法能最大化地節省時間,應該優先選擇使用

selenium提供了多種expected_conditions(EC)來設置條件,但是要注意有定位時EC的方法接收的是定位信息的元組(locator_tuple)而不是兩個參數,正確用法如EC.presence_of_element_located((By.ID,"dark"))

這個條件檢測是否有id='dark'的元素

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

title_is(str)

title_contains(str)

presence_of_element_located(locator_tuple)

visibility_of_element_located(locator_tuple) # 判斷某個元素是否可見

visibility_of(WebElement) # 同上,傳參不同

presence_of_all_elements_located(locator_tuple)

text_to_be_present_in_element(str) # 判斷某個元素中的text是否包含了指定字符串

text_to_be_present_in_element_value(str) # 判斷某個元素中的value屬性是否包含了預期的字符串

frame_to_be_available_and_switch_to_it

invisibility_of_element_located(locator_tuple)

element_to_be_clickable(locator_tuple)

staleness_of(WebElement) # 等待某個元素從的移除

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() # 判斷頁面上是否存在alert

使用上通常搭配try語句

from selenium.webdriver.common.by import By

from selenium.webdriver.support.ui import WebDriverWait # 導入顯式等待

from selenium.webdriver.support import expected_conditions as EC # 導入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()

隱式等待

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

最后補充

這是用selenium幾分鐘弄出來的網易云音樂單曲評論爬蟲,而且還模擬了評論翻頁,還截了圖。沒提取信息,提取的時候可以用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("//a[starts-with(@class,'zbtn znxt')]")

b.click()

try:

WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH,"//a[@data-type='reply']")))

print(driver.page_source)

except NoSuchElementException:

print('OMG')

finally:

driver.quit()

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

總結

以上是生活随笔為你收集整理的python爬取js动态网页_Python 从零开始爬虫(八)——动态爬取解决方案 之 selenium的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。