抓取去哪兒網機票數據
此次,我們使用webdriver測試抓取去哪兒網機票數據,爲什麼不爬取主站而爬取 m站,因爲主站機票價格通過css操作使網頁顯示價格與html元素呈現的價格不一樣,雖然可以解決但比較繁瑣。但是m站價格兩者是相同的,所以我們抓取m站點的數據,感興趣的可以自行破解css混淆抓取主站數據。
移動端數據
主站PC端
通過分析得知數據獲取url如下
所以我們只需要通過webdriver請求上述地址,更改相應的參數就能獲取到數據。
requests_dic = {
'depCity': from_city, 出發地
'arrCity': to_city, 到達地
'goDate': '2019-02-27' 日期
}
請求網址:driver_url = 'https://m.flight.qunar.com/ncs/page/flightlist?
%s&from=touch_index_search&child=0&baby=0&cabinType=0'%requestjdic
注意:webdriver要設置的相關參數
mobile_emulation = {"deviceName": "iPhone X"}
options = Options()
# 很重要破解webDiver檢測 避免js檢測webdriver機制
options.add_experimental_option('excludeSwitches', ['enable-automation'])
options.add_experimental_option("mobileEmulation", mobile_emulation)
driver = webdriver.Chrome(options=options)
去哪網有webdriver 檢測機制,單純使用webdriver 會遭到反爬, 在console 中輸入window.navigator.webdriver, 正常的瀏覽器會顯示 undefined, webdriver下會顯示 true。有興趣的自行測試。
在js判斷window.navigator.webdriver返回值就可以檢測,懂js的可能會想到覆蓋這個值,比如使用如下代碼Object.defineProperties(navigator,{webdriver:{get:()=>undefined}}),確實可以修改成功。這種寫法還是存在某些問題的,如果此時你在模擬瀏覽器中通過點擊鏈接、輸入網址進入另一個頁面,或者開啓新的窗口,你會發現window.navigator.webdriver又變成了true.那麼是不是可以在每一個頁面都打開以後,再次通過webdriver執行上面的js代碼,從而實現在每個頁面都把window.navigator.webdriver設置爲undefined呢?也不行。因爲當你執行:driver.get(網址)的時候,瀏覽器會打開網站,加載頁面並運行網站自帶的js代碼。所以在你重設window.navigator.webdriver之前,實際上網站早就已經知道你是模擬瀏覽器了。在啓動Chromedriver之前,爲Chrome開啓實驗性功能參數excludeSwitches,它的值爲['enable-automation']從而解決這個問題。
現在就可以使用webdriver 爬取頁面, 進入頁面可以看到。
我們只需要控制webdriver向下滑動並且點擊加載更多的元素就可以獲取更多的數據。
# 屏幕向下滑動到最低端
driver.execute_script("window.scrollTo(100, document.body.scrollHeight);")
more_list = driver.find_element_by_xpath(".//section[@class='list-getmore']")
print(more_list.text)
# 選擇加載更多按鈕並且點擊
driver.find_element_by_xpath(".//section[@class='list-getmore']").click()
通過xpath進行數據的提取
from_time = text(driver.find_elements_by_xpath('//div[@class="from-info"]/p[1]'))
from_airport = text(driver.find_elements_by_xpath('//div[@class="from-info"]/p[2]'))
to_time = text(driver.find_elements_by_xpath('//div[@class="to-info"]/p[1]'))
to_airport = text(driver.find_elements_by_xpath('//div[@class="to-info"]/p[2]'))
company_main = driver.find_elements_by_xpath('//div[@class="company-info"]')
price = text(driver.find_elements_by_xpath('//p[@class="price-info"]'))
pandas寫文件
df = pd.DataFrame(
{'from_time': from_time, 'from_airport': from_airport, 'to_time': to_time, 'to_airport': to_airport,
'the_plane': plane_list, 'company': company_list, 'real_price_list': price})
df.to_csv("qunaer.csv", header=0, mode='a+', index=0)
部分結果如下
關於Chrome的excludeSwitches等相關參數含義自行Google。
想要獲取源碼 關注公衆號 <程序員之心> 後臺回覆 <去哪兒網> 就可獲取。只分享技術,切勿商用。
源碼分享 https://github.com/tanjunchen/SpiderProject/tree/master/selenium+qunaerwang