快乐学Python,数据分析之使用爬虫获取网页内容

在上一篇文章中,我们了解了爬虫的原理以及要实现爬虫的三个主要步骤:下载网页-分析网页-保存数据。

下面,我们就来看一下:如何使用Python下载网页。

1、网页是什么?

浏览器画网页的流程,是浏览器将用户输入的网址告诉网站的服务器,然后网站的服务器将网址对应的网页返回给浏览器,由浏览器将网页画出来。

这里所说的网页,一般都是一个后缀名为 html 的文件。

网页文件和我们平时打交道的文件没什么不同,平时我们知道 Word 文件,后缀名为 .doc, 通过 Word 可以打开。图片文件后缀名为 .jpg,通过 Photoshop 可以打开;而网页则是后缀名为 .html,通过浏览器可以打开的文件。

网页文件本质也是一种文本文件,为了能够让文字和图片呈现各种各样不同的样式,网页文件通过一种叫作 HTML 语法的标记规则对原始文本进行了标记。

(1)手动下载网页

我们以煎蛋网为例体会一下网页的实质,使用浏览器打开这个链接http://jandan.net/可以看到如下界面。可以看到,第一条新闻的标题前缀是:今日好价。网页内容可能会随时间变化,这里你只需要注意第一条新闻的前几个字(暗号)即可,下同。


在空白区域点击右键,另存为,并在保存类型中选择:仅 HTML。

接下来回到桌面,可以看到网页已经被保存到桌面了,后缀名是 html,这个就是我们所说的网页文件。

(2)网页内容初探

我们右键刚下载的文件,选择用 VS Code 打开,打开后的文件内容如下图所示。


这就是网页文件的实际内容(未被浏览器画出来之前)。现在先不用管看不懂的代码,还记得我们看到的第一条新闻吗?“今日好价………………”。(你的暗号)

我们在 VS Code 中通过 CTRL + F 调出搜索面板,搜索“今日好价”(暗号)。可以看到成功找到了这条新闻,虽然被很多不认识的代码包围,但这也可以确定,我们看到的煎蛋网的主页确实就是这个 html 文件。

2、如何实现下载普通网页?

Python 以系统类的形式提供了下载网页的功能,放在 urllib3 这个模块中。这里面有比较多的类,我们并不需要逐一都用一遍,只需要记住主要的用法即可。

(1)获取网页内容

还是以煎蛋网为例。在我们打开这个网页的时候,排在第一的新闻是:“天文学家首次见证黑洞诞生”。

煎蛋又更新了新的新闻,你记住你当时的第一条新闻题目即可。我们待会儿会在我们下载的网页中搜索这个标题来验证我们下载的正确性。

下面开始,打开vscode,输入如下代码:

# 导入 urllib3 模块的所有类与对象import urllib3# 将要下载的网址保存在 url 变量中,英文一般用 url 表示网址的意思url = "http://jandan.net/p/date/2021/03/23"# 创建一个 PoolManager 对象,命名为 httphttp = urllib3.PoolManager()# 调用 http 对象的 request 方法,第一个参数传一个字符串 "GET"# 第二个参数则是要下载的网址,也就是我们的 url 变量# request 方法会返回一个 HTTPResponse 类的对象,我们命名为 responseresponse = http.request("GET", url)# 获取 response 对象的 data 属性,存储在变量 response_data 中response_data = response.data# 调用 response_data 对象的 decode 方法,获得网页的内容,存储在 html_content # 变量中html_content = response_data.decode()# 打印 html_contentprint(html_content)

上述代码就完成了一个完成的网页下载的功能。其中有几个额外要注意的点:

  • 我们创建 PoolManager的时候,写的是 urllib3.PoolManager,这里是因为我们导入了 urllib3 的所有类与函数。所以在调用这个模块的所有函数和类的前面都需要加模块名,并用点符号连接。
  • response 对象的 data 属性也是一个对象,是一个 bytes 类型的对象。通过调用 decode 方法,可以转化成我们熟悉的字符串。

