本文主要是介绍python爬虫基础Ⅰ——requests、BeautifulSoup:书本信息,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- requests
- 1. 安装
- 2. requests.get()
- 3. Response对象的常用属性
- (1 )response.status_code
- 常见相应状态码解释
- (2) response.content
- (3) response.text
- (4) response.encoding
- robot协议
- 需要了解一下HTML
- 1. 查看网页的HTML代码
- 2. 最简单的HTML文档
- 3. HTML属性
- BeautifulSoup
- 1. 获取与解析数据
- 2. find() 和 find_all() 方法
- 3. Tag对象常用方法
- 补充:str.strip()
- 给个练习吧
# 基础爬虫部分Ⅰ ## 什么是爬虫呀?
爬虫,从本质上来说,就是利用程序在网上拿到对我们有价值的数据。
爬虫能做很多事,能做商业分析,也能做生活助手,比如……详细还是看这里吧555→网络爬虫 (-v-)
通俗来说呢,我们平时使用浏览器搜索,浏览器就会向服务器发起请求(request),服务器再回个响应(response)给浏览器。爬虫也就是模仿人操作的这一个过程,去向服务器发起请求……话不多说。咱们接下来的每一个爬虫作业主要分为步骤:获取数据 -> 解析数据 -> 提取数据 -> 储存数据
第0步:获取数据。爬虫程序会根据我们提供的网址,向服务器发起请求,然后返回数据。
第1步:解析数据。爬虫程序会把服务器返回的数据解析成我们能读懂的格式。
第2步:提取数据。爬虫程序再从中提取出我们需要的数据。
第3步:储存数据。爬虫程序把这些有用的数据保存起来,便于你日后的使用和分析。
真的话不多说了,我们开始吧~!
requests
1. 安装
在Mac电脑里打开终端软件(terminal),输入pip3 install requests
;Windows电脑打开命令提示符(cmd),输入pip install requests
。
2. requests.get()
import requests
#引入requests库
res = requests.get('URL')
#requests.get是在调用requests库中的get()方法,它向服务器发送了一个请求,括号里的参数'URL'是你需要的数据所在的网址,然后服务器对请求作出了响应。
#把这个响应返回的结果赋值在变量res上。
打印一下type(res)
,发现它是一个对象,属于requests.models.Response
类。那既然是对象,就看看这个对象有什么属性和方法可供我们操作。
3. Response对象的常用属性
属性 | 作用 |
---|---|
response.status_code | 请求HTTP回应的各种相应的状态码 |
response.content | 把response对象转换为二进制数据 |
response.text | 把response对象转换为字符串数据 |
response.encoding | 定义response对象的编码 |
这里还是解释一下吧~~!
觉得简单的可以直接跳过嗷
(1 )response.status_code
>>> import requests
>>> res = requests.get('https://www.baidu.com/')
>>> print(res.status_code)
200 #200表明请求已成功
>>> print(res.text)
#篇幅太长
常见相应状态码解释
响应状态吗 | 说明 | 举例 | 说明 |
---|---|---|---|
1xx | 请求收到 | 100 | 继续提出请求 |
2xx | 请求成功 | 200 | 成功 |
3xx | 重定向 | 305 | 应使用代理访问 |
4xx | 客户端错误 | 403 | 禁止访问 |
5xx | 服务器端错误 | 503 | 服务不可用 |
具体的借鉴一下其他人整理的关于请求HTTP回应的各种状态码:HTTP各种相应的状态码
(2) response.content
接着的属性是response.content
,它能把Response对象的内容以二进制数据的形式返回,适用于图片、音频、视频的下载,看个例子你就懂了。
假如我们想下载这张图片,它的URL是:https://res.pandateacher.com/2018-12-18-10-43-07.png
那么代码可以这样写:
import requests
res = requests.get('https://res.pandateacher.com/2018-12-18-10-43-07.png')
#发出请求,并把返回的结果放在变量res中
pic = res.content
#把Reponse对象的内容以二进制数据的形式返回
photo = open('ppt.jpg','wb')
#新建了一个文件ppt.jpg,这里的文件没加路径,它会被保存在程序运行的当前目录下。
#图片内容需要以二进制wb读写。(open函数是文件处理里边的,简单简单哦)
photo.write(pic)
#获取pic的二进制内容
photo.close()
#关闭文件
这样,我们的图片就下载成功啦~
(3) response.text
继续看response.text
,这个属性可以把Response
对象的内容以字符串的形式返回,适用于文字、网页源代码的下载。
举个例子,下载小说《三国演义》的第一章:
import requests
#引用requests库
res = requests.get('https://localprod.pandateacher.com/python-manuscript/crawler-html/sanguo.md')
#下载《三国演义》第一回,我们得到一个对象,它被命名为res
novel = res.text
#把Response对象的内容以字符串的形式返回
print(novel[:800])
#现在,可以打印小说了,但考虑到整章太长,只输出800字看看就好。在关于列表的知识那里,前面说过[:800]的意思了~!
诶,为什么会出现一段乱码呢?
这是因为这个超级简单的网页数据的编码类型是'utf-8'
(是设计这个网页的人告诉我的!)。用requests.get()
发送请求后,我们得到一个Response
对象,其中,requests
模块会对数据的编码类型做出自己的判断。但是,这个Response
对象判断编码类型是'gbk'
。这样一来,跟数据本身的编码'utf-8'
就不一致了,所以打印出来,就是一堆乱码。(这里后边也会再提到的,关于编码类型主要有utf-8、gbk、gbk2312等,想了解的找度娘嗷~~python也有相应的编码和解码的方法~)
(4) response.encoding
这时我们就要用encoding来编码为utf-8,然后就不会有乱码啦:
import requests
res = requests.get('https://localprod.pandateacher.com/python-manuscript/crawler-html/sanguo.md')
res.encoding = 'utf-8'
#定义Reponse对象的编码为utf-8。
novel = res.text
print(novel[:800])
首先,目标数据本身是什么编码是未知的。用requests.get()
发送请求后,我们会取得一个Response
对象,其中,requests
库会对数据的编码类型做出自己的判断。但是!这个判断有可能准确,也可能不准确。
如果它判断准确的话,我们打印出来的response.text
的内容就是正常的、没有乱码的,那就用不到res.encoding
;
如果判断不准确,就会出现一堆乱码,那我们就可以去查看目标数据的编码(一般是网页源码的charset
属性值),然后再用res.encoding
把编码定义成和目标数据一致的类型即可。
在实际应用上,遇上文本的乱码问题,才考虑用res.encoding
。
robot协议
通常情况下,服务器不太会在意小爬虫,但是,服务器会拒绝频率很高的大型爬虫和恶意爬虫,因为这会给服务器带来极大的压力或伤害。
不过,服务器在通常情况下,对搜索引擎是欢迎的态度(刚刚讲过,谷歌和百度的核心技术之一就是爬虫)。当然,这是有条件的,而这些条件会写在Robots
协议。
Robots
协议是互联网爬虫的一项公认的道德规范,它的全称是“网络爬虫排除标准”(Robots exclusion protocol),这个协议用来告诉爬虫,哪些页面是可以抓取的,哪些不可以。
查看网站的robots协议,只需要在网站的域名后加上/robots.txt
就可以了。
比如淘宝的: http://www.taobao.com/robots.txt
协议里最常出现的英文是Allow
和Disallow
,Allow
代表可以被访问,Disallow
代表禁止被访问。而且有趣的是,淘宝限制了百度对产品页面的爬虫,却允许谷歌访问。
当你在爬取网站数据的时候,别忘了先看看网站的Robots
协议是否允许你去爬取。
同时,限制好爬虫的速度,对提供数据的服务器心存感谢,避免给它造成太大压力,维持良好的互联网秩序,也是我们该做的事。
需要了解一下HTML
1. 查看网页的HTML代码
打开网页(随便找个网页打开就ok)后,按F12
( Fn+F12
),浏览器弹出了一个标签页,就是HTML源代码了。(下边这个红框框没啥用的,我懒得换图)
夹在尖括号<>
中间的字母,它们叫做【标签】。标签通常是成对出现的,一个是开始标签,后边一个是结束标签。不过,也有标签是形单影只地出现,比如HTML代码的第四行<meta charset="utf-8">
(定义网页编码格式为 utf-8)。开始标签+结束标签+中间的所有内容,它们在一起就组成了【元素】(element)。
2. 最简单的HTML文档
打开记事本,保存下面的代码,保存格式.html
,就是一个最简单的HTML了。
<html><head><meta charset="utf-8"> </head><body><h1>我是一级标题</h1><h2>我是二级标题</h2><h3>我是三级标题</h3><p>我是一个段落啦。一级标题、二级标题和我,我们三个一起组成了body。</p></body>
</html>
3. HTML属性
在标签里面,属性名="属性值"
,如 name="value"
。再举例几个常用的属性:
链接一般都由<a>
标签定义,href
属性用于规定指向页面的URL
。
还有class
用于标识一系列的元素,id
属性用于标识唯一的元素。
emm,好像这些够用了吧,就不在此赘述辽。
BeautifulSoup
1. 获取与解析数据
由于BeautifulSoup
不是Python标准库,需要单独安装它,在终端输入一行代码运行:pip install BeautifulSoup4
。(Mac电脑需要输入pip3 install BeautifulSoup4
)后边不再说这个安装问题了,都是一样的操作!!
显然,我们可以使用BeautifulSoup解析和提取网页中的数据。
我认为讲这些不如直接上代码来得强,来吧,聪明的你看注释就能懂的啦~
之后先以http://books.toscrape.com/这个网站为例,先来爬下书的目录:
import requests
from bs4 import BeautifulSoup #导入模块res = requests.get('http://books.toscrape.com/') #发起请求print(res.status_code) #检查请求是否正确响应html = res.text #把Response对象的内容以字符串的形式返回soup = BeautifulSoup(html,'html.parser') #把网页解析为BeautifulSoup对象(简称BS对象)
#在括号中,要输入两个参数,第0个参数是要被解析的文本,注意了,它必须必须必须是字符串。
#括号中的第1个参数用来标识解析器,我们要用的是一个Python内置库:html.parser。(它不是唯一的解析器,但是比较简单的)#到这里先去看下边的第2点
items = soup.find('ul',class_='nav nav-list')
cate = items.find('ul')
cates = cate.find_all('li')
for i in cates:print(i.text.strip())
2. find() 和 find_all() 方法
打开那个网页后,右键 - 检查 或者 按F12,再按下图操作:
这时候右边的开发者工具栏就会在html源代码里定位到对应的位置,可以看到是右边的<div class="side_categories">
。接着打开下边的<ul>
标签,可以看到很多<li>
标签,再打开那里<li>
标签看,发现里面的文本就是这个书目的每一个书名:
而BeautifulSoup对象的两个方法,它们可以匹配html的标签和属性,把BeautifulSoup对象里符合要求的数据都提取出来。它俩的用法基本是一样的,区别在于,find()
只提取首个满足要求的数据,而find_all()
提取出的是所有满足要求的数据,以列表的形式返回,用法示例:
find(‘标签名’,class_
=‘属性名’,id=‘属性名’,=,【还可以使用其它属性,比如style
属性等】),find_all也如此。注意:可以只用标签定位,也可以只用属性定位,一个or多个都ok。还有class属性后边要加个"_"
。
然后我们就可以开始用它们定位啦!我先草草的说一下定位规则:定位了外层标签后可以继续往其内层的标签定位,但是匹配属性呢,只能匹配当前标签里的属性,还是拿个图来说吧!
但是要注意,你想定位哪个标签,就用哪个标签的属性来匹配
(不懂的话,自己多试试就知道辽 加油ヾ(◍°∇°◍)ノ゙)
items = soup.find('ul',class_='nav nav-list')
#因为我们要获取所有书的目录,可以选择先定位到所有书目标签'li'的外层标签'ul',通过定位'ul'标签和属性提取我们想要的数据。
#(这里还选用了class_属性定位,是因为前面还有其他的'ul'标签。
#而且我这里选用find定位,只会定位到第一个匹配到的。
#为了避免匹配到前边的'ul'标签位置,再加上属性来定位会更精确。
#那这里那么多标签,总不可能一个个翻吧,这时可以在开发者工具按 Ctrl+F ,搜索你想搜的内容,然后就会高亮显示出来啦,像下边我发的图
#哦对了,可以print一下cate的类型,是一个'Tag'对象cate = items.find('ul')
#接着我这选择了继续定位内层的'ul'标签。cates = cate.find_all('li')
#这里用的是find_all,返回所有跟'li'标签匹配的'Tag'对象组成的列表。#好,到这里又可以看下边第3点了。
for i in cates:print(i.text.strip())
3. Tag对象常用方法
方法 / 属性 | 作用解释 |
---|---|
find() 和 find_all() | 与BS对象一样,Tag对象也有此方法,这也是为什么能从BS对象定位到外层标签后(得到的是Tag对象),还能再继续定位内层标签(提取Tag中的Tag,得到的依然是Tag对象) |
text | 提取Tag中的文字,返回类型是 ‘str’。如,Tag.text。 |
[‘属性名’] | 输入参数:属性名,可以提取Tag中的属性的值,返回类型是 ‘str’。如,Tag[‘属性名’],得到的是属性值。(注意只能提取当前所属标签的属性值) |
补充:str.strip()
此方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
#遍历这个cates列表(每个元素的Tag对象,也是每个 li 元素)
for i in cates:print(i.text.strip())#打印li中的文字,因为前后都有很多空格,就用这个strip()方法去除。
部分运行结果:
简单不简单不(/≧▽≦)/
感觉这里还是说的有点详细又有点不详细,哪儿不清楚的可以现在本地编译器多试一试,还不懂呢善用搜索或者问我也尽力解答啦~!也可以来问我拿一个清楚详细流程图,为什么不直接发在这呢,咳咳我不知道0.0
之后这些就不会再那么一步步说了,可能是几句简单的注释,或者没有~!
给个练习吧
要求:爬取网上书店Books to Scrape中的书名+价格+评分,并且打印提取到的信息。
需要注意:如何获取完整的书名,还有评分的获取。
部分运行结果大概这样:
————————每个人都在抱怨生活不易,可是都在默默为生活打拼————————
这篇关于python爬虫基础Ⅰ——requests、BeautifulSoup:书本信息的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!