1. 程式人生 > >(四)爬蟲之動態網頁

(四)爬蟲之動態網頁

  對於網頁上的有些內容,需要進行一定的互動操作,才能拿到相應的資料,例如常見的ajax請求等。為了抓取ajax請求的結果,可以通過ajax請求的url,抓取返回結果,也可以利用Selenium模組來模擬網頁ajax。簡單記錄下一段學習過程。

1.問題分析

  如下面我愛我家的網頁中(https://wh.5i5j.com/ershoufang/),當在搜尋框中輸入“保”時,後臺會自動傳送ajax請求,拿到所有包含“保”字的小區名字。

   

  通過network分析可以看到ajax請求的返回一個json物件:

2. 抓取資料

  2.1 利用requests

    構造ajax請求的url,利用ajax請求,分析拿到的json資料,程式碼如下:

#coding:utf-8
import requests
import json
from lxml import html

url="https://wh.5i5j.com/ajaxsearch?status=ershoufang&keywords=%s"%(u'')
response = requests.get(url,headers={'User-Agent':"Mozilla/5.0 (Windows NT 6.1; r…) Gecko/20100101 Firefox/64.0"})
html_string = json.loads(response.text)['res']
tree 
= html.fromstring(html_string) li_tags=tree.getchildren() house_info={} for tag in li_tags: name = tag.xpath('.//div/span[@class="name"]/text()')[0] count = tag.xpath('.//span[@class="tao"]/text()')[0] print name,count house_info[name]=count # print house_info

  2.2 利用selenium

    selenium可以模擬瀏覽器的行為,因此可以用來作為爬蟲使用(但速度較慢),模擬瀏覽器訪問網站。

    安裝selenium:pip install selenium

    (下載瀏覽器驅動:第一次使用selenium時,可能會報錯selenium.common.exceptions.WebDriverException,這是因為需要下載模擬的瀏覽器的驅動,下載地址https://github.com/SeleniumHQ/selenium/tree/master/py#drivers

    selenium的使用參考:http://www.aneasystone.com/archives/2018/02/python-selenium-spider.html

    使用selenium抓取上面資料的程式碼如下:

from selenium import webdriver

driver = webdriver.Firefox(executable_path='D:\\Python\\geckodriver.exe')  #路徑為下載的瀏覽器驅動儲存路徑
driver.get('https://wh.5i5j.com/zufang/')  #開啟網頁
kw = driver.find_element_by_id("zufang")   #找到搜尋框
kw.send_keys(u"")                         #搜尋框中輸入文字 “萬”
# button = driver.find_element_by_class_name("btn-search")
# button.click()
driver.implicitly_wait(30)  #隱式等待30秒,瀏覽器查詢每個元素時,若未找到會等待30s,30s還未找到時報錯
li_tags = driver.find_elements_by_css_selector('ul.search_w li')  #注意此處是find_elements, 複數查詢多個element
for li_tag in li_tags:
    name = li_tag.find_element_by_class_name('name').text
    count = li_tag.find_element_by_class_name('tao').text
    print name, count

   上面程式碼中,由於ajax請求執行完成需要時間,driver.implicitly_wait(30)讓瀏覽器隱式等待30秒,即瀏覽器查詢每個元素時,若未找到會等待30s,30s後還未找到時會報錯。

關於selenium的等待有顯示等待和隱式等待。(區別參考:https://www.cnblogs.com/dsy-sun/articles/6594866.html

  顯示等待:明確說明等待某個元素出現或條件成立時,如下面程式碼:   

newWebDriverWait(driver,15).until(        
ExpectedConditions.presenceOfElementLocated(By.cssSelector("css locator")));

  隱式等待:全域性的,對所有元素都有效,找不到該元素時會等待設定時間,如上面的driver.implicitly_wait(30)