Python爬虫实战H03网页滚动加载的原理及爬取(JavaScript加密混淆逆向基础)图文教程

2024-12-30阅读数:49
上一篇:Python爬虫实战H04js加密混淆及简单反调试图文教程
下一篇:Python爬虫实战H02高分电影列表复杂页面的解析(仿豆瓣电影)- xpath高级用法图文教程

打开Python爬虫实战练习页面网页滚动加载的原理及爬取(JavaScript加密混淆逆向基础)_H03_Spiderbuf,可以看到页面内容是豆瓣电影评分,而且往下滚动页面会有几次内容的加载,到了《哈利·波特与魔法石》这里停了下来。

这种情况通常都是由JavaScript代码控制的,通过计算页面内容的高度及位置等判断是否需要加载新的数据。

在网页上点击右键 > 显示网页源代码,可以看到一部分的豆瓣电影评分内容,比我们在页面上看到的内容要少很多。这是因为浏览器查看源码这里通常只能查看到到首次加载的HTML代码,而通过JavaScript代码生成的HTML内容并不会在这里显示出来。想要看到完整的内容,就需要到开发者工具 -> Elements(元素)那里查看。

F12打开谷歌浏览器开发者工具,刷新一下页面,切换到开发者工具Network标签页,可以看到除了加载了h03页面之外,还有一个CSS样式文件以及一些jpg图片,这些图片点击一下就能看到其实就是一些电影海报,还有一个i7KQc.js的js文件,还有一个请求显示显示了5f685274073b这样的。

我们点开5f685274073b这个请求,右边展开的详情页点击Response(响应),就能看到里面是一些HTML代码内容,主要由一些div之类的组成。大致检查一下这些代码,就会在最后发现一个隐藏的div。

<div id="sLaOuol2SM0iFj4d" hidden>279fcd874c72</div>

做爬虫的时候要特别留意这些隐藏的东西,因为隐藏的东西往往就是做爬虫的关键信息。

到了这里还无法形成我们做这个爬虫的思路,但结合上面的分析,我们知道有通过JavaScript代码加载的内容,而我们目前看到的JavaScript代码就只有i7KQc.js这个文件。

点开之后发现是明文,而且逻辑也不复杂,稍微懂一些JavaScript语言的都能看懂。

window.addEventListener('scroll', function () {
    const pageHeight = document.body.scrollHeight;
    const windowHeight = window.innerHeight;
    const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;

    const threshold = 100;
    if (pageHeight - (windowHeight + scrollTop) < threshold) {
        var page = document.getElementById('sLaOuol2SM0iFj4d');
        if (page == null) {
            return;
        }
        fetch("./h03/" + page.textContent).then(response => response.text())
        .then(function (data) {
            var main_div = document.getElementById('main');
            page.remove();
            main_div.insertAdjacentHTML("beforeEnd", data);
        });
    }
});

这些JavaScript代码就是给网页加入了一个滚动事件监听,在页面滚动里计算是否滚动到了底部,如果是,则通过getElementById获取元素ID为sLaOuol2SM0iFj4d的元素。我们回到网页源码查找,可以看到这个元素是一个div。

<!-- HTML源码第240行 -->
<div id="sLaOuol2SM0iFj4d" hidden>5f685274073b</div>

然后通过fetch函数向后台请求数据,URL带上ID为sLaOuol2SM0iFj4d的div的内容。然后把这个元素删除,再把后台返回的内容插入到main元素的最后面。

结合我们在上面发现的隐藏元素,ID同样为sLaOuol2SM0iFj4d,而且在网页滚动至不再加载新的内容的时候,最后返回的内容没有了这个隐藏元素。这样综合分析,就能得出这个网页的加载思路了:

以ID为sLaOuol2SM0iFj4d的div内容作为参数,向后台请求新的数据,直至到返回的数据没有新的参数,说明已经全部加载完毕。

这个思路是不是很熟悉,其实有点像我们之前的E03 - 无序号翻页无序号翻页。只不过这次返回的不一定是一个完整的页面。

分析出了这个网页内容的加载逻辑,我们就可以使用Python写爬虫代码了。

url = 'http://www.spiderbuf.cn/h03/'
html = requests.get(url, headers=myheaders).text
# get next page uri
uri = ''
root = etree.HTML(html)
divs = root.xpath('//div[@id="sLaOuol2SM0iFj4d"]/text()')
if len(divs) > 0:
    uri = divs[0]

i = 1
while (uri != '') & (i < 10):
    html = requests.get(url, headers=myheaders).text
    uri = '' # ***
    root = etree.HTML(html)
    divs = root.xpath('//div[@id="sLaOuol2SM0iFj4d"]/text()')
    if len(divs) > 0:
        uri = divs[0]
    i += 1

把数据都爬了下来,接下来根据之前的xpath知识对这个网页进行解析提取内容即可。

完整示例代码:示例代码