执行上述代码,可以看到打印出了非常多的内容,而且很像我们第一部分手动保存的网页,这说明目前 html_content 变量中保存的就是我们要下载的网页内容。

(2)将网页保存到文件

现在 html_content 已经是我们想要的网页内容,对于完成下载只差最后一步,就是将其保存成文件。其实这一步已经和保存网页无关的,而是我们如何把一个字符串保存成一个文件。

Python 中,读取文件和保存文件都是通过文件对象来完成的。接下来,我们通过实际的例子来了解这个技术。

新建 Cell,输入以下代码:

# 调用 open 函数,三个参数都是字符串类型,第一个参数为要操作的文件名# 第二个参数代表模式,w 表示写入文件,r 表示读取文件# 第三个参数表示编码格式,一般有中文的认准 utf-8 就好# open 函数返回一个文件对象,我们存储在 fo 变量中fo = open("jiandan.html","w", encoding="utf-8")# 调用文件对象的 write 方法,将我们上面存储着网页内容的字符春变量,html_content # 作为参数fo.write(html_content)# 关闭文件对象fo.close()

执行完上述代码后,可以在 VS Code 的左侧边栏中看到,文件夹下多了一个 jiandan.html 的文件,这个就是我们用刚才 Python 代码保存的文件。

打开就可以看到熟悉的网页内容了。

(3)让我们的代码更加通用

刚才我们在两个 cell 中分别实现了将网页保存成一个字符串,以及将字符串保存为一个文件。如果我们要抓取新的网页,要么直接修改之前的代码,要么就需要拷贝一份代码出来。

这两种方式都不是很好,基于我们之前了解的内容,对于有一定通用度的代码我们可以将其改写为函数,来方便后续使用。

改写之后的代码如下:

# 第一个函数,用来下载网页,返回网页内容# 参数 url 代表所要下载的网页网址。# 整体代码和之前类似def download_content(url):http = urllib3.PoolManager()response = http.request("GET", url)response_data = response.datahtml_content = response_data.decode()return html_content# 第二个函数,将字符串内容保存到文件中# 第一个参数为所要保存的文件名,第二个参数为要保存的字符串内容的变量def save_to_file(filename, content):fo = open(filename,"w", encoding="utf-8")fo.write(content)fo.close()url = "http://jandan.net/"# 调用 download_content 函数,传入 url,并将返回值存储在html_content # 变量中html_content = download_content(url)# 调用 save_to_file 函数,文件名指定为 jiandan.html, 然后将上一步获得的# html_content 变量作为第二个参数传入save_to_file("jiandan.html", html_content)

这样改写之后,我们在抓取新的网页的时候就可以使用 download_content 函数和 save_to_file 函数快速完成了,不再需要去写里面复杂的实现。

3、如何实现动态网页下载?

urllib3 很强大,但是却不能一劳永逸地解决网页下载问题。对于煎蛋这类普通网页,urllib3 可以表现更好,但是有一种类型的网页,它的数据是动态加载的,就是先出现网页,然后延迟加载的数据,那 urllib3 可能就有点力不从心了。

我们以豆瓣的电视剧网页为例:

现在,我们来使用刚才定义的两个函数来下载一下这个网页。

url = "https://movie.douban.com/tv"html_content = download_content(url)save_to_file("douban_tv.html", html_content)

代码很简单,就是把豆瓣电视剧的网页下载到 douban_tv.html 这个文件中。执行代码,可以在 VS Code 左边的文件夹视图中看到成功生成了douban_tv.html 这个文件,这说明网页已经下载成功。

现在我们在 VS Code 中打开这个网页,搜索上图中出现的电视剧:“山河令”。这次却神奇的搜不到了,事实上,你会发现我们在网页看到的电视剧名字都搜不到。

