大家好呀~今天是数据分析课程的第七课,接下来的两节课,我们会学习爬虫的一些基础知识和基本操作。这节课主要是关于爬虫的基本概念、原理、流程、request
和 response
两个方法的使用,前端的一些基础知识,以及如何用 xpath
来解析网页等。
一、什么是爬虫?
爬虫是请求网站并提取数据的自动化程序。
二、爬虫的基本流程
1、发起请求
通过HTTP库目标站点发起请求,即发送一个 Request
,请求可以包含额外的 headers
等信息,等待服务器响应。
2、获取响应内容
如果服务器能够正常响应,会得到一个 Response
,Response
的内容便是所要获取的页面内容,类型可能有 HTML
,Json
字符串,二进制数据(如图片视频)等类型。
3、解析内容
得到的内容可能是 HTML
,可以用正则表达式,网页解析库进行解析。可能是 Json
,可以直接转为 Json
对象解析,可能是二进制数据,可以做保存或者进一步的处理。
4、保存数据
保存形式多样,可以存为文本,也可以保存至数据库,或者保存特定格式的文件。
三、Request
和 Response
- 浏览器发送消息给给该网址所在的服务器,这个过程叫做 HTTP Request。
- 服务器收到浏览器发送的消息后,能够根据浏览器发送消息的内容,做响应处理,然后把消息回传给浏览器。这个过程叫做 HTTP Response。
- 浏览器收到服务器的 Response 信息后,会对信息进行响应处理,然后展示。
查看浏览器的请求和响应:
1、Request
Request
是请求,在浏览器输入地址,回车,就是一个请求。
(1)请求方式
主要有 get
、post
两种类型,另外还有 HEAD
、PUT
、DELETE
、OPTIONS
等(这些都不常用)。
(2)请求的 URL
URL 全称为统一资源定位符,如一个网页的文档、一张图片、一个视频等都可以用 URL 来确定。
(3)请求头
包含请求时的头部信息,如 User-Agent、host、Cookies 等信息。
(4)请求体
请求时额外携带的数据如表单提交时的表单数据。
2、Response
Response
是响应,服务器根据请求,返回数据到浏览器显示,就是一个响应。
(1)响应状态
有多种响应状态,如200代表成功、301跳转、404找不到页面、502服务器错误。
(2)响应头
如内容类型、内容长度、服务器信息、设置 Cookie 等等。
(3)响应体
最主要的部分,包含了请求资源的内容,如网页 HTML、图片二进制数据等。例如:
# 导入网络请求模块(该模块需要使用pip install requests 安装)
import requests
# 创建请求头
headers = {
"User-Agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'
}
# 发送网络请求
response = requests.get(url='https://www.baidu.com',headers = headers)
# 获取请求的内容
print(response.content.decode('utf-8'))
print(response.text)
# 获取响应头
print(response.headers)
# 状态码
print(response.status_code)
四、能抓取什么样的数据?
1、网页文本
如HTML文档、Json格式的文本等。
2、图片
获取到的是二进制文件,保存为图片格式。
3、视频
获取到的是二进制文件,保存为视频格式。例如: 获取图片:
import requests
# 创建请求头
headers = {
"User-Agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'
}
# 发送网络请求
response = requests.get(url='https://www.baidu.com/img/bd_logo1.png'),headers = headers)
# 将获取的二进制内容进行保存
with open('./baidu.png','wb') as f:
f.write(response.content)
五、网页的解析方式
1、直接处理
例如:请求回来的就是一段字符串,我们可以简单处理后直接保存。
2、Json解析
例如:Ajax请求回来的一般都是 json 格式的数据,我们就需要从 json 中拿出我们想要的数据。
3、正则表达式
4、BeautifulSoup
5、PyQuery
6、XPath
解析库的选择可以根据爬取的网页具体情况酌情选择。
六、前端基础知识
1、HTML
HTML 的全称为 超级文本标记语言(HyperText Markup Language),它是标准通用标记语言下的一个应用,也是一种规范和标准,它通过标记符号来标记要显示的网页中的各个部分。网页文件本身是一种文本文件,通过在文本文件中添加标记符,可以告诉浏览器如何显示其中的内容(如:文字如何处理,画面如何安排,图片如何显示等)。
(1)HTML元素
① 根元素
<doctype> | 定义文档类型。 |
---|---|
<html> | 定义 HTML 文档。 |
② 元数据元素
<head> | 定义关于文档的信息。 |
---|---|
<meta> | 定义关于 HTML 文档的元数据。 |
<link> | 定义文档与外部资源之间的关系,一般用于引入样式表。 |
<base> | 定义页面上所有链接的默认地址或默认目标。 |
<title> | 定义文档标题。 |
<style> | 定义文档的样式信息。 |
③ 脚本元素
<script> | 定义客户端脚本。 |
---|---|
<noscript> | 定义当浏览器不支持脚本的时候所显示的内容 |
④ 块元素
<body> | 定义文档的主体。 |
---|---|
<h1>、<h2>...<h6> | 定义文档标题。 |
<p> | 定义文档段落。 |
<blockquote> | 定义块引用。 |
<ul>、<ul>、<dl> | 定义列表。 |
<table> | 定义表格。 |
⑤ 列表元素
无序列表
<ul> | 定义无序的列表。 |
---|---|
<li> | 定义列表项。 |
有序列表
<ol> | 定义有序的列表。 |
---|---|
<li> | 定义列表项。 |
定义列表
<dl> | 定义定义列表。 |
---|---|
<dt> | 定义定义术语。 |
<dd> | 定义定义描述。 |
⑥ 表格元素
<table> | 定义表格。 |
---|---|
<thead> | 定义表格的页眉。 |
<tbody> | 定义表格的主体。 |
<tfoot> | 定义表格的页脚。 |
<th> | 定义表格的表头行。 |
<tr> | 定义表格的行。 |
<td> | 定义表格单元。 |
⑦ 文本元素
文本格式化元素
<em> | 定义着重文字。 |
---|---|
<strong> | 定义加重语气。 |
<sup> | 定义上标字。 |
<sub> | 定义下标字。 |
<ins> | 定义插入字。 |
<del> | 定义删除字。 |
<b> | 定义粗体文本。 |
<i> | 定义斜体文本。 |
<big> | 定义大号字。 |
<small> | 定义小号字。 |
⑧ 链接与图像
<a> | 定义超链接 |
---|---|
<img> | 定义图像。 |
<map> | 定义图像地图。 |
<area> | 定义图像地图中的可点击区域。 |
⑨ <div>
和 <span>
<div> | 定义文档中的分区或节(division/section)。 |
---|---|
<span> | 定义 span,用来组合文档中的行内元素。 |
⑩ 表单元素
<form> | 定义供用户输入的表单。 |
---|---|
<input> | 定义输入域。 |
<textarea> | 定义文本域 (一个多行的输入控件)。 |
<lable> | 定义一个控制的标签。 |
<select> | 定义一个选择列表。 |
<option> | 定义下拉列表中的选项。 |
<optgroup> | 定义选项组。 |
<button> | 定义一个按钮。 |
<fieldset> | 定义域。 |
<legend> | 定义域的标题。 |
2、CSS
(1)CSS简介
CSS 是一种定义样式结构如字体、颜色、位置等的语言,用于描述网页上的信息格式化和现实的方式。CSS 样式可以直接存储于 HTML 网页或者单独的样式单文件。
(2)CSS类型
- 内联方式:样式定义在单个的 HTML元素中。
- 内部样式表:样式定义在 HTML 页的头元素中
-
外部样式表:将样式定义在一个外部的 CSS 文件中(
.css
文件),由 HTML 页面引用样式表文件
3、JavaScript
JavaScript 是一种属于网络的脚本语言,已经被广泛用于 Web 应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。通常 JavaScript 脚本是通过嵌入在 HTML 中来实现自身的功能的。
(1)JavaScript 语法
① js 代码能直接嵌入网页的任何地方,通常放在 <head></head>
中,但会要求用户把所有 js 代码都下载解析执行以后在呈现内容;
② 可以把代码单独的放在一个 .js
文件中,同时,多个页面可以引用同一份 .js
文件;
③ 页面中可以多次编写 <script></script>
,但是浏览器会按照顺序执行这些 JavaScript 代码;
④ JavaScript
中每个语句以 ;
结尾,每个语句块以 {…..}
包裹,注释用//
或 /* */
⑤ 所有类型都是定义变量都是用 var
,如果一个变量没有通过 var
申明就被使用,那么该变量就自动被申明为全局变量;
例:hello.html
<html>
<head>
<title>js</title>
<script type="text/javascript">
console.log("Hello javascript")
</script>
</head>
<body>
</body>
</html>
外部样式表
test.js
alert('Hello JS')
test.html
<html>
<head>
<title>js</title>
<script type="text/javascript" src='test.js'></script>
</head>
<body>
</body>
</html>
七、Xpath 的基本使用
1、简介
XPath 是一门在 XML 文档中查找信息的语言。 使用路径表达式来选取 XML 文档中的节点或者节点集。
注意:xpath 速度比较快,是爬虫在网页定位中的较优选择,但是很多网页前端代码混乱难以定位。
安装:
pip install -U lxml -i https://pypi.douban.com/simple
2、Xpath 语法
3、基础使用
# 导入 lxml 的 etree 库
from lxml import etree
data_str = """
<div>
<ul>
<li class="item-0"><a href="link1.html">first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html">third item</a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a>
</ul>
</div> """
# 注意: 该数据中缺少了一个 `li` 标签的闭合标签
# 利用 etree.HTML 可以将字符串或者 bytes 转化为 Element python对象,这个对象具有 Xpath 的方法
html = etree.HTML(data_str)
print(html)
# etree.tostring(html) 可以自动修正 HTML 代码,补全了缺胳膊少腿的标签
# 为了观察修改以后的 html 样子,根据修改后的 HTML 去写 Xpath
result = etree.tostring(html)
print(result.decode("utf-8"))
# 获取 class = item-1 的 a 标签的 href 属性
result = html.xpath('//li[@class="item-1"]/a/@href')
print(result)
4、Xpath练习:爬取百度 lol 贴吧前 50 页帖子标题
import requests
from lxml import etree
tiebaName = 'lol'
base_url = 'https://tieba.baidu.com/f?kw='+tiebaName+'&ie=utf-8&pn={}'
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'
}
# 构建请求连接
url_list = [] # 存储连接的列表
for i in range(1):
# 初始为第一页
url_list.append(base_url.format(i*50))
# 发送网络请求并得到相应内容
response = requests.get(url=url_list[0],headers = headers)
result_str = response.content.decode('utf-8')
# 由于爬取的内容被注释了,所以将注释去掉
result_str = result_str.replace('<!--','').replace('-->','')
html = etree.HTML(result_str)
# 获取每一页的连接
links = html.xpath('//li[@class=" j_thread_list clearfix"]//div[@class="threadlist_title pull_left j_th_tit "]//a[@rel="noreferrer"]/@href')
# 拼接成完整的连接
links = ['https://tieba.baidu.com/{}'.format(i) for i in links]
# 获取文字
texts = html.xpath('//li[@class=" j_thread_list clearfix"]//div[@class="threadlist_title pull_left j_th_tit "]//a[@rel="noreferrer"]/text()')
解析网页的重点是要找到你要提取的元素的标签特征,一般选取元素所具有的共同属性,本例中,所有帖子标题都有一个 class=" j_thread_list clearfix"
的属性,依靠这个属性来定位这些元素,从而取出对应的内容。