课程目标
- 理解网络爬虫的基本概念及其在数据收集中的重要性
- 掌握使用
requests
库发起HTTP请求并获取网页数据 - 学习JSON数据格式的解析方法,并能够在Python中进行操作
课程内容
网络爬虫简介
网络爬虫(Web Crawler)是一种自动遍历网页的程序,它能够访问网页并从中提取信息。在Python中,我们可以使用requests
库来实现这一功能。
HTTP协议
HTTP是一种协议,它规定了客户端(比如你的浏览器)和服务器之间如何交流信息。
- 请求(Request):当你在浏览器中输入一个网址(URL),浏览器就会向服务器发送一个HTTP请求。这个请求包含了你想要获取的资源的信息,比如网页、图片或视频。
- 响应(Response):服务器接收到请求后,会处理这个请求,并返回一个HTTP响应。这个响应包含了请求的资源,比如你请求的网页内容,以及一些状态信息,比如是否成功获取了资源。
HTTP报文
- HTTP请求报文
假设你通过浏览器访问一个网页,你的浏览器可能会发送如下的HTTP请求报文到服务器:
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
-
请求行:
GET /index.html HTTP/1.1
表示这是一个HTTP/1.1协议的GET请求,请求的资源是/index.html
。 -
请求头:包含了请求的一些附加信息,比如:
Host
:请求的服务器域名。User-Agent
:发出请求的用户代理(通常是浏览器)信息。Accept
:客户端能够处理的媒体类型。Accept-Language
:客户端偏好的语言。Accept-Encoding
:客户端能够处理的压缩格式。Connection
:通常设置为keep-alive
以保持连接,减少重复连接的开销。
-
HTTP响应报文
HTTP/1.1 200 OK
Date: Mon, 14 Sep 2024 12:34:56 GMT
Server: Apache/2.4.1 (Unix)
Last-Modified: Wed, 08 Sep 2024 23:10:00 GMT
Content-Length: 12345
Content-Type: text/html
Connection: keep-alive
<html>
<head>
<title>Example Web Page</title>
</head>
<body>
<h1>Welcome to Example.com</h1>
<p>This is an example web page.</p>
</body>
</html>
- 状态行:
HTTP/1.1 200 OK
表示服务器成功处理了请求,并且返回了状态码200,表示请求成功。 - 响应头:包含了响应的一些附加信息,比如:
Date
:响应生成的日期和时间。Server
:服务器软件的信息。Last-Modified
:资源最后被修改的时间。Content-Length
:响应体的长度。Content-Type
:响应体的媒体类型。Connection
:表示连接是否保持。
- 响应体:包含了请求的资源内容,在这个例子中是HTML代码。
这个响应报文的主体部分是HTML代码,表示请求的网页内容。
请注意,实际的HTTP报文可能会包含更多的头部字段,具体取决于请求和响应的上下文。
HTTPS
HTTPS(全称为 Hypertext Transfer Protocol Secure)是HTTP的安全版本,它在HTTP的基础上通过SSL/TLS协议提供了数据加密
请求的发送
使用requests
库,我们可以轻松地发送HTTP请求。首先,我们需要导入requests
模块,然后使用其方法来发送请求。
import requests
# GET请求,获取网页内容
response = requests.get('https://www.xxx.com/')
print(response.text) # 打印网页的源代码
响应对象属性
每次调用requests
发送请求后,都会返回一个Response
对象。该对象包含了响应的详细信息,如状态码、头部、内容等。
status_code
: 响应状态码headers
: 响应头部content
: 响应内容(字节格式)text
: 响应内容(解码后的字符串格式)json()
: 解析JSON响应内容
requests模块的常用方法
requests
模块提供了一系列方法来发送不同类型的HTTP请求。
get(url, params=None)
: 发送GET请求post(url, data=None)
: 发送POST请求put(url, data=None)
: 发送PUT请求delete(url)
: 发送DELETE请求head(url)
: 发送HEAD请求
GET请求
GET请求是最常用的HTTP方法之一,通常用于请求服务器发送资源。GET请求应该只用于获取数据,而不是修改服务器上的资源。
# 发送GET请求
response = requests.get('https://api.example.com/data')
print(response.text) # 打印获取的资源内容
当使用GET请求时,可以通过params
参数传递查询字符串,服务器根据查询字符串返回相应的数据。
# 发送GET请求并传递查询参数
params = {'key1': 'value1', 'key2': 'value2'}
response = requests.get('https://api.example.com/data', params=params)
POST请求
POST请求用于向服务器提交数据进行处理,例如表单提交。服务器通常会根据提交的数据进行一些操作,如创建新的资源。
# 发送POST请求
data = {'key1': 'value1', 'key2': 'value2'}
response = requests.post('https://api.example.com/submit', data=data)
print(response.text) # 打印服务器响应的内容
POST请求的数据可以通过data
参数传递,通常是字典类型,requests
会自动将其编码为表单提交所需的格式。
PUT请求
PUT请求与POST类似,也是用于向服务器提交数据。不同之处在于PUT通常用于更新服务器上的现有资源或创建新资源,而POST用于创建新资源。
# 发送PUT请求
data = {'key1': 'value1', 'key2': 'value2'}
response = requests.put('https://api.example.com/resource/123', data=data)
print(response.text) # 打印服务器响应的内容
PUT请求通常用于更新资源,URL中包含了要更新的资源标识符。
DELETE请求
DELETE请求用于删除服务器上的资源。通过指定的URL,服务器将删除对应的资源。
# 发送DELETE请求
response = requests.delete('https://api.example.com/resource/123')
print(response.text) # 打印服务器响应的内容
DELETE请求通常不需要传递额外的数据,只需要指定要删除的资源URL。
HEAD请求
HEAD请求与GET请求相似,但它只请求资源的头部信息,不包括资源的主体。HEAD请求常用于检查资源是否存在,或者获取资源的元数据。
# 发送HEAD请求
response = requests.head('https://api.example.com/data')
print(response.status_code) # 打印状态码,200表示资源存在
print(response.headers) # 打印响应头信息
HEAD请求不返回资源内容,只返回头部信息,因此可以用来检查资源的状态或获取资源的元数据而不加载整个资源。
请求头和查询参数
在发送请求时,我们经常需要设置请求头或传递查询参数。
# 设置请求头
headers = {
'User-Agent': 'Mozilla/5.0',
'Accept': 'application/json'
}
# 发送GET请求,传递查询参数
params = {'key': 'value'}
response = requests.get('https://api.example.com/data', headers=headers, params=params)
JSON数据的解析
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。
# 请求JSON数据
response = requests.get('https://api.example.com/data')
data = response.json() # 将响应内容解析为JSON对象
# 访问解析后的数据
print(data['key'])
cookies
在发送请求时,我们可能需要设置cookies,以便服务器能够识别用户身份。
示例
cookies = {
'sessionid': '1234567890'
}
response = requests.get('https://api.example.com/data', cookies=cookies)
JSON讲解
函数 | 功能描述 | 示例代码 |
---|---|---|
json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw) | 将Python对象编码成JSON字符串。 | import json data = {"name": "John", "age": 30} json_string = json.dumps(data) |
json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw) | 将Python对象编码成JSON字符串并写入到文件。 | import json data = {"name": "John", "age": 30} with open('data.json', 'w') as f: json.dump(data, f) |
json.loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw) | 将JSON字符串解码成Python对象。 | import json json_string = '{"name": "John", "age": 30}' data = json.loads(json_string) |
json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw) | 从文件中读取JSON字符串并解码成Python对象。 | import json with open('data.json', 'r') as f: data = json.load(f) |
json.JSONDecoder() | 创建一个JSON解码器对象。 | import json decoder = json.JSONDecoder() data = decoder.decode('{"name": "John", "age": 30}') |
json.JSONEncoder() | 创建一个JSON编码器对象。 | import json encoder = json.JSONEncoder() json_string = encoder.encode({"name": "John", "age": 30}) |
json.tool.* | 提供命令行界面来验证和格式化JSON。 | 命令行中使用 python -m json.tool |
附录
响应状态码
状态码 | 类别 | 含义 |
---|---|---|
100 | 信息性状态码 | 继续 |
101 | 信息性状态码 | 切换协议 |
200 | 成功 | OK |
201 | 成功 | 创建成功 |
202 | 成功 | 接受 |
203 | 成功 | 非授权信息 |
204 | 成功 | 无内容 |
205 | 成功 | 重置内容 |
206 | 成功 | 部分内容 |
300 | 重定向 | 多种选择 |
301 | 重定向 | 永久移动 |
302 | 重定向 | 临时移动(以前称为“重定向”) |
303 | 重定向 | 查看其他位置 |
304 | 重定向 | 未修改 |
307 | 重定向 | 临时重定向(不允许POST变更为GET) |
308 | 重定向 | 永久重定向(不允许POST变更为GET) |
400 | 客户端错误 | 错误请求 |
401 | 客户端错误 | 未授权 |
402 | 客户端错误 | 需要付款 |
403 | 客户端错误 | 禁止访问 |
404 | 客户端错误 | 未找到 |
405 | 客户端错误 | 方法不允许 |
406 | 客户端错误 | 不接受 |
407 | 客户端错误 | 需要代理授权 |
408 | 客户端错误 | 请求超时 |
409 | 客户端错误 | 冲突 |
410 | 客户端错误 | 已删除 |
411 | 客户端错误 | 需要有效长度 |
412 | 客户端错误 | 未满足前提条件 |
413 | 客户端错误 | 请求实体过大 |
414 | 客户端错误 | 请求URI过长 |
415 | 客户端错误 | 不支持的媒体类型 |
416 | 客户端错误 | 请求范围不符合要求 |
417 | 客户端错误 | 预期失败 |
500 | 服务器错误 | 内部服务器错误 |
501 | 服务器错误 | 未实现 |
502 | 服务器错误 | 错误的网关 |
503 | 服务器错误 | 服务不可用 |
504 | 服务器错误 | 网关超时 |
505 | 服务器错误 | HTTP版本不受支持 |
请求头字段解释
字段名称 | 描述 | 示例值 |
---|---|---|
authority | HTTP/2协议中的请求目标服务器权威名称,相当于HTTP/1中的Host字段 | ‘tgfly.huizejiuzhou.com’ |
accept | 客户端能够接受的内容类型 | ‘application/json, text/plain, /’ |
accept-language | 客户端能够接受的语言,优先级从高到低 | ‘zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6’ |
cache-control | 控制响应的缓存行为 | ‘no-cache’ |
content-type | 请求体的媒体类型 | ‘application/json’ |
origin | 请求发起的源站点,用于服务器判断是否允许跨域请求 | ‘https://tgfly.huizejiuzhou.com’ |
pragma | 告诉中间代理不要缓存响应,主要用于HTTP/1 | ‘no-cache’ |
referer | 请求是从哪个页面发起的,用于服务器分析请求来源 | ‘https://tgfly.huizejiuzhou.com/login’ |
sec-ch-ua | 用户代理字符串的一部分,标识浏览器类型和版本 | ‘“Chromium”;v=“122”, “Not(A:Brand”;v=“24”, “Microsoft Edge”;v=“122”’ |
sec-ch-ua-mobile | 请求是否来自移动设备 | ‘?0’ |
sec-ch-ua-platform | 用户的操作系统平台 | ‘“Windows”’ |
sec-fetch-dest | 请求的目的地 | ‘empty’ |
sec-fetch-mode | 请求是否使用CORS模式 | ‘cors’ |
sec-fetch-site | 请求是否来自同一源站点 | ‘same-origin’ |
user-agent | 提供关于用户浏览器、操作系统和设备的信息 | ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0’ |