为什么我们明明下载到了网页但是却搜不到电视剧呢?造成这个现象的原因是豆瓣电视剧网页中的电视剧列表的部分是动态加载的,所以我们用 urllib3 去直接下载,只能下载到一个壳网页,没有里面的列表内容。这种网页内部的数据是动态加载的网页,我们统一称之为动态网页。

动态网页应该怎么抓取呢?回过头去想,一个网页不管再怎么动态,最终都是要展示给用户看的,所以浏览器应该是最知道网页内容是什么的角色。如果我们可以使用代码控制浏览器来帮我们下载网页,应该就可以解决动态网页的抓取问题。

接下来我们就介绍使用 Python 来控制浏览器的利器:selenium。

(1)安装selenium

selenium 不属于 Python 的系统库,所以要使用这个库需要先进行安装。

我们安装 Python 的库一般通过 Anaconda 的命令行。既然是模拟浏览器,我们的电脑首先要先有浏览器。这里我们以 Chrome 为例。所以在一切开始之前,你需要确保你电脑上安装了 Chrome。

在准备环节,我们已经安装了 Anaconda 套件,现在我们去开始菜单(或者在桌面状态下按 Win 键)找到 Anaconda 3 文件夹,并点击文件夹中的 Anaconda Prompt 程序。Mac 用终端即可。

打开后会出现一个命令行窗口,在这个命令行,我们可以输入 conda install xxx 来安装 Python 的扩展库。

比如在这个例子中,我们输入 conda install selenium,回车。界面会变得如下所示,询问我们是否要确认安装,输入 y 继续回车就可以。

安装完毕后命令行窗口会回到待输入命令的状态,此时就可以关闭了。

回到 VS Code,新建 Cell,输入以下的测试代码:

# 从 selenium 库中导入 webdriver 类from selenium import webdriver# 创建一个 Chrome 浏览器的对象brow = webdriver.Chrome()# 使用 Chrome 对象打开 url(就是刚才豆瓣电视剧的 url)brow.get(url)

运行代码,会自动打开一个 Chrome 浏览器的窗口,并展示 url 对应的网页。同时还会有一个提示,说明这个浏览器窗口是在被程序控制的,如下图所示。


如果代码运行出错,提示找不到 chromedriver。那说明你安装的 selenium 版本缺少 chromedriver, 可以按如下方式操作:

  • 重新按照刚才的方法打开 Anaconda Prompt,输入 pip install --upgrade --force-reinstall chromedriver-binary-auto 回车执行安装。
  • 在上面的代码增加一行 import chromedriver_binary 添加完毕后如下所示。
# 从 selenium 库中导入 webdriver 类from selenium import webdriver# 导入 chromedriverimport chromedriver_binary# 创建一个 Chrome 浏览器的对象brow = webdriver.Chrome()# 使用 Chrome 对象打开 url(就是刚才豆瓣电视剧的 url)brow.get(url)

(2)使用selenium下载动态网页

如果刚才的代码已经运行成功并打开了 Chrome 的界面的话,那我们离最后的下载动态网页已经不远了。在我们通过 Chrome 对象打开了一个网页之后,只需要访问 Chrome 对象的 page_source 属性即可拿到网页的内容。

代码如下:

# 从 selenium 库中导入 webdriver 类from selenium import webdriver# 创建一个 Chrome 浏览器的对象brow = webdriver.Chrome()# 使用 Chrome 对象打开 url(就是刚才豆瓣电视剧的 url)brow.get(url)# 访问 Chrome 对象的 page_source 属性,并存储在 html_content 变量中html_content = brow.page_source# 调用我们之前定义的 save_to_file 函数,这次我们保存为 double_tv1.html# 要保存的内容就是 html_contentsave_to_file("douban_tv1.html", html_content)

运行代码,可以看到 Chrome 被打开并加载网页,等电视剧列表都加载完之后,在 VS Code 中可以看到 double_tv1.html 也被成功创建。

这个时候我们去这个文件搜索山河令,发现已经有结果了,在这个 html 文件中已经有了所有电视剧的信息。

