1.学习爬虫的好处
提升编程技能:爬虫开发需要掌握编程基础,特别是网络请求、HTML/CSS/JavaScript解析、数据存储和异常处理等技能。通过学习爬虫,你可以巩固和提升你的编程技能,特别是Python等编程语言的应用能力。
数据驱动决策:在当今数据为王的时代,数据是做出明智决策的重要依据。通过爬虫,你可以获取到各种公开的数据资源,如市场分析、用户行为、行业趋势等,从而为你的个人决策或商业决策提供有力支持。
自动化处理任务:爬虫可以实现自动化处理任务,如数据抓取、信息监控、报表生成等。这些任务如果手动完成,不仅费时费力,而且容易出错。通过学习爬虫,你可以将这些繁琐的任务自动化,提高工作效率和准确性。
增强解决问题能力:爬虫开发过程中会遇到各种挑战,如反爬虫机制、动态加载内容、验证码识别等。解决这些问题需要综合运用多种技术和方法,如分析网络请求、模拟用户行为、使用代理IP等。这些过程将锻炼你的问题解决能力和创新思维。
拓宽职业道路:爬虫技能在多个职业领域都有广泛的应用,如数据分析师、数据科学家、产品经理、市场分析师等。掌握爬虫技能将使你更具竞争力,拓宽你的职业道路和发展空间。
应对数据孤岛问题:在许多组织和企业中,数据往往分散在不同的系统和平台中,形成数据孤岛。通过学习爬虫,你可以实现不同系统之间的数据抓取和整合,打破数据孤岛,促进数据的共享和利用。
了解互联网运作机制:爬虫的工作原理涉及到网络协议、HTTP请求、服务器响应等多个方面。通过学习爬虫,你可以更深入地了解互联网的运作机制,理解网页是如何被加载和渲染的,以及数据是如何在网络中传输的。
2. HTTP协议的基本概念
全称:Hypertext Transfer Protocol(超文本传输协议)。
作用:用于从WWW服务器传输超文本到本地浏览器的传送协议,保证计算机正确快速地传输超文本文档,并确定传输文档中的哪一部分以及如何显示(如文本先于图形)。
层次:HTTP协议是应用层协议,运行于TCP/IP协议之上,通过TCP或TLS(加密的TCP连接)发送。
模型:采用客户端-服务器架构模式,客户端向服务器发送请求,服务器返回相应的响应。
2.1 HTTP协议的特点
无状态:HTTP协议对事务的处理没有记忆能力,每次请求都需要提供完整的请求信息。
无连接:HTTP协议不需要在客户端和服务器之间建立持久的连接,每个请求都是独立的,服务器处理请求后立即关闭连接(但HTTP 1.1版本支持长连接)。
面向对象:HTTP协议可以传输任何类型的数据对象,如HTML、XML、JSON、图片、音频、视频等。
无阻塞:HTTP协议不会限制客户端的请求数量和大小,使得服务器可以处理大量的请求。
可缓存:HTTP协议允许客户端缓存服务器响应的内容,以提高响应速度和减少网络流量。
2.2 HTTP协议的请求与响应
(1)请求报文
格式:请求报文由请求行、请求头部、空行和请求数据(可选)四部分组成。
请求行:包括请求方法(如GET、POST)、请求URL和HTTP协议版本信息。
请求头部:包含多个字段,用于告知服务器一些额外的信息,如客户端类型、支持的内容格式、是否支持压缩等。
(2)响应报文
格式:响应报文由状态行、响应头部、空行和响应数据(可选)四部分组成。
状态行:包括HTTP协议版本、状态码和状态信息,用于描述请求的处理结果。
响应头部:包含多个字段,用于描述响应的各种属性信息,如内容类型、内容编码、长度等。
2.3 HTTP协议的状态码
HTTP协议定义了多种不同的状态码,每个状态码都表示服务器对请求的响应状态。常见的状态码包括:
1xx(信息性状态码):表示请求已经被接收,继续处理。
2xx(成功状态码):表示请求已经被成功接收、理解和处理。
3xx(重定向状态码):表示需要进行额外操作才能完成请求。
4xx(客户端错误状态码):表示客户端发送的请求有误,服务器无法处理。
5xx(服务器错误状态码):表示服务器在处理请求的过程中发生了错误。
2.4 URI与URL
HTTP 协议使用 URI 定位互联网上的资源。因为 URI 可以访问到互联网上任意位置的资源。
URI(Uniform Resource Ide ntifier,统一资源标识符),用字符串标识某一互联网资源。
URL(Uniform Resource Locator,统一资源定位符),表示资源的地点(互联网上所处的位置)
URL是URI的一个子集,它特指那些能够定位到互联网上资源的URI。换句话说,所有的URL都是URI,但不是所有的URI都是URL。URL通常指的是能够通过网络协议访问的资源的地址。
URI 的格式:
3. 爬虫程序常用库
3.1 requests 库
requests
是 Python 中一个常用的 HTTP 请求库,通过它可以方便地发送 HTTP/1.1 请求。
它可以简化 HTTP 请求的过程,支持自动处理重定向、cookies 等功能,同时支持多种认证方式等。
3.2 requests 库基本使用
(1) 安装 requests 库
使用 requests
库,需要先安装。可以通过 pip
命令来安装:
python">pip install requests
(2) 导入 requests 库
安装完成后,就可以在 Python 中导入使用:
python">import requests
(3) requests
的常用方法
python">requests.get(url, params=None, **kwargs)
说明:
-
发送 GET 请求
-
url
为请求的 URL -
params
为请求参数(字典或者字符串) -
**kwargs
其它参数,如 headers、timeout 等
python">requests.post(url, data=None, json=None, **kwargs)
说明:
-
发送 POST 请求
-
url
为请求的 URL -
data
为 POST 请求的数据(字典或者字符串) -
json
为 POST 请求的 JSON 数据, -
**kwargs
其它参数,如 headers、timeout 等
python">requests.put(url, data=None, **kwargs)
说明:
-
发送 PUT 请求,
-
url
为请求的 URL -
data
为 PUT 请求的数据(字典或者字符串) -
**kwargs
其它参数,如 headers、timeout 等
python">requests.delete(url, **kwargs)
说明:
-
发送 DELETE 请求
-
url
为请求的 URL -
**kwargs
其它参数,如 headers、timeout 等
其中,**kwargs
为可选参数,支持以下参数:
-
headers
: 请求头部 -
cookies
: cookies -
auth
: 认证 -
timeout
: 超时时间 -
allow_redirects
: 是否允许重定向,默认为True
-
proxies
: 代理 -
verify
: 是否验证 SSL 证书,默认为True
-
cert
: SSL 证书
例:
python">import requests
# 发送 GET 请求
response = requests.get('https://www.baidu.com/')
print(response.status_code) # 响应状态码
print(response.text) # 响应内容
# 发送 POST 请求
data = {'key1': 'value1', 'key2': 'value2'}
response = requests.post('https://httpbin.org/post', data=data)
print(response.json()) # 响应内容(JSON 格式)
说明:
-
上述代码分别演示了使用
requests
发送 GET 和 POST 请求,获取响应状态码和内容,并将 POST 请求的数据传递给data
参数。 -
https://httpbin.org/post 是一个 HTTP 请求和响应测试网站,可以用于测试 HTTP 客户端请求的功能。你可以向该网站发送请求,然后它将返回一些关于该请求的信息,包括请求头、响应头、请求方法、请求数据等等。这对于调试和测试 HTTP 请求非常有用。
(4)处理 HTTP 响应内容
处理 HTTP 响应内容通常需要根据实际情况选择合适的方式,可以使用 requests
库提供的 text
和 content
属性获取响应内容,也可以使用其他库来处理。
(5) 获取文本内容
使用 requests
库发送 HTTP 请求并获取响应时,可以使用 text
属性来获取响应的文本内容。
例如:
python">import requests
response = requests.get('http://www.example.com')
print(response.text)
说明:
-
这里将请求的响应赋值给
response
变量; -
然后使用
text
属性来获取文本内容。如果响应中的内容是文本,那么这种方式非常方便,可以直接获取到文本内容进行后续处理。
(6) 获取二进制数据
如果响应中包含的是二进制数据(例如:图片、音频、视频等),那么使用 content
属性可以获取这些数据。
例如:
python">import requests
response = requests.get('http://www.example.com/image.jpg')
with open('image.jpg', 'wb') as f:f.write(response.content)
说明:
-
这里将响应的二进制数据保存到本地文件中,使用了
content
属性获取响应内容。 -
需要注意的是,如果响应中包含的是二进制数据,那么不能直接使用
text
属性来获取内容,否则可能会出现编码等问题。此时应该使用content
属性获取响应内容,并根据实际需要进行进一步处理。
(7) 其他处理方式
除了使用 requests
库提供的 text
和 content
属性获取响应内容之外,还可以使用其他库来处理 HTTP 响应内容,例如:
-
BeautifulSoup
库:用于解析 HTML 和 XML 文档,可以方便地提取其中的数据。 -
lxml
库:也用于解析 HTML 和 XML 文档,性能比BeautifulSoup
更好。 -
json
库:用于解析 JSON 格式的数据。
根据实际情况选择合适的方式来处理 HTTP 响应内容,可以提高代码的可读性和可维护性。
3.3 BeautifulSoup 库基本使用
BeautifulSoup 是 Python 的一个 HTML 或 XML 解析库,可以方便地从 HTML 或 XML 文档中提取数据。
它的主要功能包括解析 HTML 或 XML 文档、搜索文档树、遍历文档树、修改文档树等。
使用 BeautifulSoup 库可以大大简化网页数据的解析和提取过程,减少爬虫代码的编写难度。
BeautifulSoup 支持多种解析器,包括 Python 自带的标准库解析器 html.parser、 lxml 解析器和 html5lib 解析器等。可以根据需要选择不同的解析器进行解析。
BeautifulSoup 对象的基本操作主要包括创建 BeautifulSoup 对象、解析 HTML 文档、搜索文档中的元素、修改 HTML 文档等。
(1)安装BeautifulSoup库
python">pip install BeautifulSoup4
(1) BeautifulSoup 的基本操作
BeautifulSoup(html, 'html.parser')
:将 HTML 代码解析为 BeautifulSoup 对象。
需要传入两个参数:被解析的文本和解析器。
常用的解析器有 html.parser、lxml 和 html5lib。
python">from bs4 import BeautifulSoup
import requests
url = 'https://www.example.com/'
response = requests.get(url)
html = response.text
soup = BeautifulSoup(html, 'html.parser')
(2) 标签选择器
在 BeautifulSoup 中,标签选择器是最常用的选择器之一,可以通过标签名直接选取指定标签。
-
soup.find('tag')
:返回第一个匹配到的标签 -
soup.find_all('tag')
:返回所有匹配到的标签 -
soup.select('css_selector')
:使用 CSS 选择器获取标签
下面是一个使用标签选择器的示例:
python">from bs4 import BeautifulSoup
html = """
<!DOCTYPE html>
<html>
<head><title>网页标题</title>
</head>
<body><h1>文章标题</h1><p>这是第一段文字</p><p>这是第二段文字</p>
</body>
</html>
"""
soup = BeautifulSoup(html, 'html.parser')
# 选取标题标签
title_tag = soup.title
print(title_tag)
# 选取文章标题标签
h1_tag = soup.h1
print(h1_tag)
# 选取第一段文字标签
p_tag1 = soup.p
print(p_tag1)
# 选取第二段文字标签
p_tag2 = soup.find_all('p')[1]
print(p_tag2)
输出结果如下:
<title>网页标题</title> <h1>文章标题</h1> <p>这是第一段文字</p> <p>这是第二段文字</p>
说明:
-
soup.p
选取的是第一个<p>
标签。 -
find_all
方法和列表索引的方式选取了第二个<p>
标签。 -
find
方法返回第一个匹配的标签 -
find_all
方法返回所有匹配的标签,返回结果均为一个Tag
对象。
在使用标签选择器时,需要注意标签名的大小写。例如,soup.p
可以选取<p>
标签,但无法选取<P>
标签。
同时,如果选取不存在的标签,将会返回None
类型。
(3) 标签属性选择器
-
soup.find('tag', attrs={'attribute': 'value'})
:返回第一个匹配到的带有指定属性的标签。 -
soup.find_all('tag', attrs={'attribute': 'value'})
:返回所有匹配到的带有指定属性的标签。 -
soup.select('tag[attribute=value]')
:使用 CSS 选择器获取带有指定属性的标签。
python">from bs4 import BeautifulSoup
html_doc = """
<html>
<head><title>Example</title>
</head>
<body><div id="content"><p class="first">This is the first paragraph.</p><p class="second" custom="123">This is the second paragraph.</p><p class="second">This is the third paragraph.</p></div>
</body>
</html>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
# 选择所有具有 class="second" 属性的 <p> 标签
second_paragraphs = soup.select('p[class=second]')
for p in second_paragraphs:print(p.text)
# 选择具有 custom 属性的 <p> 标签
custom_paragraphs = soup.select('p[custom]')
for p in custom_paragraphs:print(p.text)
(4) 获取标签内容
获取标签内容可以使用BeautifulSoup对象的.text
属性或.string
属性来获取。这两个属性可以获取标签内的纯文本内容,但有一些区别:
-
tag.text
:获取标签的纯文本内容。可以获取当前标签及其子标签内的所有文本内容,并将其拼接成一个字符串返回。使用.text
属性获取标签的文本内容非常方便,而且适用于大多数情况。 -
tag.string
:获取标签的纯文本内容。只能获取当前标签内的文本内容,当标签内含有多个字符串时,返回值为None
。 -
tag.get('attribute')
:获取标签指定属性的值。
假设有以下HTML文档:
python"><html>
<head><title>Example</title>
</head>
<body><h1>Hello World</h1><p>This is an example page.</p><ul><li>Item 1</li><li>Item 2</li></ul>
</body>
</html>
使用 BeautifulSoup 解析后,可以获取各个标签的内容:
python">from bs4 import BeautifulSoup
html_doc = """
<html>
<head><title>Example</title>
</head>
<body><h1>Hello World</h1><p>This is an example page.</p><ul><li>Item 1</li><li>Item 2</li></ul>
</body>
</html>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
# 获取h1标签的文本内容
h1 = soup.find('h1')
print(h1.text) # Hello World
# 获取p标签的文本内容
p = soup.find('p')
print(p.text) # This is an example page.
# 获取ul标签的文本内容
ul = soup.find('ul')
print(ul.text) # Item 1\nItem 2\n
# 获取li标签的文本内容
li = soup.find('li')
print(li.text) # Item 1