前言
爬虫的基本结构及工作流程
1. 确定目标
首先,确定你想要爬取的目标,包括目标网站或网页、需要提取的数据类型(如文本、图片、视频等)以及爬取的深度(单页、整个网站等)。
2. 获取网页内容
使用HTTP请求获取网页内容。这通常涉及发送GET或POST请求到目标网址。
3. 解析网页内容
解析获取的网页内容以提取有用的数据。这通常需要解析HTML或其他标记语言。
4. 数据提取
从解析后的网页内容中提取你需要的数据,如文本、链接、图片URL等。
5. 数据存储
将提取的数据存储到合适的地方,如文件、数据库或内存中。
6. 异常处理和日志记录
处理可能出现的异常情况,如网络错误、网页结构变更等,并记录日志以便后续分析和调试。
网络爬虫的基本工作流程:
初始化爬虫:设置初始URL和其他配置参数。
发送HTTP请求:使用HTTP库发送请求获取网页内容。
解析网页:使用解析库(如BeautifulSoup、lxml等)解析网页内容。
数据提取:根据网页结构从解析后的内容中提取数据。
存储数据:将提取的数据存储到文件、数据库或其他数据存储介质中。
检查结束条件:根据设定的结束条件(如爬取深度、时间限制等)决定是否继续爬取。
异常处理:处理可能出现的异常,并记录日志。
循环爬取:根据上述步骤循环执行,直到满足结束条件。
urllib网络请求库
urllib
是 Python 标准库中的一个模块,用于处理与 URL 相关的请求。它提供了一系列的模块来进行各种网络操作,如发送 HTTP 请求、处理 cookie、处理 URL 解析等。
urllib
主要模块:
urllib.request
: 用于打开和读取 URL。urllib.error
: 包含urllib.request
产生的异常。urllib.parse
: 用于解析 URL。urllib.robotparser
: 用于解析 robots.txt 文件。
主要功能:
1. 发送 HTTP 请求
urllib.request.urlopen()
方法可以用于发送 HTTP GET、POST、PUT、DELETE 等请求。
from urllib import request
with request.urlopen('https://www.example.com') as response:
html = response.read()
print(html)
2. URL 解析
urllib.parse
模块提供了 urlparse()
和 urljoin()
等函数,用于解析和构造 URL。
from urllib.parse import urlparse, urljoin
parsed_url = urlparse('https://www.example.com/path?query=value')
print(parsed_url.scheme) # 输出:'https'
print(parsed_url.netloc) # 输出:'www.example.com'
print(parsed_url.path) # 输出:'/path'
print(parsed_url.query) # 输出:'query=value'
base_url = 'https://www.example.com'
absolute_url = urljoin(base_url, '/path')
print(absolute_url) # 输出:'https://www.example.com/path'
3. 处理异常
urllib.error
模块定义了与 urllib.request
相关的异常,如 HTTPError
、URLError
等。
from urllib import request, error
try:
response = request.urlopen('https://www.nonexistent.com')
except error.URLError as e:
print(f"Failed to reach the server: {e.reason}")
4. 处理 Cookie
虽然 urllib
提供了基本的 Cookie 支持,但它的功能相对有限。在处理复杂的 Cookie 操作时,可能需要使用 http.cookiejar
模块。
from urllib import request, parse
url = 'https://www.example.com/post_endpoint'
data = {'key': 'value'}
# 将字典类型的数据转换为 URL 编码的字符串
data = parse.urlencode(data).encode()
req = request.Request(url, data=data, method='POST')
with request.urlopen(req) as response:
print(response.read().decode())
requests 网络请求库
requests
是被广泛使用的 HTTP 客户端库,它提供了简洁的 API,使得发送 HTTP 请求变得容易和直观。相较于 Python 的内置库 urllib
,requests
更为友好、功能丰富。
安装
你可以使用 pip
来安装 requests
:
pip install requests
请求网页的原理及流程
原理:
requests
库基于urllib3
,它是一个更低级别的库,提供了对 HTTP 连接的封装和管理。当你发送一个 HTTP 请求时,requests
会使用urllib3
来建立连接、发送请求和接收响应。
流程:
创建会话(Session):使用
requests.Session()
创建一个会话对象,这允许你在多个请求之间保持 cookies 和其他状态。构建请求:使用
requests.get()
,requests.post()
,requests.put()
等方法构建和发送 HTTP 请求。这些方法接受 URL、参数、头部、数据等参数。发送请求:
requests
库会处理与服务器的连接、请求头、数据传输等细节,然后发送 HTTP 请求。接收响应:一旦服务器响应,
requests
会接收并处理响应,提供响应状态码、头部、内容等信息。数据处理:你可以直接访问响应内容,或使用
json()
、text
、content
等方法获取内容。关闭会话:对于使用了会话的情况,最后需要关闭会话以释放资源。
主要功能
简单易用的 API:
requests
提供了简单直观的 API,使得发送 HTTP 请求变得非常容易。多种请求方法:支持 GET、POST、PUT、DELETE、HEAD 等多种 HTTP 请求方法。
自动解码:自动处理响应内容的编码,如 UTF-8。
文件上传:支持文件上传,包括表单和多部分上传。
会话管理:支持会话(Session),允许在多个请求之间保持 cookies、身份验证等状态。
SSL 证书验证:支持 SSL 证书验证,并提供了快速和简便的方式来处理 SSL/TLS 连接问题。
连接池管理:自动管理 HTTP 连接池,提高请求效率。
重定向和历史:自动处理 HTTP 重定向,并记录请求的历史。
异常处理:定义了一组异常类,如
requests.exceptions.RequestException
,方便错误处理。
应用代码:
# 发送 GET 请求
response = requests.get('https://www.baidu.com')
print(response.status_code)
print(response.text)
# 发送 POST 请求
data = {'key': 'value'}
response = requests.post('https://www.baidu.com/post', data=data)
print(response.json())
# 文件上传
files = {'file': open('file.txt', 'rb')}
response = requests.post('https://www.baidu.com/upload', files=files)
print(response.text)
# 会话管理
with requests.Session() as session:
session.get('https://www.example.com/login', params={'username': 'user', 'password': 'pass'})
response = session.get('https://www.example.com/dashboard')
print(response.text)
Postman 简介
Postman 是一个流行的 API 测试工具,它提供了一个直观、用户友好的界面,用于创建、测试和管理 HTTP 请求和 API。无论是测试 RESTful API、SOAP 服务还是 HTTP 请求,Postman 都为开发人员、测试人员和 API 设计者提供了一个强大的平台。
主要功能:
创建和发送请求:支持各种 HTTP 请求方法(如 GET、POST、PUT、DELETE、PATCH 等),并允许自定义请求头、请求参数、请求体等。
自动化测试:可以创建测试脚本来验证 API 的响应,例如检查响应状态码、响应时间、JSON 断言等。
环境和变量:支持环境变量和全局变量,方便管理不同环境(如开发、测试、生产)的配置。
集合和集合运行器:允许将相关的 API 请求组织成集合,并使用集合运行器批量运行这些请求。
数据驱动:支持 CSV 和 JSON 数据文件,可以使用这些文件进行数据驱动的测试。
身份验证:支持各种身份验证方式,如基本认证、摘要认证、OAuth 1.0、OAuth 2.0 等。
自定义脚本:使用 JavaScript 脚本,可以进行高级的数据处理和测试逻辑。
历史记录和收藏夹:保存你发送过的请求和响应,方便后续查看和复用。
团队协作:支持团队协作,可以与团队成员共享集合、环境和测试脚本。
使用步骤:
打开 Postman:安装完成后,打开 Postman 应用。
创建请求:在新建请求页签中,选择 HTTP 请求方法(如 GET、POST),输入 URL、请求头、请求体等。
发送请求:点击“发送”按钮,发送请求并查看响应。
测试和验证:在“测试”选项卡中,编写测试脚本来验证 API 响应。
保存和分享:将请求保存到集合中,或分享给团队成员。
管理环境和变量:在“环境”选项卡中管理环境变量和全局变量。
演示实用教程
以百度为例:
通过Postman测试访问情况:
返回数据内容:
所以Postman 是一个非常强大和灵活的 API 测试工具,它的直观界面和丰富的功能使得 API 测试和开发变得更加高效和便捷。无论你是开发人员、测试人员还是 API 设计者,都会发现 Postman 是一个不可或缺的工具,同时也是爬虫工程师必不可少的工具。
爬取百度搜索结果(附源码)
模拟用户搜索并解析搜索结果页面,未为了模拟更真实的用户请求,我们可以添加一些请求头信息,如用户代理、Referer、以及可能的其他请求头,以更好地模拟浏览器发出的请求。
# -*- coding:utf-8 -*-
import requests
from lxml import etree
import time
import os
class BaiDu_Spider(object):
def __init__(self, keyword):
"""初始化方法,设置基本属性和 URL"""
self.base_url = 'https://www.baidu.com/s?wd={}'
self.keyword = keyword
self.url = self.base_url.format(self.keyword) + '&pn={}&ie=utf-8'
def get_html(self, page):
"""发送请求获取页面内容,并解析页面内容"""
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36'
}
try:
# 发送 GET 请求
r = requests.get(self.url.format(page), headers=headers)
# 检查响应状态码,如果不是 200,则抛出异常
r.raise_for_status()
# 设置编码
r.encoding = 'utf-8'
# 使用 lxml 解析页面内容
res = etree.HTML(r.text)
# 提取搜索结果
selector = res.xpath('//div[@id="content_left"]/div[@class="result c-container new-pmd"]')
data_list = []
for data in selector:
item = {
'title': ''.join(data.xpath('./h3/a/text()')),
'link': ''.join(data.xpath('./h3/a/@href'))
}
data_list.append(item)
# 检查是否有下一页,返回搜索结果和是否有下一页的标志
flag = res.xpath('//div[@id="page"]/div/a[last()]/text()')
return data_list, bool(flag)
except requests.RequestException as e:
# 捕获 requests 异常
print(f"An error occurred: {e}")
return [], False
except Exception as e:
# 捕获其他异常
print(f"An unexpected error occurred: {e}")
return [], False
def save_data(self, item):
"""保存数据到文件"""
with open(crawl_result, 'a', encoding='utf-8') as f:
data = f"{item['title']}\t{item['link']}"
print(data)
f.write(data + '\n')
def main():
"""主函数,控制爬虫流程"""
n = 0
while True:
# 获取当前页的搜索结果和是否有下一页的标志
data_list, flag = spider.get_html(n)
# 遍历搜索结果,并保存数据
for data in data_list:
spider.save_data(data)
# 延迟 2 秒
time.sleep(2)
# 如果有下一页,继续爬取;否则退出
if flag:
n += 10
else:
print(f'程序已经退出,在{int(n / 10) + 1}页......')
break
if __name__ == '__main__':
# 设置搜索关键词和保存数据的文件路径
keyWord = 'Python'
crawl_result = os.path.join(os.getcwd(), f'crawl_{keyWord}.txt') # 获取当前目录并设置文件路径
# 创建爬虫对象并运行主函数
spider = BaiDu_Spider(keyWord)
main()
注意:百度的反爬虫机制可能会检测和阻止过于频繁或异常的请求,为了避免被封 IP,建议添加适当的延迟或使用代理 IP,并尽量模拟人类的搜索行为。此外,上述代码中的解析逻辑仍基于当前的搜索结果页面结构,如果百度更新了页面结构,可能需要更新解析逻辑。
今天的内容分享到这里了,创作不易,感谢大家的三连哦!