至此,我们也实现了对于动态内容网页的下载功能。

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

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

相关文章

JDBC事务

1.事务 数据库事务是一组数据库操作,它们被视为一个单一的逻辑工作单元,要么全部成功执行,要么全部回滚(撤销)到事务开始前的状态。事务是确保数据库数据一致性、完整性和可靠性的关键机制之一。 简单来说&#xff0…

Python代码调试的几种方法总结

使用 pdb 进行调试 pdb 是 python 自带的一个包,为 python 程序提供了一种交互的源代码调试功能,主要特性包括设置断点、单步调试、进入函数调试、查看当前代码、查看栈片段、动态改变变量的值等。pdb 提供了一些常用的调试命令,详情见表 1。…

互联网加竞赛 基于机器视觉的12306验证码识别

文章目录 0 简介1 数据收集2 识别过程3 网络构建4 数据读取5 模型训练6 加入Dropout层7 数据增强8 迁移学习9 结果9 最后 0 简介 🔥 优质竞赛项目系列,今天要分享的是 基于机器视觉的12306验证码识别 该项目较为新颖,适合作为竞赛课题方向…

6.1810: Operating System Engineering 2023 <Lab7 lock: Parallelism/locking>

一、本节任务 二、要点 2.1 文件系统(file system) xv6 文件系统软件层次如下: 通过路径树我们可以找到相应的文件: fd(文件描述符)是进程用来标识其打开的文件的手段,每个进程有自己的文件…

从0开始学前端第二天

学习内容&#xff1a; css 行内样式表 页内样式表 外部样式表 同步修改所有某一类标签的内容&#xff1a;内部样式表 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" conte…

程序员有哪些接s单的渠道?

这题我会&#xff01;程序员接单的渠道那可太多了&#xff0c;想要接到合适的单子&#xff0c;筛选一个合适的平台很重要。如果你也在寻找一个合适的接单渠道&#xff0c;可以参考以下这些方向。 首先&#xff0c;程序员要对接单有一个基本的概念&#xff1a;接单渠道可以先粗…

Elasticsearch_8.11.4_kibana_8.11.4_metricbeat_8.11.4安装及本地部署_ELK日志部署

文章目录 Elasticsearch_8.11.4_kibana_8.11.4_metricbeat_8.11.4安装及本地部署_ELK日志部署分布式引擎Elasticsearch_8.11.4安装及本地部署系统环境要求1 Windows 安装 Elasticsearch下载完成后进行解压,进入 bin 目录,找到elasticsearch.bat脚本文件执行一键启动.启动都选允…

51单片机HC-SR04超声波测距lcd1602显示(程序+ad硬件设计+文档说明)

本帖主控使用STC89C52单片机&#xff0c;超声波测距采用HC-SR04模块&#xff0c;包含ad硬件设计和文档。 测距原理 超声波测距是通过不断检测超声波发射后遇到障碍物所反射的回波&#xff0c;从而测出发射和接收回波的时间差t,然后求出距SCt/2,式中的C为超声波波速。由于超声…

Golang 使用 AST 获取方法和参数名以及应用举例

背景 在做一些自动生成的代码工作时&#xff0c;有时需要知道方法以及对应的参数名 如果仅是方法&#xff0c;利用反射机制就可以解决 而参数名&#xff0c;程序编译后&#xff0c;已经丢失 可以通过 AST 事先获取方法的参数名 有了方法、参数名&#xff0c;加上反射&…

leetcode-83删除排序链表中的重复元素

题目链接 83. 删除排序链表中的重复元素 - 力扣&#xff08;LeetCode&#xff09; 解题代码 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def d…

环保时代下的品牌全球化之路:绿色供应链的战略洞察

