《零基础入门学习Python》第053讲:论一只爬虫的自我修养

0. 请写下这一节课你学习到的内容:格式不限,回忆并复述是加强记忆的好方式!

马上我们的教学就要进入最后一个章节,Pygame 嗨爆引爆全场,但由于发生了一个小插曲,所以这里决定追加一个章节,因为有人反应说:“你上一节课教我们去查找文档,教我们如何从官方文档中找到需要的答案,但是我发现知易行难也,希望举一个详细点的例子,教我们如何去查找。”

所以这里我们详细的深刻的讲一下网络爬虫。所以就有了本章节,论一只爬虫的自我修养。

首先,我们需要理解,什么是网络爬虫,如图:

网络爬虫又称为网络蜘蛛(Spider),如果你把整个互联网想象为一个蜘蛛网的构造,每个网站或域名都是一个节点,那我们这只蜘蛛就是在上面爬来爬去,在不同的网页上爬来爬去,顺便获得我们需要的资源,抓取最有用的。做过网站的朋友一定很熟悉,我们之所以能够通过百度、谷歌这样的搜索引擎检索到你的网页,靠的就是他们每天派出大量的蜘蛛在互联网上爬来爬去,对网页中的每个关键字建立索引,然后建立索引数据库,经过了复杂的排序算法之后,这些结果将按照搜索关键词的相关度的高低展现在我们的眼前。那当然,现在让你编写一个搜索引擎是一件非常苦难的、不可能完成的事情,但是有一句老话说的好啊:千里之行,始于足下。我们先从编写一段小爬虫代码开始,然后不断地来改进它,要使用Python编写爬虫代码,我们要解决的第一个问题是:

Python如何访问互联网?

好在Python为此准备好了电池,Python为此准备的电池叫做:urllib

urllib 事实上是由两个单词组成的:URL(就是我们平时说的网页地址) 和 lib(就是library的意思,就是首页)。

•URL的一般格式为(带方括号[]的为可选项):

protocol :// hostname[:port] / path / [;parameters][?query]#fragment

•URL由三部分组成:

–第一部分是协议(protocol):http,https,ftp,file,ed2k…

–第二部分是存放资源的服务器的域名系统或IP地址(有时候要包含端口号,各种传输协议都有默认的端口号,如http的默认端口为80)。

–第三部分是资源的具体地址,如目录或文件名等。

那好,说完URL,我们现在可以来谈一下 urllib 这个模块了,Python 3 其实对这个模块进行了挺大的改动,以前有urllib和urllib2 两个模块,Python3 干脆把它们合并在了一起并做了统一。其实 urllib 并不是一个模块,而是一个包。我们来查一下文档就知道了(我们说过,有问题,找文档。)

urllib 其实是一个包,其中包含4个模块,request 、error、parse 和 robotparser,我们主要会来讲解 request 这个模块,这个模块也是最复杂的,因为它包含了对服务器的请求和发出、跳转、代理、安全等几大方面。

我们点进去会发现文档非常长,从头看到尾是不可能的,这时候怎么办呢?建议百度、谷歌,查询 urllib.request 的用法,或者查询 Python3 如何访问网页,也可以得到想要的结果。你会得到,使用 urlopen() 这个函数。

