Python项目——轻松实现动态网页爬虫|附详细源码

news2024/11/26 2:28:45

动态网页爬虫是专门设计用来爬取动态网页内容的自动化程序或工具。与静态网页爬虫不同,动态网页的内容不是预先存储在服务器上的HTML文件,而是根据用户的请求、交互、时间、数据库状态或其他外部因素动态生成的。这些动态内容通常通过JavaScript、AJAX(Asynchronous JavaScript and XML)或其他客户端脚本技术在浏览器中异步加载。
在这里插入图片描述

动态网页爬虫的特点:

  1. 实时性:由于动态网页内容是根据用户请求实时生成的,因此动态网页爬虫能够获取到最新的数据。

  2. 依赖客户端渲染:动态网页的内容通常是在浏览器端通过JavaScript渲染的,这意味着爬虫需要模拟浏览器的行为来执行JavaScript并渲染DOM(文档对象模型)。

  3. AJAX和WebSockets:动态网页经常通过AJAX调用与服务器进行异步通信,获取或更新页面内容。WebSockets则提供了全双工通信渠道,使得服务器可以主动向客户端推送数据。动态网页爬虫需要处理这些通信过程。

  4. 复杂性:由于动态网页的生成涉及多个技术栈(如HTML、CSS、JavaScript、AJAX、WebSockets等),因此动态网页爬虫的实现相对复杂。

实现方法:

  1. 使用浏览器自动化工具:如Selenium、Puppeteer(Node.js环境)或Pyppeteer(Python封装版)等,这些工具可以模拟用户在浏览器中的操作,包括打开网页、点击链接、填写表单、执行JavaScript等,从而获取渲染后的页面内容。

  2. 网络抓包工具:通过分析浏览器与服务器之间的通信(如使用Wireshark、Fiddler、Chrome DevTools等工具),识别出动态内容加载的AJAX请求,然后使用HTTP客户端库(如requests、urllib等)直接发送这些请求并获取数据。

  3. 无头浏览器:无头浏览器是指没有图形用户界面(GUI)的浏览器,它们可以在没有显示界面的情况下执行JavaScript和渲染DOM。例如,Puppeteer和Pyppeteer都是基于Chromium的无头浏览器解决方案。

  4. JavaScript执行引擎:一些爬虫框架(如Scrapy的Splash插件)集成了JavaScript执行引擎,允许爬虫在执行HTML解析之前先执行页面中的JavaScript代码。
    AJAX(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。通过AJAX,网页可以异步地(在后台)与服务器交换数据并更新部分网页内容,而无需重新加载整个页面。这对于创建动态、交互式和响应迅速的网页应用程序非常有用。

AJAX工作原理

  1. 创建XMLHttpRequest对象:AJAX通过XMLHttpRequest对象与服务器交换数据。尽管名字中包含“XML”,但AJAX通信可以返回任何类型的数据,包括JSON、HTML、纯文本等。

  2. 配置请求:设置请求的方法(如GET或POST)、URL以及可能的请求头、请求体等。

  3. 发送请求:将配置好的请求发送到服务器。

  4. 处理响应:当服务器响应时,XMLHttpRequest对象会触发相应的事件(如onreadystatechange),此时可以读取服务器的响应数据,并使用JavaScript来更新网页的DOM。

示例代码

以下是一个简单的AJAX示例,用于从服务器动态加载HTML内容并插入到网页中。假设我们有一个服务器端的脚本(例如data.php),它返回一些HTML数据。

HTML文件(index.html)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>AJAX Example</title>
</head>
<body>

<div id="content">内容将在这里加载...</div>
<button onclick="loadContent()">加载内容</button>

<script>
function loadContent() {
    var xhr = new XMLHttpRequest(); // 创建XMLHttpRequest对象
    xhr.open('GET', 'data.php', true); // 配置请求,URL为'data.php',异步模式

    // 当接收到响应时执行此函数
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            // 检查是否请求已完成并且响应已成功返回
            document.getElementById('content').innerHTML = xhr.responseText; // 更新DOM
        }
    };

    xhr.send(); // 发送请求
}
</script>

</body>
</html>
PHP文件(data.php)
<?php
// 假设的服务器端脚本,返回一些HTML内容
echo '<p>这是通过AJAX动态加载的内容!</p>';
?>

项目实操

怎么说了那么多理论,说实话也不想那么啰嗦。可是吧,这些东西经常会被问到,干脆直接写下来,下次还有人问就直接把这篇文章发给他,一劳永逸!

我们拿一个法院信息公示网页举例:

那我们就开启爬虫的正确姿势吧,先用解析接口的方法来写爬虫。

