热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python全套教程第八十八讲_手把手教你学python第十八讲(初识爬虫)

学习爬虫呢?我们首先要知道什么叫做爬虫,爬虫其实又叫做网页蜘蛛。互联网就是一个大的蜘蛛网,而网页蜘蛛在网上爬来爬去的行为就是我们不断阅读网

0ff2d030525a77f8aac8bd64e7c8ed9c.png

学习爬虫呢?我们首先要知道什么叫做爬虫,爬虫其实又叫做网页蜘蛛。互联网就是一个大的蜘蛛网,而网页蜘蛛在网上爬来爬去的行为就是我们不断阅读网页的行为。325ed4d211e9a935894f877be1bdef3a.png

那么下面就有问题了啊,我们以前完全没有讲过python如何访问互联网啊。python怎么访问互联网呢?就是通过下面的模块。99e5c773b9e33a4cd12bd21002e32370.png

urllib是url和lib(库)组成。先看一下urllib是个什么东西9306d18554327215df0cd824e4b87b4b.png

看到urllib是一个包,里面有五个模块。我们再实际去看一下c5dcc7fe8a0c25baf3df53e40215e3f4.png

然后我们来说一说URL是什么。知己知彼才能更好的应用爬虫嘛,参考了百度百科。

URL0f54c70f484a4b59ac215d74f2173b6b.png

f28128b3895c9431c1d99a0663c41924.png

cef60b66a430c68572641435a8b35999.png

百度百科是把后面两部分作为一部分。8ba322a5f1bef65d97f85e1fc0cd3989.png

1ff0f1fe4b6ae391ebaec9ee92f6dae8.png

下面参考了https://jingyan.baidu.com/article/2c8c281df0afd00008252aa7.html,我认为说的很详细,就直接拿过来了,不想自己在重新组织语言了,人的惰性所致。633ce0332c84d776234ac4c8f84ac7b4.png

我们先了解一下什么叫服务器4f5d7a9a463429289599accd6ef48d4b.png

我们上面说的都是WEB服务器,下面说的也是。其实服务器就是一台大型计算机嘛。1e0b398db5dcd6cf0b016739a3246808.png

d748ea3d6fead566a0ef4a5e6fc3e322.png

57fe5ad1afb3efb5875269db65175490.png

也就是说一个域名可以有不同的网站名,因为服务器可以不一样。c585c5e730fae1ba73b585e306b954d3.png

83cff75c1f847239b9c4c7385e5310d8.png

18b98317df576c3d921a73c9b4f88ca8.png

我来重复一遍,第一个是我们打进去的,第二个是电脑自动给我们加的,第三个是服务器自动加的根目录,前面我们在文件系统那里讲过根目录的概念。最后一个是根目录下默认的网页。3aab23b060db0f4e66abfba58cb14d85.png

前面的协议名字不同的网站可能会不一样,现在一般都是https,这样的没有弹窗啊,广告什么的。上面我是写了80端口,下面换一个81号端口试试,你问我什么叫做端口(port)?这个我还是知道的,毕竟学过微机原理,首先,计算机与外设通讯的电路叫做接口,端口就是接口里面的寄存器,通常有控制,状态,数据端口。你的计算机上有各种接口,典型的有USB接口,显卡接口,键盘接口等。计算机给每个端口都有一个二进制或者说十六进制的地址,多少位和你的地址总线宽度有关系哈。这里面还有一个独立编址还是统一编址的问题,不过你只需要知道一个端口有唯一的地址就够了。我就知道这些,我们也就到这就够了。534533e58fd2c8a440174f92df6c4601.png

如果你知道了服务器就是一台大型计算机,那么绝对URL和相对URL你就理解了,和绝对路径相对路径类似嘛。5152056705db547be820dacd9ea3491d.png

除了URL还有一个东西叫做URI,这些以后都会用到的,参考了https://www.zhihu.com/question/21950864b609f1fc84f8657f3886058b79322355.png

详细来说呢,我觉得知乎这位写得很形象,我就不献丑了。34d4561ee00032a5b192e08a191ce22b.png