urlopen() 函数除了第一个参数 url 是必需的外,后面的都有默认参数和可选参数,文档告诉我们,url 可以是一个字符串或者 Request object。Request object 是什么,我们下节课讲解。我们猜测 url 为一个字符串是应该就是域名地址的字符串,我们先来尝个鲜:(之所以选择https://ilovefishc.com这个网页,是因为这个网页的源代码量较少,其他的网站会直接把IELD搞崩溃,不信你可以试试 https://www.baidu.com。)

 
  1. >>> import urllib.request

  2. >>> response = urllib.request.urlopen("https://ilovefishc.com")

  3. >>> html = response.read()

  4. >>> print(html)

  5. b'<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <meta name="keywords" content="\xe9\xb1\xbcC\xe5\xb7\xa5\xe4\xbd\x9c\xe5\xae\xa4|\xe5\x85\x8d\xe8\xb4\xb9\xe7\xbc\x96\xe7\xa8\x8b\xe8\xa7\x86\xe9\xa2\x91\xe6\x95\x99\xe5\xad\xa6|Python\xe6\x95\x99\xe5\xad\xa6|Web\xe5\xbc\x80\xe5\x8f\x91\xe6\x95\x99\xe5\xad\xa6|\xe5\x85\xa8\xe6\xa0\x88\xe5\xbc\x80\xe5\x8f\x91\xe6\x95\x99\xe5\xad\xa6|C\xe8\xaf\xad\xe8\xa8\x80\xe6\x95\x99\xe5\xad\xa6|\xe6\xb1\x87\xe7\xbc\x96\xe6\x95\x99\xe5\xad\xa6|Win32\xe5\xbc\x80\xe5\x8f\x91|\xe5\x8a\xa0\xe5\xaf\x86\xe4\xb8\x8e\xe8\xa7\xa3\xe5\xaf\x86|Linux\xe6\x95\x99\xe5\xad\xa6">\n <meta name="description" content="\xe9\xb1\xbcC\xe5\xb7\xa5\xe4\xbd\x9c\xe5\xae\xa4\xe4\xb8\xba\xe5\xa4\xa7\xe5\xae\xb6\xe6\x8f\x90\xe4\xbe\x9b\xe6\x9c\x80\xe6\x9c\x89\xe8\xb6\xa3\xe7\x9a\x84\xe7\xbc\x96\xe7\xa8\x8b\xe8\xa7\x86\xe9\xa2\x91\xe6\x95\x99\xe5\xad\xa6\xe3\x80\x82">\n <meta name="author" content="\xe9\xb1\xbcC\xe5\xb7\xa5\xe4\xbd\x9c\xe5\xae\xa4">\n <title>\xe9\xb1\xbcC\xe5\xb7\xa5\xe4\xbd\x9c\xe5\xae\xa4-\xe5\x85\x8d\xe8\xb4\xb9\xe7\xbc\x96\xe7\xa8\x8b\xe8\xa7\x86\xe9\xa2\x91\xe6\x95\x99\xe5\xad\xa6|Python\xe6\x95\x99\xe5\xad\xa6|Web\xe5\xbc\x80\xe5\x8f\x91\xe6\x95\x99\xe5\xad\xa6|\xe5\x85\xa8\xe6\xa0\x88\xe5\xbc\x80\xe5\x8f\x91\xe6\x95\x99\xe5\xad\xa6|C\xe8\xaf\xad\xe8\xa8\x80\xe6\x95\x99\xe5\xad\xa6|\xe6\xb1\x87\xe7\xbc\x96\xe6\x95\x99\xe5\xad\xa6|Win32\xe5\xbc\x80\xe5\x8f\x91|\xe5\x8a\xa0\xe5\xaf\x86\xe4\xb8\x8e\xe8\xa7\xa3\xe5\xaf\x86|Linux\xe6\x95\x99\xe5\xad\xa6</title>\n <link rel="shortcut icon" type="image/x-icon" href="img/favicon.ico">\n <link rel="stylesheet" href="css/styles.css">\n <script src="js/jq.js"></script>\n <script src="https://cdn.bootcss.com/timelinejs/2.36.0/js/storyjs-embed.js"></script>\n <script src="https://cdnjs.cloudflare.com/ajax/libs/timelinejs/2.36.0/js/storyjs-embed.js" defer></script>\n <!-- <script src="https://fishc.oss-cn-hangzhou.aliyuncs.com/Web/js/embed.js"></script> -->\n <script>\n $(document).ready(function() {\n var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;\n\n createStoryJS({\n type: \'timeline\',\n width: \'auto\',\n height: windowHeight,\n source: \'data.json\',\n start_at_end:true, //OPTIONAL START AT LATEST DATE\n embed_id: \'my-timeline\'\n });\n\n });\n </script>\n <!-- END TimelineJS -->\n</head>\n<body>\n<div id="my-timeline"></div>\n</body>\n</html>\n'

得到的字符串是一个以 b 开头(二进制)字符串。得到的字符串似乎和我们所理解的网页代码不一样,但是我们又看到了很熟悉的身影(例如:div,link rel等),但是在这个网页,如果右键审查元素

我们会发现网页的代码很整齐,那这是怎么回事呢?为什么Python这里高的一团糟,我们刚才说了,Python这里直接得到的是byte类型(二进制编码),所以我们可以对它进行解码操作,我们先来看一下这个网页的编码方式是:UTF-8。

 
  1. >>> html = html.decode("utf-8")

  2. >>> print(html)

  3. <!DOCTYPE html>

  4. <html lang="en">

  5. <head>

  6. <meta charset="UTF-8">

  7. <meta name="viewport" content="width=device-width, initial-scale=1.0">

  8. <meta name="keywords" content="鱼C工作室|免费编程视频教学|Python教学|Web开发教学|全栈开发教学|C语言教学|汇编教学|Win32开发|加密与解密|Linux教学">

  9. <meta name="description" content="鱼C工作室为大家提供最有趣的编程视频教学。">

  10. <meta name="author" content="鱼C工作室">

  11. <title>鱼C工作室-免费编程视频教学|Python教学|Web开发教学|全栈开发教学|C语言教学|汇编教学|Win32开发|加密与解密|Linux教学</title>

  12. <link rel="shortcut icon" type="image/x-icon" href="img/favicon.ico">

  13. <link rel="stylesheet" href="css/styles.css">

  14. <script src="js/jq.js"></script>

  15. <script src="https://cdn.bootcss.com/timelinejs/2.36.0/js/storyjs-embed.js"></script>

  16. <script src="https://cdnjs.cloudflare.com/ajax/libs/timelinejs/2.36.0/js/storyjs-embed.js" defer></script>

  17. <!-- <script src="https://fishc.oss-cn-hangzhou.aliyuncs.com/Web/js/embed.js"></script> -->

  18. <script>

  19. $(document).ready(function() {

  20. var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;

  21. createStoryJS({

  22. type: 'timeline',

  23. width: 'auto',

  24. height: windowHeight,

  25. source: 'data.json',

  26. start_at_end:true, //OPTIONAL START AT LATEST DATE

  27. embed_id: 'my-timeline'

  28. });

  29. });

  30. </script>

  31. <!-- END TimelineJS -->

  32. </head>

  33. <body>

  34. <div id="my-timeline"></div>

  35. </body>

  36. </html>


测试题

0. 请问 URL 是“统一资源标识符”还是“统一资源定位符”?

答:往后的学习你可能会经常接触 URL 和 URI,为了防止你突然懵倒,所以在这里给大家简单普及下。URI 是统一资源标识符(Universal Resource Identifier),URL 是统一资源定位符(Universal Resource Locator)。用一句话概括它们的区别:URI 是用字符串来标识某一互联网资源,而 URL 则是表示资源的地址(我们说某个网站的网址就是 URL),因此 URI 属于父类,而 URL 属于 URI 的子类。

1. 什么是爬虫?

答:爬虫事实上就是一个程序,用于沿着互联网结点爬行,不断访问不同的网站,以便获取它所需要的资源。

2. 设想一下,如果你是负责开发百度蜘蛛的攻城狮,你在设计爬虫时应该特别注意什么问题?

答:不要重复爬取同一个 URL 的内容。假设你没做这方面的预防,如果一个 URL 的内容中包含该 URL 本身,那么就会陷入无限递归。

3. 设想一下,如果你是网站的开发者,你应该如何禁止百度爬虫访问你网站中的敏感内容?

(课堂上没讲,可以自行百度答案)

答:在网站的根目录下创建并编辑 robots.txt 文件,用于表明您不希望搜索引擎抓取工具访问您网站上的哪些内容。此文件使用的是 Robots 排除标准,该标准是一项协议,所有正规搜索引擎的蜘蛛均会遵循该协议爬取。既然是协议,那就是需要大家自觉尊重,所以该协议一般对非法爬虫无效。

4. urllib.request.urlopen() 返回的是什么类型的数据?

答:返回的是一个HTTPResponse的实例对象,它属于http.client模块。

 
  1. >>> response = urllib.request.urlopen("http://www.fishc.com")

  2. >>> type(response)

  3. <class 'http.client.HTTPResponse'>

调用其read()方法才能读出URL的内容。

5. 如果访问的网址不存在,会产生哪类异常?

(虽然课堂没讲过,但你可以动手试试)

答:HTTPError

6. 鱼C工作室(https://ilovefishc.com)的主页采用什么编码传输的?

答:UTF-8 编码。

一般网页通过点击审查元素,在 <head> 标签中的 charset 会显示采用了哪种编码。

7. 为了解决 ASCII 编码的不足,什么编码应运而生?

答:Unicode 编码。扩展阅读关于编码的那篇文章太长了,有鱼油说太生涩难懂,对于对编码问题还一头雾水的鱼油请看 -> 什么是编码?


动动手

0. 下载鱼C工作室首页(https://ilovefishc.com),并打印前三百个字节。

代码清单:

 
  1. >>> import urllib.request

  2. >>> response = urllib.request.urlopen('http://www.fishc.com')

  3. >>> print(response.read(300))

  4. b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\r\n\t"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r\n\r\n<!-- \r\n(c) 2011 \xc4\xbdubom\xc3\xadr Krupa, CC BY-ND 3.0\r\n -->\t\r\n\r\n<html xmlns="http://www.w3.org/1999/xhtml">\r\n\t<head>\r\n\t\t<meta http-equiv="content-type" content="text/html; charset=utf-8" />\r\n\t\t'

1. 写一个程序,检测指定 URL 的编码。

演示:

提示:

提供个“电池”给你用 -> 一次性解决你所有的编码检测问题

代码清单:

 
  1. import urllib.request

  2. import chardet

  3. def main():

  4. url = input("请输入URL:")

  5. response = urllib.request.urlopen(url)

  6. html = response.read()

  7. # 识别网页编码

  8. encode = chardet.detect(html)['encoding']

  9. if encode == 'GB2312':

  10. encode = 'GBK'

  11. print("该网页使用的编码是:%s" % encode)

  12. if __name__ == "__main__":

  13. main()

2. 写一个程序,依次访问文件中指定的站点,并将每个站点返回的内容依次存放到不同的文件中。

演示:

urls.txt 文件存放需要访问的 ULR:

执行你写的程序(test.py),依次访问指定的 URL 并将其内容存放为一个新的文件:

代码清单:

 
  1. import urllib.request

  2. import chardet

  3. def main():

  4. i = 0

  5. with open("urls.txt", "r") as f:

  6. # 读取待访问的网址

  7. # 由于urls.txt每一行一个URL

  8. # 所以按换行符'\n'分割

  9. urls = f.read().splitlines()

  10. for each_url in urls:

  11. response = urllib.request.urlopen(each_url)

  12. html = response.read()

  13. # 识别网页编码

  14. encode = chardet.detect(html)['encoding']

  15. if encode == 'GB2312':

  16. encode = 'GBK'

  17. i += 1

  18. filename = "url_%d.txt" % i

  19. with open(filename, "w", encoding=encode) as each_file:

  20. each_file.write(html.decode(encode, "ignore"))

  21. if __name__ == "__main__":

  22. main()

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

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

相关文章

Qt Core学习日记——第四天QMetaEnum(下)

类定义&#xff1a; 成员变量就只有QMetaObject *mobj和uint handle&#xff0c;handle同样用于计算在qt_meta_stringdata_XTest的位置 成员函数&#xff1a; 接下以test类进行函数讲解 test.h #pragma once #include <qobject.h> #include <QFlags> class X…

有些能力,是工作中学不来的,看看这篇超过90%同行

俗话说:360行&#xff0c;行行转IT。 在就业形势压力巨大的今天&#xff0c;不仅仅是计算机专业的毕业生&#xff0c;很多其他专业的大学生都选择转行从事计算机行业。 尤其是软件测试行业&#xff0c;远远超出其他行业的薪水和广阔的就业前景&#xff0c;吸引了大批应届毕业…

QT DAY1

1.思维导体 2.作业 #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {qDebug()<<this->size();qDebug()<<this->rect().size();qDebug()<<this->geometry().size();qDebug()<<this->frameGeometry().siz…

视频增强技术-对比度增强

在图像处理中&#xff0c;由于获取的图像质量不好&#xff0c;需要通过对比度增强来提升图片质量&#xff0c;主要解决的是由于图像灰度级范围较小造成的对比度较低的问题&#xff0c;作用是使图像的灰度级范围放大&#xff0c;从而让图像更加清晰。主要对比度增强方法包括线性…

macbook 软件iMovie for Mac(专业视频剪辑工具)中文版

iMovie mac中文版是一款针对Mac平台量身定做的视频编辑工具&#xff0c;软件凭借流线型设计和直观的编辑功能&#xff0c;可以让您感受前所未有的方式制作好莱坞风格的预告片和精美电影&#xff0c;并且还可以浏览视频资料库&#xff0c;快速共享挚爱瞬间&#xff0c;创建精美的…

DevOps自动化平台开发之 Shell脚本执行的封装

基础知识 基于如下技术栈开发DevOps平台 Spring Boot Shell Ansible Git Gitlab Docker K8S Vue 1、spring boot starter的封装使用 2、Shell脚本的编写 3、Ansible 脚本的编写 4、Docker 的使用与封装设计 本篇介绍如何使用Java封装Linux命令和Shell脚本的使用 将其设计成…

文件上传漏洞

什么是文件上传漏洞&#xff1f; 攻击者上传了一个可执行文件如木马&#xff0c;病毒&#xff0c;恶意脚本&#xff0c;WebShell等到服务器执行&#xff0c;并最终获得网站控制权限的高危漏洞。 webshell 非法用户可利用上传的恶意脚本文件控制整个网站&#xff0c;甚至控制服…

直线导轨的主要功能

直线导轨是一种常见的机械结构&#xff0c;用于工业机器人、数控机床和其他自动化装置中。它的作用是提供一个准确的直线运动轨道&#xff0c;使得设备能够在预定的路径上进行精确的移动。 直线导轨作为一种重要的机械基础件&#xff0c;在现代工业中得到了广泛的应用。它主要的…

min_free_kbytes

转自&#xff1a;技术分享 | MemAvailable 是怎么计算的-腾讯云开发者社区-腾讯云 背景 前两天安装 OceanBase 时遇到一个小问题&#xff1a; 很明显&#xff0c;安装OB时要求服务器可用内存至少 8G&#xff0c;不达标就无法安装。为了凑这3台10G内存的服务器我已经费了不少劲…

Yunfly 一款高效、性能优异的node.js企业级web框架

介绍 Yunfly 一款高性能 Node.js WEB 框架, 使用 Typescript 构建我们的应用。 使用 Koa2 做为 HTTP 底层框架, 使用 routing-controllers 、 typedi 来高效构建我们的 Node 应用。 Yunfly 在 Koa 框架之上提升了一个抽象级别, 但仍然支持 Koa 中间件。在此基础之上, 提供了一…

【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群功能分析)

探究Redis服务启动的过程机制的技术原理和流程分析的指南&#xff08;集群功能分析&#xff09; Redis集群的出现背景提升性能扩展性 Redis集群概述Redis Cluster特性分布Redis Cluster的Failover机制Redis集群节点宕机集群如何判断节点是否挂掉集群进入失败状态的必要条件 Fai…

jmeter随记2:压测

jmeter随记1:压测 简述一、压测步骤二、观察cpu和内存占用情况三、查看磁盘占用情况 简述 关于压测&#xff0c;jmeter更直观的作用是用来编写压测脚本【请求和压测策略】&#xff0c;然后在linux服务器上执行&#xff0c;也可以在本地执行&#xff0c;压测执行脚本在启动jmet…

Linux:入门学习知识及常见指令

文章目录 入门介绍操作系统的概念Linux机器的使用Linux上的指令 对文件知识的补充文件的定义和一些含义文件和目录的存储绝对路径和相对路径 ls指令pwd指令cd指令touch指令mkdir指令rmdir指令rm指令man指令cp指令mv指令cat指令more指令echo指令输出重定向 less指令find指令grep…

5、joern安装

文章目录 一、安装环境二、安装步骤1、joern地址2、安装中可能出现的问题 一、安装环境 1. java 8   2. gradle 2.0.0(按照官网步骤安装)   3. Graphviz (sudo apt install graphviz-dev)   4. python > 3.5 二、安装步骤 1、joern地址 joern地址 2、安装中可能出…

Docker配置阿里云容器镜像加速

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

白话机器学习笔记(三)评估已建立的模型

模型评估 在进行回归和分类时&#xff0c;为了进行预测&#xff0c;我们定义了函数 f θ ( x ) f_\theta(x) fθ​(x)&#xff0c;然后根据训练数据求出了函数的参数 θ \theta θ。 如何预测函数 f θ ( x ) f_\theta(x) fθ​(x)的精度&#xff1f;看它能否很好的拟合训练数…

【玩转Linux】标准io缓冲区的操作

(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误&#x…

[Golang] Viper原理以及详细使用案例

文章目录 什么是 Viper&#xff1f;基础配置引入依赖&#xff1a;动态监听原理分析&#xff1a;监听原理分析 Config.yaml文件配置Viper文件配置 什么是 Viper&#xff1f; 介绍&#xff1a;用于处理配置文件中解析和读取配置文件 优点&#xff1a;支持多种配置格式&#xff0…

新老联手,火花四溅?大众汽车与小鹏汽车达成长期合作框架协议

7 月 26 日资讯&#xff0c;大众汽车宣布与小鹏汽车达成长期合作框架协议&#xff0c;并在官网中正式宣布&#xff0c;大众是老牌油车领军代表&#xff0c;小鹏则是新势力中的佼佼者&#xff0c;新老强强联手&#xff0c;又会碰撞出怎样的火花呢&#xff1f; 现阶段大众计划与…

Postman学习之常用断言

什么是断言&#xff1f; 断言——就是结果中的特定属性或值与预期做对比&#xff0c;如果一致&#xff0c;则用例通过&#xff0c;如果不一致&#xff0c;断言失败&#xff0c;用例失败。断言&#xff0c;是一个完整测试用例所不可或缺的一部分&#xff0c;没有断言的测试用例…