web技术笔记(1):科学地让up主交出封面

b站舞区最不缺的是小姐姐,好看的小姐姐最不缺的是精美的视频封面。作为一个常逛舞区的b站用户,若是仅仅只能看着一张张令人舔屏的封面——的缩略图,那和吃着芥末味的冰淇淋、喝着加了大蒜的冰糖雪梨水有什么区别?

那么今天就来介绍最基本的网页分析:找到一个视频封面的URL并用python的urllib库来获取URL对应的资源。
在这里插入图片描述

Step1:找到封面的URL

为了避免一些不必要的纠纷,这次我就用我自己的投稿来进行示范。首先我们要有一个可以打开开发人员工具(控制台)的浏览器。不同的浏览器操作大同小异,这里我就用最普适的chrome来示范了。

打开我们的视频,按F12调出控制台。
在这里插入图片描述
在控制台中我们会发现许多蓝蓝的链接,那就是各种资源的URL。我们要知道,在网页设计的过程中,并不是把所有的信息都记录在网页的HTML中的,通常记录的只会是可以进行编码的文本信息。像视频、图像这类二进制文件,HTML无法对它们本身进行记录,它们只能在HTML标签中记录这类文件在该网站服务器上面的地址。

在把网页呈现到用户面前的同时,根据http协议,这些资源会被调用到标签所指示的位置,从而在网页的特定位置被显示出来。反过来讲,通过藏在我们控制台中的这些蓝蓝的小链接,我们就可以定位到网页中我们想要的任何资源。

UP主封面的URL,同样也隐藏在控制台当中。我们点开HTML中的head标签,会发现底下有一长串的meta标签。
在这里插入图片描述
我们在浏览器网页当中能读到的一般是body标签当中的信息,至于会显示在浏览器的导航栏、标题栏之类的地方的信息,一般在head标签当中定义。head标签下的meta标签中的信息更是整个网页类似背景、环境一样的属性,它们通常不会被我们看见,却产生了一个网页的全部摘要。

我们的目标,视频的封面,也就隐藏在其中一个meta标签中。

不难猜,虽然带有.jpg的链接有三个,但是它们都长得一模一样,指向了同一张图片,那就是我们要的封面。将这个链接打开,就能看到视频封面的原尺寸大图了。
在这里插入图片描述
在这里作为科普,我也顺带解释一下http://i2.hdslb.com/bfs/archive/d8309d7704e1753102d21ddfda009259791b4e8b.jpg这一长串URL的意义。我们可以看到这个URL的开始不是https://www.bilibili.com/,说明b站存放图片的服务器域名和b站本站的域名不一样。URL中的一部分让我们想起了自己计算机上的文件路径:/bfs/archive/d8309d7704e1753102d21ddfda009259791b4e8b.jpg。的确,这便是这个封面的.jpg文件在服务器上的存放路径的一部分,但不是完整路径。而http://i2.hdslb.com也并不一定像我们本地计算机的D盘C盘一样,是服务器主机的根目录,而可能,出于安全考虑,为了防止暴露服务器数据库绝对路径,是主机根目录下的某个子文件夹、子子文件夹……它们被赋予域名,设为网站的根目录。

Step2:保存URL对应的资源

前文我们说过,那一串URL就表示文件在服务器上的储存位置。网页、图片、视频等资源都是通过这样的路径被表示出来的,你在浏览器上通过这些路径访问到的不仅仅会是网页。

假如你打开的URL以.html结尾,那么它确实是网页,但是像刚才那样直接打开一个以.jpg为结尾的URL时,我们便直接在浏览器上看到了这个资源,而没有通过网页。这时候我们点击右键,就会出现保存图片的选项。
在这里插入图片描述
浏览器可以保存图片,我们同样也可以编程实现这一过程。拿出我们万能的python,安装urllib库,我们就可以开工敲代码了!

import urllib.request    #引入urllib库底下的request模块
urllib.request.urlretrieve(URL,filename=路径) #将URL对应的资源直接保存到filename对应的路径 

用上面短短的两句话,仅仅是在记事本当中就可以写出一个python脚本,实现自动把URL对应的图片保存到本地的功能。
在这里插入图片描述
在这里插入图片描述
可是这样的两行脚本并没能解决问题。如果每次看到一个视频,都要打开控制台,获取URL,再复制到脚本里,再执行,其效率和复制URL到浏览器地址栏,打开新页面后保存图片大同小异,不符合人类怠惰的本性,不能让辛苦掌握python语言的我们产生丝毫优越感……

我们想要这样一个脚本:当我们输入视频的av号时,会自动打开视频的网页,定位到封面所在的URL,提取这个URL,再执行伟大的urllib.request.urlretrieve。能不能做到呢?当然可以。当你构思出了这一系列的过程时,你实际上已经设计出了一个简单的”网络爬虫“的爬取策略了。

Step3:获取视频网页

浏览器在打开URL,获取URL对应的资源时,便好像是在查号码本,查到了对应的电话号码后,再拨打电话号码叫来对应的人。我们把URL当作电话号码,那么打电话把对应的人叫过来的这个过程,在http中,就是一个get请求。