4a10888e4cfc93e95c513420a29fe776.png

URI就是一种一一对应对应关系的某种标识符,这个可以有很多种,区别一个人,我们可以用,身份证号,手机号,QQ号,邮箱(一个人可以有多个手机号,同样的,一个网站可以有多个URL的,不过那样就太分散了,但是绝对不会有两个不同的网站有一样的URL),住址,等等。URL是什么呢?就是其中的一种类似于住址的定位符,比如说你住在哪个寝室几号床啊,有人可能会说,我和我爸睡在一个屋子里的一张床上,那这个显然是抬杠,不过这个例子确实不是很严谨,但是还是可以帮助我们理解的。2f07208b21e3c5689e2b1be443ecb357.png

稍微扩展一下知识84f4bdfbdc630e4fe5e4ab05eacbc874.png

有了以上知识,到实际中操作一下吧。如何打开一个网页?urllib包里的request模块有urlopen函数

爬虫初试fa2ef865b8c0c83de514329afbe93333.png

02eb48ca263962b43382f278fbfe77f0.png

这个阶段我们只用到了第一个参数URL。

试着来打开一个网页,比如流氓的百度0ec443fea15f4eca89fe06cb203b4f4c.png

6b0c2ff7c86baa48dda9a754860998ee.png

看来目前打开一个网页需要,把协议名和网站名都输进去,而且输端口号会报错,报错说是违反了协议,这个去到源文件应该是可以看到为什么报错的,这里我就不展示了,有兴趣自己可以根据报错内容,自己去相关的模块的源文件看一看。返回的是一个http.client模块的HTTPResponse对象。先简单了解一下http.client模块,参考了http://www.jb51.net/article/109852.htm。写的真的不错,我觉得这种可以直接拿来用的,我就不自己献丑写了。f76b180ad015c5d7ac355cd500d77659.png

c1fb81b38fb8418cf7da499f5a5e8db2.png

be7c904c50d86535519ff36beb9ce937.png

看到这个443端口是不是上面的报错就豁然开朗了呢?唉,原来是端口不对造成的嘛,当然如果你想深究的话,没有这么简单,你需去ssl.py的握手handshake这一行去找原因。ce1bb8c56f767ab855789ae67fb9afbd.png

还有a49fbbbe40855348d0c54a740e62a816.png

有兴趣的可以自己深入了解。其实理解起来很简单,就是不是默认端口访问不到呗。b9519c3220a122afdcde565454955153.png

并且在responses里我们 可以看到熟悉的404。d17cba0fb779ef91d9a28b67037d1365.png

4b40e545933c04d5a4cae5a4f939c44f.png

375230321d0e5c509e4f7c739503f407.png

a56e3004d8611c757f0c3f33ffbf39b8.png

8224b6e81624af69fd980efa04adc151.png

我们就偏要来试试实例化这个HTTPResponse类。

da61638289142cb9bf940f815e309d80.png

这个错误原因要究其根源就要扯太多了,不是仅仅缺了sock参数这么简单,而且要读很多行代码,费时间而且大家也不一定能读懂,所以大家自己有经验有耐心的时候再去读更好,读高手的代码也是进步的一个很重要的方法哦。下面我就只截取了和HTTPResponse有关的内容,其它的你们可以自己打开那个网站看,如果你有兴趣的话。其实这些以后都会讲到,只是现在还没到时候。

183e7996b272b49b53321802f2edba05.png

注意红箭头的read我们下面马上会用得到。2059fdeef5a364afe629422aaad829bc.png

这里就再科普几个知识吧。下面我都尽量选通俗的解释。先说一下什么叫做DNS7817f8bc431fec26eb226b299c4048ab.png

ce7ac309841c96fd334e71f4e08de076.png

179a86b9d155f7be65ffbdf145f58d2b.png

以下参考了https://blog.csdn.net/paranoidyang/article/details/54288370eb884ff4d7f4dc0b02942d34721b2e1a.png

DNS就是把域名转换为IP地址。

网关。88ca540c0c9dd41d226cd3bff6ab4fc6.png