首先,找到真实请求。右键检查,点击Network,选中XHR,刷新网页,选择Name列表中的jsp文件。没错,就这么简单,真实请求就藏在里面。

我们再仔细看看这个jsp,这简直是个宝啊。有真实请求url,有请求方法post,有Headers,还有Form Data,而From Data表示给url传递的参数,通过改变参数,咱们就可以获得数据!

我们再仔细看看这些参数,pagesnum参数不就是代表页数嘛!我们尝试点击翻页,发现只有pagesnum参数会变化。

既然发现了它,那就赶紧抓住它。打开PyCharm,导入了爬虫所需的库。

1from urllib.parse import urlencode  
2import csv  
3import random  
4import requests  
5import traceback  
6from time import sleep  
7from lxml import etree    #lxml为第三方网页解析库,强大且速度快  

构造真实请求,添加Headers。

 1base_url = 'http://www.hshfy.sh.cn/shfy/gweb2017/ktgg_search_content.jsp?'  #这里要换成对应Ajax请求中的链接  
 2  
 3headers = {  
 4    'Connection': 'keep-alive',  
 5    'Accept': '*/*',  
 6    'X-Requested-With': 'XMLHttpRequest',  
 7    'User-Agent': '你的User-Agent',  
 8    'Origin': 'http://www.hshfy.sh.cn',  
 9    'Referer': 'http://www.hshfy.sh.cn/shfy/gweb2017/ktgg_search.jsp?zd=splc',  
10    'Accept-Language': 'zh-CN,zh;q=0.9',  
11    'Content-Type': 'application/x-www-form-urlencoded',  
12    'Cookie': '你的Cookie'  
13}

构建get_page函数,自变量为page,也就是页数。以字典类型创建表单data,用post方式去请求网页数据。这里要注意要对返回的数据解码,编码为’gbk’,否则返回的数据会乱码!另外我还加了异常处理优化了下,以防意外发生。

 1def get_page(page):  
 2    n = 3  
 3    while True:  
 4        try:  
 5            sleep(random.uniform(1, 2))  # 随机出现1-2之间的数,包含小数  
 6            data = {  
 7                'yzm': 'yxAH',  
 8                'ft':'',  
 9                'ktrqks': '2020-05-22',  
10                'ktrqjs': '2020-06-22',  
11                'spc':'',  
12                'yg':'',  
13                'bg':'',  
14                'ah':'',  
15                'pagesnum': page  
16            }  
17            url = base_url + urlencode(data)  
18            print(url)  
19            try:  
20                response = requests.request("POST",url, headers = headers)  
21                #print(response)  
22                if response.status_code == 200:  
23                    re = response.content.decode('gbk')  
24                    # print(re)  
25                    return re  # 解析内容  
26            except requests.ConnectionError as e:  
27                print('Error', e.args)  # 输出异常信息  
28        except (TimeoutError, Exception):  
29            n -= 1  
30            if n == 0:  
31                print('请求3次均失败,放弃此url请求,检查请求条件')  
32                return  
33            else:  
34                print('请求失败,重新请求')  
35                continue

构建parse_page函数,对返回的网页数据进行解析,用Xpath提取所有字段内容,保存为csv格式。有人会问为这么喜欢用Xpath,因为简单好用啊!!!

 1def parse_page(html):  
 2    try:  
 3        parse = etree.HTML(html)  # 解析网页  
 4        items = parse.xpath('//*[@id="report"]/tbody/tr')  
 5        for item in items[1:]:  
 6            item = {  
 7                'a': ''.join(item.xpath('./td[1]/font/text()')).strip(),  
 8                'b': ''.join(item.xpath('./td[2]/font/text()')).strip(),  
 9                'c': ''.join(item.xpath('./td[3]/text()')).strip(),  
10                'd': ''.join(item.xpath('./td[4]/text()')).strip(),  
11                'e': ''.join(item.xpath('./td[5]/text()')).strip(),  
12                'f': ''.join(item.xpath('./td[6]/div/text()')).strip(),  
13                'g': ''.join(item.xpath('./td[7]/div/text()')).strip(),  
14                'h': ''.join(item.xpath('./td[8]/text()')).strip(),  
15                'i': ''.join(item.xpath('./td[9]/text()')).strip()  
16            }  
17            #print(item)  
18            try:  
19                with open('./law.csv', 'a', encoding='utf_8_sig', newline='') as fp:  
20                    # 'a'为追加模式(添加)  
21                    # utf_8_sig格式导出csv不乱码  
22                    fieldnames = ['a', 'b', 'c', 'd', 'e','f','g','h','i']  
23                    writer = csv.DictWriter(fp,fieldnames)  
24                    writer.writerow(item)  
25            except Exception:  
26                print(traceback.print_exc())  #代替print e 来输出详细的异常信息  
27    except Exception:  
28        print(traceback.print_exc())

