美文网首页
爬虫 0&1

爬虫 0&1

作者: 若晴y | 来源:发表于2021-04-21 23:26 被阅读0次

    requests.get()

    引入requests库

    import requests

    requests.get是在调用requests库中的get()方法,它向服务器发送了一个请求,括号里的参数是你需要的数据所在的网址,然后服务器对请求作出了响应。

    我们把这个响应返回的结果赋值给变量res

    res = requests.get('URL')

    第2行代码,是引用requests库。

    icon

    第6行代码,requests.get()发送了请求,然后得到了服务器的响应。服务器返回的结果是个Response对象,现在存储到了我们定义的变量res中。
    现在看一下requests.get()方法的参数——我们又看到了URL,也就是我们通常说的“网址”,在接下来的学习中,你也会发现,它几乎无处(课)不在,这是一个很基础却重要的内容,我们来一起学习或复习一下,学过的同学也不用担心回忆起被考试支配的恐惧,我们目前只需要看一眼去哪里找到它,不需要记得它大名叫统一资源定位符以及其它……

    任意一个网页,在浏览器最顶部的地址栏双击一下鼠标,显示出的全部内容就是URL了,如果你正用网页版学习课程,鼠标双击地址栏,会看到https://www.pypypy.cn/#/apps/2/home,这就是我们风变爬虫课主页的URL,如图所示:
    URL的功能从它的常用别名“网址”以及它所在的位置“地址栏”联想一下就很好理解了:它指示了一个网页在网络上的地址,就像我们住的房子在地球上的详细到某某街道某某号的具体地址。
    再啰嗦一句,已知URL(网址),想打开网页的时候,只要把整个URL粘贴到浏览器地址栏,按个回车就可以了。

    icon

    如果用图片展示requests.get()的工作过程,那就是这样的:

    image.png
    Response对象的常用属性

    res是一个Response对象
    Response对象常用的四个属性:


    image.png

    首先是response.status_code,直接看用法
    import requests

    res = requests.get('https://res.pandateacher.com/2018-12-18-10-43-07.png')

    打印变量res的响应状态码,以检查请求是否成功

    print(res.status_code)
    第5行代码是在打印res的响应状态码,它可以用来检查我们的requests请求是否得到了成功的响应。我们看到终端结果显示了200,这个数字代表服务器同意了请求,并返回了数据给我们。
    除了200,我们还可能收到其他的状态码。下面有一个表格,供你参考不同的状态码代表什么,但不需要记住它们,在遇到问题的时候查询就好。


    image.png
    image.png

    接着的属性是response.content,它能把Response对象的内容以二进制数据的形式返回,适用于图片、音频、视频的下载,看个例子你就懂了。

    引入requests库

    import requests

    发出请求,并把返回的结果放在变量res中

    res = requests.get('https://res.pandateacher.com/2018-12-18-10-43-07.png')

    把Reponse对象的内容以二进制数据的形式返回

    pic = res.content

    新建了一个文件ppt.jpg,这里的文件没加路径,它会被保存在程序运行的当前目录下。

    图片内容需要以二进制wb读写。你在学习open()函数时接触过它。

    photo = open('ppt.jpg','wb')

    获取pic的二进制内容

    photo.write(pic)

    关闭文件

    photo.close()

    讲完了response.content,继续看response.text,这个属性可以把Response对象的内容以字符串的形式返回,适用于文字、网页源代码的下载。

    引入requests库

    import requests

    下载《三国演义》第一回,我们得到一个对象,它被命名为res

    res = requests.get('https://localprod.pandateacher.com/python-manuscript/crawler-html/sanguo.md')

    把Response对象的内容以字符串的形式返回

    novel = res.text

    创建一个名为《三国演义》的txt文档,指针放在文件末尾,追加内容

    k = open('《三国演义》.txt','a+')

    写进文件中

    k.write(novel)

    关闭文档

    k.close()
    我们看最后一个属性:response.encoding,它能帮我们定义Response对象的编码。
    那么,回看之前的【练习:下载文章《三国演义》第一回并打印】,终端是怎么“知道”编码类型并将文字正确打印显示的呢?

    icon

    事实上,requests.get()发送请求后,我们得到一个Response对象,其中,requests模块会对数据的编码类型做出自己的判断。

    引用requests库

    import requests

    下载《三国演义》第一回,我们得到一个对象,它被命名为res

    res = requests.get('https://localprod.pandateacher.com/python-manuscript/crawler-html/sanguo.md')

    定义Reponse对象的编码为utf-8。

    res.encoding='utf-8'

    把Response对象的内容以字符串的形式返回

    novel=res.text

    打印小说的前800个字。

    print(novel[:800])

    为了让大家理解res.encoding的意义,也就是它能定义Response对象的编码类型。
    那在真实的情况中,我们该在什么时候用res.encoding呢?
    先,目标数据本身的编码方式是未知的。用requests.get()发送请求后,我们会取得一个Response对象,其中,requests库会对数据的编码类型做出自己的判断。但是!这个判断有可能准确,也可能不准确。比如你发给我一张“法语”字条,我看不出来是什么语言,猜测可能是“俄语”,“德语”等。
    如果它判断准确的话,我们打印出来的response.text的内容就是正常的、没有乱码的,那就用不到res.encoding;如果判断不准确,就会出现一堆乱码,那我们就可以去查看目标数据的编码,然后再用res.encoding把编码定义成和目标数据一致的类型即可。
    总的来说,就是遇上文本的乱码问题,才考虑用res.encoding。
    好,到这里,requests.get()方法和Response对象常见的四个属性就讲完了。
    如果用一张图来总结,那就是这样的:


    image.png

    可以看到,爬虫的第0步:获取数据,本质就是通过URL去向服务器发出请求,服务器再把相关内容封装成一个Response对象返回给我们,这是通过requests.get()实现的,而我们获取到的Response对象下有四个常用的属性
    同学们要注意这种从URL到Response这种操作对象的转换关系。
    HTML是用来描述网页的一种语言,英文全称是Hyper Text Markup Language,也叫超文本标记语言。
    标记语言就是把文本和文本以外的相关信息(例如大小,高度,颜色,位置等)组合在一起的语言
    HTML的组成

    icon

    看起来有点复杂?不怕,事实上,HTML文档在编程界是有名的软萌可推。不信?来看一份基础的HTML文档。
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    </head>
    <body>
    风变一下,你就学到
    </body>
    </html>
    对,这个看上去很简单的程序就是整个HTML的基本架势,我们先熟悉一下它的格式,不用纠结代码具体的意思。

    image.png
    HTML文档主要由元素组成。
    第一行<!DOCTYPE html>是一个全局声明,目的是告诉浏览器,你现在处理的这个文档是HTML文档。
    声明过后,迎来了HTML代码的主战场,一共有三组基本元素,分别是html元素(<html></html>),head头元素(<head></head>),和body主体元素(<body></body>)。它们成对出现,都带有尖括号(<>&</>),分别代表着元素的起点和终点。最外层是<html>(文档起点)</html>(文档终点),它的作用是标记文档的起始位置和终止位置,从层级上来看,显然是老大,将<head></head>(头部)和<body></body>(主题)包裹了起来。看到这里,你会发现,HTML文档就好像一个勾勒好头部和身体位置的人体。
    image.png
    当然,人生在世,只有简单的“轮廓”是不够的,需再勾画些“器官”,穿些漂亮衣服,学习一些行为动作,才不虚此行。html亦是如此,下面,让它展露下自己的一鳞半甲。前面我们说,HTML文档可以容纳更加丰富的信息,于是,老师在原来的基础上撒点料,变成了这样(体验一下,不必细究具体某块代码的意思):
    <!DOCTYPE html>
    <html>
    <head>
    <title>风变一下,就能学到</title>
    <link rel="shortcut icon" href="http://static.pandateacher.com/forcode_favicon.ico" type="image/x-icon">
    <link rel="stylesheet" href="https://res.pandateacher.com/L0test1.css">
    </head>
    <body>
    <div style="text-align:center;margin-top:80px;" class="search_box">
    <img width="150px" src="https://res.pandateacher.com/横版:中文组合:风变蓝.png">
    <form id="search_form">
    <input type="text" class="input_box">
    <button class="btn_submit" disabled="true">风变一下</button>
    </form>
    </div>
    </body>
    </html>
    事情似乎变得有趣起来了,粗略地阅读代码框架,大致能得到如下信息:

    层级结构

    icon

    HTML和python一样,【有缩进】,这缩进将文档之间的那点结构层级安排地明明白白。
    以我们人体为例,每颗头,都有眼睛、耳朵、鼻子,嘴唇、头发(好像不一定?)。而每双眼睛,又由眼睫毛、眼皮、眼球等结构组成。
    生活如斯,在数据的世界中,分层级的组织规则和作用会更加明显。
    譬如,头部元素(<head></head>)内,一般会被用来设置网页的编码,添加网页标签的小logo,小标题,外部文件引用(就好像python会用import引用别的模块)等。

    image.png
    其次,HTML文档的主体元素(<body></body>)负责定义网页窗口内的所有内容,同时也是今后我们重点关注的对象
    image.png
    在这里,主体元素(<body></body>)的腹中只有一个div元素(<div></div>),而div元素(<div></div>)手下有两个“关节”:图片元素(<img/>)和表单元素(<form></form>),表单元素(<form></form>)也有两节“骨头”,分别是input元素(<input/>)和按钮元素(<button>)。
    以上便是这份HTML文档的层级结构。
    除了尖括号的英文外,似乎还暗藏着许多"赋值语句"(如width='200px')。这和尖括号的英文字符或字母(<img />)有什么关系?如何区分?
    要捋清楚它们其实很容易,总结起来就两类东西:标签和属性,接下来我们会挨个讲解。
    标签
    标签用于标记文本信息,指用尖括号(<>和</>)括起来的字母和英文,形式有两种:闭合标签和空标签。
    闭合标签,它们绝大多数成对出现(有开始标签<>,也有结束标签</>),如:<title>和</title>是标题标签,<div>和</div>是块标签,<form>和</form>是表单标签。
    空标签,顾名思义,指那些“孤苦伶仃”的单标签,它们“形影单只”只有一个尖括号<>(斜杠/可省略),标签开始即结束,比如上面的<img />是图片标签,<link />是链接标签,<input />是input标签。

    值得注意的是,不要把标签与我们前文讲的元素混淆了哦,前面我们说的元素,其实是包含了开始标签与结束标签内的所有代码。如html元素是指<html></html>包括标签内的所有代码。
    通过标签的英文名,我们大致能猜测出它的作用:给浏览器介绍文本的结构。你看<img/>这个位置,我打算放一张图片,那个<form></form>里面我塞的是一张表单。HTML文档含有许多标签,我们不必记住它们,了解几个常用的,混个脸熟即可,有兴趣的同学可以课后翻阅相关的文档(HTML标签)。

    image.png
    用标签给文本标记好了之后,浏览器开始发问了,年轻的程序员哟,你要的是这个金色的标题,还是这个银色的标题,还是这个五颜六色的标题?
    image.png
    想更加详细生动地描述乏味的标签,需要向标签注入点“形容词”,大的还是小的?长的还是高的?什么颜色?
    总而言之,是要刻画元素的属性,给html的骨架增添点漂亮的“衣服”。(注意:HTML的属性和Python中的属性不是一个东西)。
    属性
    正式介绍属性之前,来玩一个“找茬”游戏吧!请你尝试寻找body元素(<body></body>)内三条图片标签<img />间的不同之处,然后运行一下代码,比较一下两者之间的样式差异。
    提示:作用相当于python中的#,是HTML的注释方式。
    <html>
    <head>
    <meta charset="utf-8">
    <title>来找茬</title>
    </head>
    <body>
    <img src="https://res.pandateacher.com/black_logo.png" alt='图片1' width="20" height="24">
    <br />
    <img src="https://res.pandateacher.com/black_logo.png" alt='图片2' width="50" height="60">
    <br />
    <img src="https://res.pandateacher.com/black_logo.png" alt='图片3' width="100" height="100">
    <br />

    三个熊猫头大小各异,这其实是赋值语句width='xx'和height='xx'的功劳,width属性可以描述图片的宽。height属性能控制图片的高度,两相结合,图片的大小任人摆布。
    除此之外,还有设置图片链接的src属性(src='xx'),alt属性可编辑当图片无法显示时的替代文本,它们的独有的特征是:都由赋值语句构成。

    image.png
    属性的书写方式(赋值)让人一目了然,却也有一个致命的问题,若一个标签具有多个属性(如大小、颜色、间距、对齐方式),结构就会变得十分冗杂,严重影响阅读体验,像这样:<h1 font-weight='bold' align='center' letter-spacing='2px' style="color: #20b2aa;">这个书苑不太冷</h1>
    倒是有个通用的style属性能把所有的样式以键值对的形式收集起来,像这样

    <h1 style="font-weight:bold;text-align:center;letter-spacing:2px;color: #20b2aa;">这个书苑不太冷</h1>
    可是,这样“长篇累牍”的代码还是不够优雅。于是,集勤劳与智慧于一身的程序员一不做二不休,干脆将style属性样式全部抽离出来。
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <style>
    /规定h1的具体样式/
    h1 {
    font-weight: bold;/控制元素字体粗细/
    text-align: center;/控制元素对齐方式/
    letter-spacing: 2px;/控制文本字符的间距/
    color: #20b2aa;/控制元素的颜色/
    }
    </style>
    </head>
    <body>
    <h1>这个书苑不太冷</h1>
    </body>
    </html>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <style>
    /规定h1的具体样式/
    h1 {
    font-weight: bold;/控制元素字体粗细/
    text-align: center;/控制元素对齐方式/
    letter-spacing: 2px;/控制文本字符的间距/
    color: #20b2aa;/控制元素的颜色/
    }
    </style>
    </head>
    <body>
    <h1>这个书苑不太冷</h1>
    </body>
    </html>
    如此,分工明确,各司其职。标签<h1>只管增添文本内容,文本样式的控制权交给head元素的<style>标签
    <style>
    /规定h1的具体样式/
    h1 {
    font-weight: bold;/控制元素字体粗细/
    text-align: center;/控制元素对齐方式/
    letter-spacing: 2px;/控制文本字符的间距/
    color: #20b2aa;/控制元素的颜色/
    }
    </style>
    h1 {}的内容,是h1元素样式的具体描述,比如text-align: center;,而/控制元素对齐方式/是对代码的注释。
    好景不长,很快就有人就提出了质疑:这不是一刀切么,所有的h1元素都一个模样,倘若第二个h1元素想保持原有的样式可不就尴尬了?
    为了解决这个问题,HTML文档诞生了两个最为特殊的元素:class和id。
    属性:class&id
    讲解它们的作用之前,我们再来思考一个场景:如果网页需要排版多张大小不同的图片,它们的属性应该怎么设置?
    image.png
    譬如上面这几张图片的排版,每行第一张图片宽度为100像素(width=100px),其余的图片的宽度为50像素(width=50px)。
    直接设置img元素的样式,似乎有些不妥。那给每个logo的<img />标签都标注宽高?试想,电商网站有成千上万张图片,都这么干的话,某宝的前端程序员单是图片处理就已过劳而秃了吧。
    怎么办?如果我们用的是python代码,遇到类似的事情会怎么做? icon

    还记得吗?在python中,可将相同的属性和方法的对象抽象成,关键词是class

    image.png

    在HTML文档中,我们也有一个关键词为class的属性,class属性值相同的元素可复用同一套样式。
    经观察发现,上面的六张图片,可根据它们的宽度进行简单分类,宽度是100像素(width=100px)为一类,宽度为50像素(width=50px)是另一类。
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    </head>
    <style>
    /定义了class属性为style_1的样式/
    .style_1 {
    width: 100px;
    }
    /定义了class属性为style_2的样式/
    .style_2 {
    width: 50px;
    }
    </style>
    <body style="background:#a8c7e2">

    <img class='style_1' src="https://res.pandateacher.com/风变科技logo1.png" >
    <img class='style_2' src="https://res.pandateacher.com/forchange_blue_logo.png" >
    <img class='style_2' src="https://res.pandateacher.com/forchange_black_logo.png" >



    <img class='style_1' src="https://res.pandateacher.com/风变科技logo2.png" >
    <img class='style_2' src="https://res.pandateacher.com/panda_black_logo.png" >
    <img class='style_2' src="https://res.pandateacher.com/panda_white_logo.png" >
    </body>
    </html>
    上面,我们创建了两套样式,图片class属性值为style_1,获得<style>标签中的.style_1样式,其余class属性值为style_2的图片抱走.style_2的样式。

    image.png
    我们可以这么理解:class属性的作用是给元素增添类名,多个元素可配置一个类名,类名相同的元素沿袭同一套样式。
    id属性则刚好和class属性相反,整个HTML文档,它是独一无二的标识,每个id值只能定义一个元素。
    如若今后要爬取的元素带有id属性,那么恭喜💐你!这个元素具有唯一的标识,有了id,从千万元素中取值,犹如探囊取物。
    !DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <style>
    .book {
    padding: 0px;
    margin: 0px;
    }
    #book_info {
    width: 450px;
    font-size: 13px;
    }
    </style>
    </head>
    <body>
    <h1 align='center' style='color: #20b2aa;'>这个书苑不太冷</h1>
    <h2 style=" font-weight: bold;padding-bottom: 3px;margin-bottom: 16px;border-bottom: 1px solid #ddd;">吴枫喜欢的书:</h2>
    <div class="book">
    <img style='float: left;margin-right: 20px;height: 200px;' src="https://res.pandateacher.com/book_qidianyimin.jpg" alt="奇点遗民">
    <div class='book' id="book_info">
    <h4>《奇点遗民》</h4>
    <p style='color:#4c4a4a;'>本书精选收录了刘宇昆的科幻佳作共22篇。《奇点遗民》融入了科幻艺术吸引人的几大元素:数字化生命、影像化记忆、人工智能、外星访客……刘宇昆的独特之处在于,他写的不是科幻探险或英雄奇幻,而是数据时代里每个人的生活和情感变化。透过这本书,我们看到的不仅是未来还有当下。
    </p>
    <a href="https://wordpress-edu-3autumn.localprod.oc.forchange.cn/">点这里看看</a>
    </div>
    </div>
    </body>
    </html> image.png
    咱们重点关注第18行和第20行代码,显然,两个div元素含有同一个class属性值book,两个元素都可以使用.book的样式,但只有id="book_info"的元素可以使用#book_info的样式。
    注:在<style>标签中定义class属性的样式用点.,id属性用井号键#(了解即可)。
    id就像是学生的学生证号码,每个人都是唯一的,而学生们可以属于同一个班级,班级就像class。
    好,以上,是HTML文档关于结构、标签、属性、元素这几个概念的理解,来份总结吧~
    image.png
    HTML分析
    开发者工具
    用谷歌浏览器(chrome)随机打开一个网页,右键点击【检查】选项,Windows电脑的同学可直接按F12,随即,网页下方(或右方)弹出一个子窗口,这便是浏览器的开发者工具。
    image.png
    可以看到,HTML源代码中有一些小三角形,每一个三角形都可以展开或合上。尖角向下代表展开,向右代表合上了。
    HTML的层级关系可通过这些小三角形进行查阅,每一个可以展开和合上的小三角形里包含的内容,都是一个层级,就像电脑中一层一层的文件夹。
    image.png
    image.png
    开发者彩蛋
    值得一提的是,浏览器的开发者工具除了可以查看html的源代码,还可以查看前端程序员留给同行的“暗号”,老师带你去看看。
    打开百度网页下的开发者工具,点击开发者工具导航栏上的Console标签,哎嘿,发现了百度的招聘链接。
    修改网页
    最后,老师再教你一个网页偷天换日法:
    打开我们的爬虫学习网站网页下的开发者工具,你能看到左上角,有一个图标长这样吗?
    image.png
    点击它,然后再把鼠标放在网页中,你会发现很好玩的事情:当鼠标放在网页上,右边代码区中描述它的代码会被标亮出来:
    image.png
    这是一个你以后会经常用到的功能,用来定位你所要查找的网页内容的源代码。我们可用鼠标在源代码上从网页头到尾轻轻滑过(无需点击),查看当前代码被浏览器解析后呈现的内容。
    然后,定位到我们想修改的网页标题,把鼠标放在网页"这个书苑不太冷"这里,双击,和修改word文档一样。
    image.png

    调用requests模块

    import requests

    获取网页源代码,得到的res是response对象。

    res = requests.get('https://localprod.pandateacher.com/python-manuscript/crawler-html/spider-men5.0.html')

    检测请求是否正确响应

    print(res.status_code)

    正确响应,进行读写操作

    新建一个名为book的html文档,你看到这里的文件没加路径,它会被保存在程序运行的当前目录下。

    字符串需要以w读写。你在学习open()函数时接触过它。

    if res.status_code == 200:
    file = open('book.html','w')
    # res.text是字符串格式,把它写入文件内。
    file.write(res.text)
    # 关闭文件
    file.close()

    <pre style="box-sizing: border-box; margin: 0px; padding: 0px; border: 0px; text-decoration: none; font: inherit; vertical-align: baseline; -webkit-tap-highlight-color: rgba(255, 255, 255, 0);"># 调用requests模块
    import requests

    获取网页源代码,得到的res是response对象。

    res = requests.get('https://localprod.pandateacher.com/python-manuscript/crawler-html/spider-men5.0.html')

    检测请求是否正确响应

    print(res.status_code)

    正确响应,进行读写操作

    新建一个名为book的html文档,你看到这里的文件没加路径,它会被保存在程序运行的当前目录下。

    字符串需要以w读写。你在学习open()函数时接触过它。

    if res.status_code == 200:
    file = open('book.html','w')
    # res.text是字符串格式,把它写入文件内。
    file.write(res.text)
    # 关闭文件
    file.close() </pre>

    icon

    然后,双击我们写在本地的book.html文件,你会发现它可以用浏览器打开。这就好比MP3文件用音乐播放器打开,txt用记事本打开。

    现在的你应该更明白浏览器的工作原理了,简单来说:浏览器从服务器上接收一个HTML文档,然后拿去做解析,最后呈现给你。因此,它也可以把你电脑的HTML文档解析成漂亮的网页。
    本关的内容就到这里结束了,我们来复习一下吧。


    image.png icon

    首先,我们了解了由网页头和网页体所构成的HTML基本结构。


    image.png

    认识了HTML中的常见标签和常见属性:


    image.png
    image.png
    然后,我们读了一遍【这个书苑不太冷】的网页源代码。 icon

    分析完网页的结构和组成,又在HTML源代码的页面里成功修改了网页上显示的标题——“这个书苑不太冷”。
    最后,还通过调用requests模块,获取到了网页源代码。
    有了HTML的背景知识,我们就可以去学习爬虫的第1步【解析数据】和第2步【提取数据】啦。
    只有看得懂网页结构,我们才能在HTML中找出要解析的数据,才能知道如何根据HTML本身的结构去提取出我们想要的数据。

    相关文章

      网友评论

          本文标题:爬虫 0&1

          本文链接:https://www.haomeiwen.com/subject/hnptrltx.html