子网掩码,参考了https://www.zhihu.com/question/56895036a2f9d3ce23018ae183c98a3175461a89.png

d6438e4ef649566bb987f2be063e4364.png

所以通过子网掩码我们可以推算出每个儿子内网的范围咯。回过来继续看。

对了这里还漏了一点内容,HTTPResponse返回的是一个二进制的对象,因为计算机只认识0,1在网络传输的过程中自然也必须只能传送二进制了。上面也说过read可以读取返回的HTTPResponse的内容,我们来试一试,读一个简单点的吧,就读取b站主页的前1000个字节吧,,不然会很长很长,15bd229b30fb4414a6516420ba271d0b.png

这读出来是二进制吗?你看到开头有个b,还有很多\x十六进制的数字。没错,这的确是二进制文件(虽然看着不全是二进制的数,还有一些拉丁字母和英文标点,下面会讲解为什么是这样的,实际上缺失的都是不能用ASCII码表示的字符)。这里就有必要详细了解编码的一些知识

编码[encode]和译码(解码)[decode]

参考了http://bbs.fishc.com/thread-66084-1-1.html和https://www.cnblogs.com/OldJack/p/6658779.html535ed2797eb76273400b37a147ed97ad.png

还有http://python.jobbole.com/86670/和https://www.cnblogs.com/vipchenwei/p/6993788.html8902a8430033f0a83095ce81b433c344.png

unicode就是universal code的意思。GBK就比较中式,叫国标扩展,接触过机械的都见过GB/什么什么的,那就是国标的首字母。e4e44c3f7b462e28799a7a542ad9ad3f.png

下面是更清晰地说明UTF-8是如何存储Unicode码的https://blog.csdn.net/hezh1994/article/details/78899683。还有http://www.cnblogs.com/yyds/p/6171340.htmle1e3ebaf69b90e97917426ebf7e35b72.png

UTF的全称是Unicode transformation format。aabd8cba564c3ca5aeff112f6329b019.png

更详细点d8df3cc060bf4f847d71141c20d1871b.png

编码问题是很重要的问题。我就再总结一下编码,如果学过数字电子就更好理解了,比如说2用8421码来编就是10,用格雷码来编就是11,编码就是把我们认识的字符都转化为计算机认识的0和1。为了把英文字符一一对应为电脑认识的二进制,美国人发明了ASCII码,为了把中文字符一一对应为二进制,我们中国有现在一般是GBK码,同样日本,韩国等都有自己国家的语言对应到二进制的码,而且会出现同一个二进制在不同国家的编码体系里对应不同的字符,这也很好理解对吧。这样不便于大家交流,那么就需要有统一的一种编码方式了,然后Unicode就诞生了,它这种体系可以包容各个国家的语言,可以保证每个二进制数和字符的一一对应关系,不会出现比如说某个二进制既对应着中国的‘你‘,又对应着美国的'fuck'。但是Unicode的码存储起来是很耗费空间的,这时候就需要用到utf这种变字节存储方式来存,utf-8是我们比较常用的。那么译码就是反过程咯。我们可以在命令行里查看系统的默认编码,右键标题栏,点属性054e0f62d7e9e9b2bc8657836ab04ff5.png

2944eea3e16abdd1c0858d3a2b47540d.png

可以看到是GBK的。你也可以在命令行直接输入chcp就可以查看。如果是936那么就也是GBK编码。也可以查看python默认的编码方式是什么样的。ace60acbe4a7b6411fa85703c6c2551e.png

我们再来深入探索一下编码与解码的世界。参考了https://www.cnblogs.com/abclife/p/7445222.html和https://www.cnblogs.com/654321cc/p/7419124.html。21f8d7e95e20ffd5b7c288f7b65e083d.png

bin是把一个整数转换为二进制,用的是8421码,并且只能转换整数。我们一般用不到它,因为你在键盘上面敲进去的数字也全是字符,并不是数字。什么意思呢?还记得input吗?4a2705d6039c3ddd0ff05e64057624c3.png