urllib库中同样提供了这个”电话“,只需要你输好电话号码,按下通话键,万能的python就会把电话那头的人请回你家。

response=urllib.request.urlopen(URL) #向URL发送一个get请求,并且将请求的回应保存到response对象当中 content=response.read() #将response中的资源(读网页的话,就是网页的HTML)保存到byte对象content中 text=content.decode("utf-8") #将byte数据解码为utf-8字符串 

上面的语句便可以模拟浏览器获取网页HTML的过程。将视频链接作为URL,运行以上语句,就可以把视频网页的HTML保存到text中。打印text,便可以看到HTML内容。

保存,运行,然后完美打脸。
在这里插入图片描述
在这里插入图片描述
恭喜您收获403一枚,我们略过常规浏览器瞒天过海访问b站的行为被逮了个正着。看来要爬取b站网页并不是一件非常容易的事情……

既然不使用浏览器发出的请求会被b站拒绝,那我们能不能把我们的请求伪装成浏览器发出的请求呢。

在浏览器向网站发送get请求的同时,网站也会看到浏览器的“header”,相当于是用户的一个标识。

打开chrome控制台,切换到network选项卡,刷新网页,你就会看见控制台中跳出了非常多的资源,那些都是浏览器通过http请求获取的。最顶端的一条便是我们要的网页的html。
在这里插入图片描述
在右边将选项卡切换到headers。往下找到Request Headers。
在这里插入图片描述
Request Headers有非常多条,最重要的就是最下面的User-Agent一条。
在这里插入图片描述
我们可以看到这一条当中记录了一些浏览器基本信息,网站会读取User-Agent中的信息来判断我们是不是通过浏览器来访问的。如果不是,那么对不起,你就要受到有反爬虫策略的网站的惨拒了。

我们现在用urllib中的方法来构造一个带有User-Agent的自定义请求,再用urlopen把请求发送出去并获取资源。

req=urllib.request.Request(url=URL,headers={'字段名':'内容'}) #创建一个自定义请求。 

在这里插入图片描述
将之前代码中单纯的urlopen替换为上面的语句,执行。
在这里插入图片描述
我们成功执行到了下面的语句,说明我们已经利用伪造headers瞒过了b站的小眼睛!

但是还没来得及兴奋,新的问题又出现了。0x8b这个十六进制数字无法被转换为utf-8,怎么办呢?

我们再看之前的Request Headers,里面有这样一条:
在这里插入图片描述
HTTP协议上的gzip编码是一种用来改进web应用程序性能的技术。大流量的web站点常常使用gzip压缩技术来让用户感受更快的速度。.decode(‘utf-8’)可以把byte数据转换为utf-8,但如果是被gzip压缩过的byte数据,便不可以转换。

但有什么难得倒万能的python呢?我们可以通过安装zlib库来解决这个问题。

(假如你使用了Anaconda环境,那么zlib和urllib都已经预装好了,能省去不少时间

import zlib    #引入zlib

content=zlib.decompress(content, 16+zlib.MAX_WBITS) #解压网页 在text=content.decode('utf-8') 这句话前加入上两句话,运行。 

在这里插入图片描述
网页已经成功被爬取显示了!

Step4:定位封面URL

我们已经成功获取了网页,网页被用字符串的方式储存,有python基础的同学现在就已经可以使用字符串操作的方式去找到URL了。但是在爬虫开发当中,我们可以使用更加优雅的方法定位URL。

HTML是一种由标签定义的树形结构,一个大标签之下有多个子标签,每个子标签之下又有数个子子标签,其结构和XML有高度相似性。而xpath表达式则是针对XML文档的树形结构设计的表达式,如果我们使用xpath表达式,就可以非常高效地在被转为XML文档的HTML中定位资源。

xpath语法的详细信息可以参考w3school上的教程:http://www.w3school.com.cn/xpath/index.asp

我们回到我们爬取的HTML上来,还记得我们是在head标签下的一些meta标签里的一个属性里发现了我们的目标URL吗?我们可以写出下面这个xpath表达式来定位。

/html/head/meta[@itemprop=“image”]/@content

然后,我们使用以下语句来实现定位:

from lxml import etree    #从lxml库中引入能将HTML转化为树形结构的模块

tree = etree.HTML(HTML字符串) #将HTML转化为树形结构 result=tree.xpath(xpath表达式) #定位资源 

在这里插入图片描述
在这里插入图片描述
好的,接下来要做的事情已经不言自明了。将result作为urlretrieve的参数,并且把av号改成手动输入,我们就可以完成这个脚本的制作了。

最终代码如下:
在这里插入图片描述
执行效果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

小结

本次介绍的基本网页分析和基于urllib的爬虫实现方案,非常基础也非常重要。在接下来的文章当中还会介绍一些复杂网页的爬取、一些网络协议分析,介绍更加强大的网页爬取工具,但不管怎样,贯穿本文的爬取策略——“分析-获取-定位”,始终是网络爬虫设计当中的核心思想。

转载于:https://www.cnblogs.com/HarmoniaLeo/p/10568865.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值