最后,遍历一下页数,调用一下函数。OK,搞定!

1    for page in range(1,5):  #这里设置想要爬取的页数  
2        html = get_page(page)  
3        #print(html)  
4        print("第" + str(page) + "页提取完成")  

我们来看一下最终效果:

结 语

总结一下,对于AJAX动态加载网页爬虫,一般就两种方式:解析接口;Selenium。这次就先介绍了解析接口方式,个人还是推荐解析接口的方式,如果解析的是json数据,就更好爬了。实在没办法了再用Selenium吧。

关于Python学习指南

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程。带你从零基础系统性的学好Python!
————————————————

在这里插入图片描述

**全套Python学习资料分享:
👉Python所有方向的学习路线👈

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。(全套教程文末领取)

​​​​在这里插入图片描述

👉学习软件

在这里插入图片描述

👉全套PDF电子书

在这里插入图片描述

👉实战案例
在这里插入图片描述

👉Python副业兼职路线&方法👈
学好 Python 不论是就业还是做副业赚钱都不错,但要学会兼职接单还是要有一个学习规划。

在这里插入图片描述

👉 这份完整版的Python全套学习资料已经上传,朋友们如果需要可以扫描下方CSDN官方认证二维码或者点击链接免费领取保证100%免费

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2035652.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年3个超好用的思维导图软件推荐

专业又经典的思维导图模板&#xff0c;全部拿去&#xff0c;可以直接套用的喔 1、TreeMind树图 推荐指数&#xff1a;☆☆☆☆☆ 点击直达官网>>https://shutu.cn/ TreeMind树图是一个在线思维导图工具&#xff0c;提供65万份思维导图模板&#xff0c;涵盖了各种使用场…

Java二十三种设计模式-观察者模式(15/23)

观察者模式&#xff1a;实现对象间的松耦合通知机制 引言 在当今的软件开发领域&#xff0c;设计模式已成为创建可维护、可扩展和可重用代码的基石。在众多设计模式中&#xff0c;观察者模式以其独特的能力&#xff0c;实现对象间的松耦合通信而脱颖而出。本文将深入探讨观察…

信息安全等级保护:全面解读与实践指南

一、什么是等级保护&#xff1f; 1.1 概念 信息安全等级保护是依据我国《信息安全等级保护管理办法》&#xff0c;对各类信息系统基于重要程度和保密需求进行分级&#xff0c;并制定相应技术与管理措施&#xff0c;以保障信息系统的安全性、完整性和可用性。等级保护共分五级…

【开源 Mac 工具推荐之 4】Awesome-macOS:全能的宝藏工具库

简介 Awesome-macOS 是一个开源项目&#xff0c;属于 GitHub 的热门项目“Awesome”的体系&#xff0c;旨在为 macOS 用户提供一个集合了各种优秀的 macOS 应用程序、插件、脚本和工具的精选列表。该项目由开源社区共同维护&#xff0c;通过不断收集和整理优秀的macOS资源&…

小白安装---Ubuntu教程!!!

1、首先将映像源放入到一个不被删除的地方。 2、打开vmware&#xff0c;创建一个虚拟机 3、 按照顺序点击 4、选择映像源 选择22版的映像 5、设置主机名称和密码 6、设置虚拟机名称和位置 7、 设置磁盘大小 8、选择配置&#xff0c;使用推荐的就行&#xff08;这个可以随时修改…

二级制安装LAMP

一、安装Apache 1.1解压 tar xf apr-1.6.2.tar.gz tar xf apr-util-1.6.0.tar.gz tar xf httpd-2.4.29.tar.bz2 mv apr-1.6.2 httpd-2.4.29/srclib/apr mv apr-util-1.6.0 httpd-2.4.29/srclib/apr-util1.2安装相关工具 yum -y install \ gcc \ #C语言的编译器 gcc-c+…

HarmonyOS应用一之登录页面案例

目录&#xff1a; 1、代码示例2、代码分析3、注解分析 1、代码示例 实现效果&#xff1a; /** Copyright (c) 2023 Huawei Device Co., Ltd.* Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance w…

【数据结构】六、图:6.图的最短路径(BFS 算法、迪杰斯特拉(Dijkstra)算法、弗洛伊德(Floyd)算法)

3.最短路径 文章目录 3.最短路径3.1 BFS 算法3.2 迪杰斯特拉(Dijkstra)算法3.3 弗洛伊德(Floyd)算法总结 在网图和非网图中&#xff0c;最短路径的含义是不同的。 由于非网图它没有边上的权值&#xff0c;所谓的最短路径&#xff0c;其实就是指两顶点之间经过的边数最少的路径。…

JAVA—集合框架