只有经过了int才转化成整数了。这就是我们输入的都是字符的含义。以前我们曾经用过ord()说它返回的是ASCII码,其实是不对的,返回的是utf-8码,只是因为拉丁字母和一些特殊字符的ASCII码和UTF—8码是一样的或者说是兼容的而已。返回的是单个字符的utf-8码78a6f0d2edfe0ccbd36960535c4cdd30.png

当然实际存在计算机里都是二进制的,只是为了方便用户看,显示出来的是十进制的。与之对应的是chrce3b77acbbe07fba40ce3da3bda96b05.png

为什么chr(23)和chr(31)没有显示字符呢?因为ASCII码表里(我为什么用ASCII码表呢?因为utf-8和ASCII码是兼容的),23和31对应的字符都是控制字符,python并不能给你显示出来,所以返回了一个十六进制字符。c2843e7eeb519093cd3f73663d2cc022.png

Bytes()前面也说到是一种二进制类型。ef1591540194ce59d56b6e388d3e9a36.png

d65b7316c9170a607265438f5524162e.png

499bb69eea0f76960a42a41d8d24fbaa.png

1e8fe46ee7cea2b62ef75361ad143312.png

打印出来的 格式默认都是十进制。8f05234789f5b5b0f4d21a4944bac449.png

字符串内部确实有encode()编码的内置函数可以按照给定编码形式把字符串进行编码,转换为二进制的形式,如果不给编码形式那么就按照python默认的utf-8来编码。bytes类的内置方法decode()可以按照给定解码方式解码,如果不给就按照python默认的utf-8解码。上面d为什么按照utf-8解码错误呢?因为回去看这个表49ef52ea8d6fcb348274a891e699ab24.png

\xd6\xd0二进制就是11010110  11010000,这样的二进制是不符合utf-8的格式的。有的时候不会报错,但是会出现乱码。还有可能会出现下面的情况。41fbc40ae3c318a88b3f786823105bb9.png

ad05ba677466bbd9d7bb64aeb518ee9f.png

为什么有的返回的不是b十六进制而是直接b+原来的字符串呢?根据上面的尝试我猜想是ASCII码里有的打印字符在后来的所有编码格式里包括GBK,utf-8等等里面都是直接继承了ASCII码的。因为大家都一样嘛,所以就直接前面加个b表示这是二进制就返回了。到这里,你就知道前面b站主页返回的前1000个字节为什么有的是\x十六进制,有的直接就是拉丁字母和英文标点了。

下面看看bytes()的作用。87c0631af77e7e401640c3a488facdb3.png

其实就是编码,而且后面还必须要加上编码的格式。并且上面验证了所有编码格式都继承了美国最早的ASCII码的所有拉丁字母和英文字符的对应关系。这样就理解了为什么上面获取的网站后返回的HTTPResponse类型为什么不全是\x的十六进制形式,可以看到拉丁字母和英文字符都是直接表示出来了,因为在python认可的所有编码体系里它们的二进制都一样,不需要给出来了。有时候我们打开的文件会出现乱码,是怎么回事呢?下面我们要学习一下python里的文件读取操作,

python之文件读取简单原理

参考了http://www.cnblogs.com/yyds/p/6186621.html和

http://www.cnblogs.com/yyds/p/6171340.htmlbb3fe91f432cd7f762b909136bb5020f.png

首先我们要明白一个概念,磁盘写入或读取数据时使用的字符编码是由编辑器指定的工程或文件的字符编码决定的,这与Python解释是无关的。Python3的解释器以"UTF-8"作为默认编码,但是这并不表示可以完全兼容中文问题。比如我们在Windows上进行开发时,Python工程及代码文件都使用的是默认的GBK编码,也就是说Python代码文件是被转换成GBK格式的字节码保存到磁盘中的。怎么体现这点呢?98aadcd1f027cb9927b02ec51e727362.png

首先我们写了一个txt文件,这个文件是怎么被写进去的?还是必须先编码才行,由于我们没有指定编码方式,就用了默认的GBK,因为计算机只认识0和1,然后这个编码方式其实也传给了计算机,那么我们的计算机就会以GBK的格式去解码传过来的二进制数据,也就是编码解码方式是一样的,我们才能看到'中文‘。那么我们就试试用‘utf-8’去编码试一下咯。51634f9ff2433c574ccf1bfd41669262.png

