我們在利用python進行爬取數據的時候,一定會遇到這樣的情況,在瀏覽器中打開能開到所有數據,但是利用requests去爬取源碼得到的卻是沒有數據的頁面框架。
出現這樣情況,是因為別人網頁使用了ajax異步加載,你的requests得到的只是頁面框架而已。
遇到這樣的情況有幾種方法可以解決:
1、分析(f12)network中的響應,從而獲得ajax的請求接口,在通過這些接口去獲得數據。
2、使用selenium這個網頁自動化測試工具,去獲得源碼。因為這個工具是等到頁面加載完成采取獲取的整個頁面的代碼,所以理論上是可以獲得頁面完整數據的。
我自己測試過一個頁面,也是獲取了完整數據的。有需要的朋友可以去自己測試。
下面,我們針對第二種方法,做一個實驗:本地新建一個json.html前端文件和json.php后端腳本。web服務器我們使用apache(集成環境xampp)。
json.php
<?php header('Access-Control-Allow-Origin:*'); //代表允許任何網址請求 $arr = array( 'testarr' => array( 'name' => 'panchao', 'age' => 18, 'tel' => '15928838350', 'addr' => 'test' ) ); echo json_encode($arr); ?>
json.html
<div id='test'> test </div> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script> function easyAjax(requestUrl){ $.ajax({ url: requestUrl, type: "GET", dataType: "json", success: function(msg){ var a = "<span>"+msg.testarr.name+"</span>"; //動態的向頁面中加入html元素 $("#test").append(a); }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert(XMLHttpRequest.status); alert(XMLHttpRequest.readyState); alert(textStatus); } }); } easyAjax("http://localhost:8080/json/json.php") </script>
然后我們分別用python的request和selenium(webdriver.Chrome)來做實驗。
request
import requests r = requests.get("http://localhost:8080/json/json.html") r.encoding = 'utf-8' print(r.text)
selenium(webdriver.Chrome)至於selenium怎么使用我前面的文章中有提到
from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_argument("--headless") driver = webdriver.Chrome(executable_path=(r'C:\Users\0923\AppData\Local\Google\Chrome\Application\chromedriver.exe'), options=chrome_options) base_url = "http://localhost:8080/json/json.html" driver.get(base_url) print(driver.page_source)
我們來看結果:
第一種,利用python request請求的方法得到的頁面數據為:
<div id='test'> test </div> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script> function easyAjax(requestUrl){ $.ajax({ url: requestUrl, type: "GET", //async : false, dataType: "json", success: function(msg){ var a = "<span>"+msg.testarr.name+"</span>"; console.log(msg); $("#test").append(a); }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert(XMLHttpRequest.status); alert(XMLHttpRequest.readyState); alert(textStatus); } }); } easyAjax("http://localhost:8080/json/json.php") </script>
第二種,利用selenium(webdriver.Chrome)方法得到的頁面數據為:
<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><div id="test"> test <span>panchao</span></div> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script> function easyAjax(requestUrl){ $.ajax({ url: requestUrl, type: "GET", //async : false, dataType: "json", success: function(msg){ var a = "<span>"+msg.testarr.name+"</span>"; console.log(msg); $("#test").append(a); }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert(XMLHttpRequest.status); alert(XMLHttpRequest.readyState); alert(textStatus); } }); } easyAjax("http://localhost:8080/json/json.php") </script></body></html>
我們可以看到以上兩種結果,最主要的差異就是第二種方法(selenium(webdriver.Chrome))得到的web代碼中包含了ajax異步加載的數據。
<div id="test"> test <span>panchao</span></div>
而第一種方法(python request)得到的web代碼中沒有包含ajax異步加載的數據。
<div id='test'> test </div>
根據以上結論,證明利用selenium(webdriver.Chrome)來獲取頁面數據,是可以獲取到javascript腳本加載的數據的。
不知道大家有沒有注意到利用selenium(webdriver.Chrome)來獲取頁面數據的方法還自動的給我們不全了html的標簽
希望可以幫助到有需要的人。