关于python爬取异步ajax数据的一些见解

我们在利用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:Users923AppDataLocalGoogleChromeApplicationchromedriver.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 = "&lt;span&gt;"+msg.testarr.name+"&lt;/span&gt;";

    
    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的标签

 

希望可以帮助到有需要的人。

原文地址:https://www.cnblogs.com/573734817pc/p/11187308.html