我们还是看到了正常的'中文',这前面说过是因为编码方式也被传递给计算机了,计算机会按照python传过来的编码格式也就是utf-8来解码。但是当python在读取的时候,它是得不到这个我们原来传过去的编码方式的,它得到的就只有文本内容的一堆二进制,如何解码呢?不知道,我们如果不给它解码方式,它就按照默认的GBK来解码,结果就报错了。你们可以自己去对照GBK的表http://www.qqxiuzi.cn/zh/hanzi-gbk-bianma.php。然后我们来看ae09c4bf20933bebd04a591d3e58d821.png

我们先来了解什么叫做流,参考了https://www.zhihu.com/question/38075755,https://blog.csdn.net/hansnowqiang/article/details/50130437和https://blog.csdn.net/u011000290/article/details/48940371。b18e224b2b174ca0294bfd97480e69d9.png

当然上面只是说了我们为什么需要缓冲区的原因,还没有说什么是流。6fdab994e4444c2dcd24e47ca3f4a03d.png

我们不再延伸了,有兴趣可以自己去学有关流的更多操作。

c8c8e1a8750fe30d50f486c075ac6c80.png

API就是Application Programming Interface,应用程序编程接口,就是前人已经写好的实现复杂功能的函数,以供后人可以直接调用。eb04aab61c4ad439f32cbd77e7fdbae5.png

上面编码花了好打空间,我们回过来继续学爬虫,上面这些后面课程的基础,所以我在爬虫的第一讲先讲一部分知识,当然这还没有包含掌握爬虫需要掌握的所有知识。以后再慢慢渗透吧。前面爬取b站的时候,我们得到的是编码过的二进制,需要译码成我们可以看懂的形式。译码之前我们就需要知道百度是什么编码方式,怎么获得呢?其实很简单按F12就可以审查元素了。这个Elements里面是HTML代码,

Console里面是调试JavaScipt的,Sources是资源,后面的暂时后用不到。然后点开head,charset后面就是编码的格式。ce7cb8fad87a2357009f4917a7a5d2b4.png

知道了编码形式我们来解码吧。ff2bf53d579e57272d665ec343fbff95.png

你可以去和上面对比,哪些是十六进制的地方绝对都是汉字。虽然还是看不懂HTML,但是这并不妨碍你找资源。这里在稍微说一个小知识

再写十六进制的时候,你需要按照字节来写\x号,什么意思呢?对比下面你就懂了

第一种写法b'\x8140'其实是\x81=129,ord('4')=52,ord('0')=48。第二种才是\x81=128,\x40=64。e218bba8539f8ac7e6e15b21e622d83a.png

下面就先来大展一番身手吧

练习

0.编写一段程序,检测指定URL的编码。

1.写一个程序,依次访问指定文件夹里的网页,并将内容保存在不同的文件中。

答案和讲解会在下一讲公布。1cbf43c55372030e251e421912a69224.png



推荐阅读
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文介绍了django中视图函数的使用方法,包括如何接收Web请求并返回Web响应,以及如何处理GET请求和POST请求。同时还介绍了urls.py和views.py文件的配置方式。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了使用CentOS7.0 U盘刻录工具进行安装的详细步骤,包括使用USBWriter工具刻录ISO文件到USB驱动器、格式化USB磁盘、设置启动顺序等。通过本文的指导,用户可以轻松地使用U盘安装CentOS7.0操作系统。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • RouterOS 5.16软路由安装图解教程
    本文介绍了如何安装RouterOS 5.16软路由系统,包括系统要求、安装步骤和登录方式。同时提供了详细的图解教程,方便读者进行操作。 ... [详细]
  • 解决github访问慢的问题的方法集锦
    本文总结了国内用户在访问github网站时可能遇到的加载慢的问题,并提供了解决方法,其中包括修改hosts文件来加速访问。 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
author-avatar
手机用户2502861455
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有