随着全球化的深入和消费者对可持续发展和环保的日益关注&#xff0c;品牌出海不仅需要考虑市场扩张和竞争力提升&#xff0c;还需要认真思考如何在全球供应链中构建绿色可持续的供应链体系。本文Nox聚星将和大家探讨品牌出海的绿色供应链建设&#xff0c;分析可持续发展和环保要…

系统学习Python——警告信息的控制模块warnings:常用函数-[warnings.formatwarning]

分类目录&#xff1a;《系统学习Python》总目录 函数 warnings.formatwarning(message, category, filename, lineno, lineNone)以标准方式格式化一条警告信息。将返回一个字符串&#xff0c;可能包含内嵌的换行符&#xff0c;并以换行符结束。如果未提供line&#xff0c;form…

机器学习扩散模型简介

一、说明 扩散模型的迅速崛起是过去几年机器学习领域最大的发展之一。在这本易于理解的指南中了解您需要了解的有关扩散模型的所有信息。 扩散模型是生成模型&#xff0c;在过去几年中越来越受欢迎&#xff0c;这是有充分理由的。仅在 2020 年代发布的几篇开创性论文就向世界…

MySQL系列之数据导入导出

前言 大数据与云计算作为当今时代&#xff0c;数据要素发展的“动力引擎”&#xff0c;已经走进了社会生活的方方方面。而背后承载的云服务或数据服务的高效运转&#xff0c;起了决定作用。 作为数据存储的重要工具&#xff0c;数据库的品类和特性也日新月异。从树型、网络型…

MySQL/Oracle 的 字符串拼接

目录 MySQL、Oracle 的 字符串拼接1、MySQL 的字符串拼接1.1 CONCAT(str1,str2,...) : 可以拼接多个字符串1.2 CONCAT_WS(separator,str1,str2,...) : 指定分隔符拼接多个字符串1.3 GROUP_CONCAT(expr) : 聚合函数&#xff0c;用于将多行的值连接成一个字符串。 2、Oracle 的字…

python调试可以看到每个变量的值吗

Python在调试窗口查看变量的值 看来想鼠标移上去就看到变量值是不可能了吧。 边修改代码边实时查看变量值&#xff0c;热更新&#xff0c;热重载咋样&#xff1f; 在开发过程中&#xff0c;调试是一项非常重要的技能。当我们编写复杂的程序时&#xff0c;很容易出现bug或逻辑…

C#灵活控制多线程的状态(开始暂停继续取消)

ManualResetEvent类 ManualResetEvent是一个同步基元&#xff0c;用于在多线程环境中协调线程的执行。它提供了两种状态&#xff1a;终止状态和非终止状态。 在终止状态下&#xff0c;ManualResetEvent允许线程继续执行。而在非终止状态下&#xff0c;ManualResetEvent会阻塞线…

Python画球面投影图

天文学研究中&#xff0c;有时候需要画的并不是传统的XYZ坐标系&#xff0c;而是需要画一个形如这样子的球面投影图&#xff1a; 下面讲一下这种图怎么画 1. 首先要安装healpy包 pip install healpy 2. 然后导入包 如果之前安装过healpy&#xff0c;有的会提示不存在healpy…

【蓝桥杯日记】第一篇——如何搭建系统环境

目录 前言 环境相关文件 学生机环境-Web应用开发环境&#xff08;第十五届大赛&#xff09; 学生机环境-Java编程环境&#xff08;第十五届大赛&#xff09; 学生机环境-C/C编程环境&#xff08;第十五届大赛&#xff09; 学生机环境-Python编程环境 &#xff08;第十五届…

20240112让移远mini-PCIE接口的4G模块EC20在Firefly的AIO-3399J开发板的Android11下跑通【DTS部分】

20240112让移远mini-PCIE接口的4G模块EC20在Firefly的AIO-3399J开发板的Android11下跑通【DTS部分】 2024/1/12 16:20 https://blog.csdn.net/u010164190/article/details/79096345 [Android6.0][RK3399] PCIe 接口 4G模块 EC20 调试记录 https://blog.csdn.net/hnjztyx/artic…