Spider-Python爬蟲之使用Selenium模擬瀏覽器行爲

分析

他的代碼比較簡單,主要有如下的步驟:使用BeautifulSoup庫,打開百度貼吧的首頁地址,再解析獲得idnew_list標籤底下的img標籤,最後將img標籤的圖片保存下來。javascript

headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'
}

data=requests.get("https://tieba.baidu.com/index.html",headers=headers)
html=BeautifulSoup(data.text,'lxml')

前面提到過,有部分圖片是動態加載的,那麼首先咱們得弄清楚,這部分圖片是怎麼動態加載的。在瀏覽器中打開百度貼吧的首頁,能夠明顯的看到,在往下滾動滾動條的時候,當滾動到底部的時候,滾動條縮短了,並向上移動了一段距離。這個現象也正是有DOM元素動態的添加到了html文檔的一個表現。動態加載數據無非就是ajax請求,而ajax本質上就是XMLHttpRequest請求(簡稱xhr)。在谷歌瀏覽器中,咱們能夠經過開發者工具的network面板來監測xhr請求。css

剛打開首頁時的xhr請求,這裏的請求都和要爬取的圖片無關。html

滾動條向下第1次滾動到底部,這裏請求的是第20-40條熱門動態,包含要爬取圖片。java

滾動條向下第2次滾動到底部,這裏請求的是第40-60條熱門動態,包含要爬取圖片。而且返回的的has_more:false代表沒有跟多數據了。python

滾動條向下第3次滾動到底部,再無xhr請求。git

解決方案

根據上面的分析,咱們已經明白,單純使用BeautifulSoup進行爬蟲的時候,只能爬取到1-20條熱門動態裏面的圖片。爲了爬取到完整的熱門動態裏面的圖片,咱們則須要模擬瀏覽器的滾動條滾動,讓網頁去觸發xhr請求更多的熱門動態。github

在python中,若是須要模擬瀏覽器的行爲,可使用selenium庫。selenium庫是一個自動化測試框架,能夠用來模擬測試瀏覽器的各類行爲,這裏咱們使用它來模擬瀏覽器打開百度貼吧的首頁,並模擬滾動條向下滾動到底部的操做。web

安裝

pip install selenium

下載瀏覽器驅動

對照本身電腦安裝的瀏覽器和對應的版本,分別從上面的地址下載驅動文件,也能夠從個人github項目中統一下載以上幾個驅動(地址:https://github.com/Sesshoumaru/attachments/tree/master/Selenium%20WebDriver)。下載解壓後,將所在的目錄添加系統的環境變量中。固然你也能夠將下載下來的驅動放到python安裝目錄的lib目錄中,由於它自己已經存在於環境變量(我就是這麼幹的)。

使用python代碼模擬瀏覽器行爲

要使用selenium先須要定義一個具體browser對象,這裏就定義的時候就看你電腦安裝的具體瀏覽器和安裝的哪一個瀏覽器的驅動。這裏以火狐瀏覽器爲例:

from selenium import webdriver
browser = webdriver.Firefox()

再模擬打開貼吧首頁:

browser.get("https://tieba.baidu.com/index.html")

再模擬滾動條滾動到底部

for i in range(1, 5):
    browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
    time.sleep(1)

最後再使用BeautifulSoup,解析圖片標籤:

html = BeautifulSoup(browser.page_source, "lxml")
imgs = html.select("#new_list li img")

幾個注意點

  • 必須安裝瀏覽器和瀏覽器驅動,而且瀏覽器和瀏覽器驅動要配到

    即若是使用谷歌瀏覽器模擬網頁行爲,則須要下載谷歌瀏覽器驅動;
      若是使用火狐瀏覽器模擬網頁行爲,則須要下載火狐瀏覽器驅動
  • 瀏覽器驅動所在的目錄要在環境變量中,或者定義瀏覽器browser的時候指定驅動的路徑

selenium更多用法

查找元素

from selenium import webdriver

browser = webdriver.Firefox()
browser.get("https://tieba.baidu.com/index.html")

new_list = browser.find_element_by_id('new_list')
user_name = browser.find_element_by_name ('user_name')
active = browser.find_element_by_class_name  ('active')
p = browser.find_element_by_tag_name ('p')

# find_element_by_name 經過name查找單個元素
# find_element_by_xpath 經過xpath查找單個元素
# find_element_by_link_text 經過連接查找單個元素
# find_element_by_partial_link_text 經過部分連接查找單個元素
# find_element_by_tag_name 經過標籤名稱查找單個元素
# find_element_by_class_name 經過類名查找單個元素
# find_element_by_css_selector 經過css選擇武器查找單個元素
# find_elements_by_name 經過name查找多個元素
# find_elements_by_xpath 經過xpath查找多個元素
# find_elements_by_link_text 經過連接查找多個元素
# find_elements_by_partial_link_text 經過部分連接查找多個元素
# find_elements_by_tag_name 經過標籤名稱查找多個元素
# find_elements_by_class_name 經過類名查找多個元素
# find_elements_by_css_selector 經過css選擇武器查找多個元素

獲取元素信息

btn_more = browser.find_element_by_id('btn_more')
print(btn_more.get_attribute('class')) # 獲取屬性
print(btn_more.get_attribute('href')) # 獲取屬性
print(btn_more.text) # 獲取文本值

元素交互操做

btn_more = browser.find_element_by_id('btn_more')
btn_more.click() # 模擬點擊,能夠模擬點擊加載更多

input_search = browser.find_element(By.ID,'q')
input_search.clear() # 清空輸入

執行JavaScript

# 執行JavaScript腳本
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
browser.execute_script('alert("To Bottom")')
相關文章
相關標籤/搜索