集合 大小可变 是存储数据的容器&#xff0c;本文是在学习过ArrayList集合后对于集合进行一个比较系统的学习&#xff0c;只要是对于Collection类和Map类的学习和案例实践。需要对于Stream流再进行加深学习和理解&#xff0c;功能比较强大和简洁。 目录 1.集合体系结构 &…

流程图语法Mermaid教程

在使用Markdown来编写博客的过程中&#xff0c;尤其是需要更醒目的逻辑说明时&#xff0c;就需要使用流程图。 既然CSDN官方推荐Mermaid作为流程图语法&#xff0c;那我也针对Mermaid来做一期教程。 在学习之前&#xff0c;先总结一下流程图的需求&#xff1a; 节点设置方向设…

好看的超清4K视频素材去哪里找?下载素材资源网站分享

在当前高清与4K视频素材盛行的时代&#xff0c;创作出色的视频内容离不开优质的超清4K视频素材。以下是一些宝藏网站&#xff0c;它们提供了丰富的4K视频素材&#xff0c;可以使您的视频创作更加引人注目。 蛙学网 蛙学网是获取高质量4K视频素材的首选之地。该网站详细标注了视…

lvs、集群

1.集群和分布式 当多个用户当用户访问一个服务器时&#xff0c;服务器server1可能就会崩&#xff0c;假如这时候我们新加一个服务器server2来缓解server1的压力&#xff0c;那么就需要一个调度器lvs来分配&#xff0c;所以现在就是用户的访问就需要通过调度器之后到达服务器&a…

期望薪资3k,面试官笑了但没说话

吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247485367&idx1&sn837891059c360ad60db7e9ac980a3321&chksmc0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330#rd 《网安面试指南》http://mp.weixin.qq.com/s?…

Linux系统编程(8)进程进阶

一、进程的执行 子进程被创建好后&#xff0c;就需要去执行它所该执行的功能&#xff0c;根据子进程需要做的事&#xff0c;将其分为两类&#xff1a; 1.子进程所做的事与父进程差不多&#xff0c;两者功能几乎一样 //子承父业 2.子进程所做的事和父进程做的事完全不同&…

随手记录第十四话 -- 在 Spring Boot 3.2.3 中使用 springdoc-openapi-starter-webmvc-ui

项目升级到JDK21后&#xff0c;SpringBoot版本也到了3.2.3&#xff0c;之前的Swagger-ui不在支持了&#xff0c;找了其他的一直忘记记录了&#xff0c;这里记录一下。 快捷目录 1.引言2.添加依赖3.配置类4.Java代码实现5.启动应用6.总结 1.引言 随着 Spring Boot 版本的更新&a…

一个C++模板有意思的小实验

看面经遇到一个C模板的问题&#xff0c;顺手做了下实验看看结果&#xff0c;觉得比较有意思就记录一下 我们一般用模板会把声明和定义放在一起(放在同一个头文件内)&#xff0c;那么如果我们在一个头文件内声明我们要使用的模板函数&#xff0c;并在另一个cpp文件内实现会怎么样…

HarmonyOS NEXT星河版零基础入门(2)

1.Scroll滚动容器-核心用法 1&#xff08;1&#xff09;.Scroll的核心用法 快速得到一个长度为5的数组 Array.from({length:5}) 代码&#xff1a; 这种是默认是竖向的 要是想要实现横向的 就得把Scroll里边的Column改为Row组件 并且把scrolllable设置为Horizontal横向 1&a…

Spring AI 更新:支持OpenAI的结构化输出,增强对JSON响应的支持

就在昨晚&#xff0c;Spring AI发了个比较重要的更新。由于最近OpenAI推出了结构化输出的功能&#xff0c;可确保 AI 生成的响应严格遵守预定义的 JSON 模式。此功能显着提高了人工智能生成内容在现实应用中的可靠性和可用性。Spring AI 紧随其后&#xff0c;现在也可以对OpenA…

如何在萤石云视频app转移设备

本文将详述如何在萤石云视频app转移设备 一&#xff0e; 注意事项 1. 若设备正在分享中,无法转移 2. 若设备已开通云存储等可以转移的增值服务&#xff0c;相应的服务也会转移&#xff1b;若开通了订阅服务将取消订阅服务&#xff0c;次月不再扣费续订 3. 转移设备时若设备…

【iOS】—— Runloop和多线程问题总结

Runloop和多线程问题总结 runloop总结1. runloop简介2. runloop的基本作用3. 获取runloop的流程4. runloop和线程的关系5. runloop中的Mode有几种以及作用6.runloop的事件源7. 讲一下source0和source18. runloop的六种观察者模式9. 针对定时器在滑动时停止工作的问题10. 如何解…