
🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手
🏳️🌈 个人博客主页:请点击——> 个人的博客主页 求收藏
🏳️🌈 Github主页:请点击——> Github主页 求Star⭐
🏳️🌈 知乎主页:请点击——> 知乎主页 求关注
🏳️🌈 CSDN博客主页:请点击——> CSDN的博客主页 求关注
👍 该系列文章专栏:请点击——>Python办公自动化专栏 求订阅
🕷 此外还有爬虫专栏:请点击——>Python爬虫基础专栏 求订阅
📕 此外还有python基础专栏:请点击——>Python基础学习专栏 求订阅
文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
❤️ 欢迎各位佬关注! ❤️
用 Python 写你的第一个网络爬虫:从零开始,轻松抓取网页数据
前言:数据世界的“魔法”之门
在这个信息爆炸的时代,数据无处不在。从商品价格到新闻头条,从天气预报到社交媒体动态,海量数据蕴藏着巨大的价值。然而,这些数据往往散落在互联网的各个角落,以非结构化的网页形式呈现。如何高效、自动化地获取这些数据呢?答案就是——网络爬虫 (Web Crawler)。
网络爬虫,顾名思义,就像一只勤劳的蜘蛛,在互联网这张巨大的“网”上爬行,根据你设定的规则,抓取并收集所需的信息。它能帮你省去大量手动复制粘贴的时间,将网页上的“非结构化”数据转化为你可以分析、利用的“结构化”数据。
本篇博客将作为你进入爬虫世界的第一站。我们将使用 Python 这一强大且易学的语言,手把手教你编写一个简单的网络爬虫,即使你是编程小白,也能轻松掌握数据抓取的乐趣。
准备工作:你的工具箱
在开始编写爬虫之前,我们需要确保你的开发环境已经准备就绪。
1. 安装 Python
如果你还没有安装 Python,请访问 Python 官方网站 下载并安装最新版本的 Python 3.x。安装时,请务必勾选“Add Python to PATH”选项,这样你就可以在命令行中直接运行 Python 了。
2. 学习基础 Python 知识 (如果需要)
虽然本教程尽量简化,但如果你对 Python 的变量、列表、循环和函数等基本概念有所了解,学习过程会更加顺畅。如果你是完全的编程新手,建议先花一些时间学习 Python 官方教程 的前几章。
3. 安装必要的第三方库
我们将使用两个核心的 Python 库来构建我们的爬虫:
requests: 用于发送 HTTP 请求,获取网页内容。BeautifulSoup4: 用于解析 HTML 和 XML 文档,从中提取数据。
打开你的命令行工具 (Windows 用户是 cmd 或 PowerShell,macOS/Linux 用户是 Terminal),运行以下命令来安装它们:
pip install requests beautifulsoup4
如果安装成功,你就可以开始你的爬虫之旅了!
手把手教学:编写你的第一个爬虫
我们将以一个经典的爬虫练习网站 http://quotes.toscrape.com/ 为例,目标是抓取该网站上的所有名言及其作者。
步骤一:理解网页结构 (知己知彼,百战不殆)
在开始写代码之前,最重要的一步是分析目标网页的结构。我们需要知道我们想要的数据(名言和作者)在 HTML 代码中的位置和特征。
- 打开目标网站: 在你的浏览器中访问
http://quotes.toscrape.com/。 - 打开开发者工具:
- 大多数浏览器可以通过右键点击页面上的任何元素,然后选择“检查”或“检查元素”来打开开发者工具。
- 或者使用快捷键:
F12(Windows/Linux) 或Cmd + Option + I(macOS)。
- 定位目标数据:
- 在开发者工具中,点击左上角的“选择元素”小图标 (一个鼠标箭头指向一个方块的图标)。
- 将鼠标移动到页面上的一条名言上,例如“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”,你会看到对应的 HTML 代码被高亮显示。
- 仔细观察,你会发现每条名言都包含在一个
<div class="quote">标签中。 - 名言本身在
<span class="text" itemprop="text">标签里。 - 作者在
<small class="author" itemprop="author">标签里。
通过这一步,我们明确了数据在 HTML 中的“身份信息”:它们都位于 div 标签中,并且带有特定的 class 属性。
步骤二:发送 HTTP 请求,获取网页内容
现在,我们使用 requests 库来模拟浏览器访问目标网页,获取其 HTML 内容。
import requests
# 目标网页的 URL
url = 'http://quotes.toscrape.com/'
try:
# 发送 GET 请求,获取网页响应
response = requests.get(url)
# 检查 HTTP 状态码,200 表示成功
if response.status_code == 200:
print("网页请求成功!")
# 获取网页的 HTML 内容
html_content = response.text
# print(html_content[:500]) # 打印前500个字符,查看是否成功获取
else:
print(f"网页请求失败,状态码:{response.status_code}")
except requests.exceptions.RequestException as e:
print(f"请求发生错误: {e}")
代码解释:
import requests: 导入requests库。url = 'http://quotes.toscrape.com/': 定义我们要抓取的网页地址。requests.get(url): 这是最核心的部分,它向指定的 URL 发送一个 HTTP GET 请求,并返回一个Response对象。response.status_code: 检查请求的状态码。200表示请求成功,服务器已返回网页内容。response.text: 获取响应的文本内容,这就是我们需要的 HTML 源代码。try...except: 这是一个错误处理机制,用于捕获在网络请求过程中可能发生的异常(例如网络断开)。
运行这段代码,如果看到“网页请求成功!”的输出,说明你已经成功迈出了第一步!
步骤三:解析网页内容
获取到 HTML 内容后,它还是一大串杂乱的字符串。我们需要一个工具来“理解”这些字符串,将它们组织成一个易于操作的结构。这时,BeautifulSoup 就派上用场了。
from bs4 import BeautifulSoup
import requests
url = 'http://quotes.toscrape.com/'
response = requests.get(url)
html_content = response.text
# 使用 BeautifulSoup 解析 HTML 内容
# 'html.parser' 是 Python 内置的解析器
soup = BeautifulSoup(html_content, 'html.parser')
print("网页解析成功!")
# print(soup.prettify()[:1000]) # 打印格式化后的HTML前1000字符,方便查看结构
代码解释:
from bs4 import BeautifulSoup: 从bs4库中导入BeautifulSoup类。BeautifulSoup(html_content, 'html.parser'): 创建一个BeautifulSoup对象。它接收两个参数:html_content: 我们从requests获取到的 HTML 字符串。'html.parser': 指定使用 Python 内置的 HTML 解析器。
现在,soup 对象就包含了整个网页的结构,我们可以像操作树形结构一样,方便地查找和提取其中的元素。
步骤四:提取所需数据
这是爬虫最核心的部分。根据我们在步骤一中对网页结构的分析,我们将使用 BeautifulSoup 的方法来定位并提取名言和作者。
from bs4 import BeautifulSoup
import requests
url = 'http://quotes.toscrape.com/'
response = requests.get(url)
html_content = response.text
soup = BeautifulSoup(html_content, 'html.parser')
# 查找所有 class 为 'quote' 的 div 标签
# 每个这样的 div 标签都包含一条名言和作者信息
quotes = soup.find_all('div', class_='quote')
# 创建一个列表来存储所有提取到的数据
all_quotes_data = []
# 遍历每一个 quote 标签,提取名言和作者
for quote_tag in quotes:
# 提取名言文本
text = quote_tag.find('span', class_='text').get_text()
# 提取作者
author = quote_tag.find('small', class_='author').get_text()
# 提取标签(可选)
# tags_elements = quote_tag.find('div', class_='tags').find_all('a', class_='tag')
# tags = [tag.get_text() for tag_element in tags_elements]
# 将提取到的数据存储为字典
quote_data = {
'text': text,
'author': author,
# 'tags': tags
}
all_quotes_data.append(quote_data)
# 打印提取到的数据
for data in all_quotes_data:
print(f"名言: {data['text']}")
print(f"作者: {data['author']}")
print("-" * 30)
print(f"\n成功提取了 {len(all_quotes_data)} 条名言。")
代码解释:
soup.find_all('div', class_='quote'): 这是BeautifulSoup最常用的方法之一。- 它会在整个
soup对象中查找所有符合条件的标签。 'div': 指定要查找的标签名是div。class_='quote': 指定标签的class属性必须是'quote'(注意class是 Python 关键字,所以这里用class_表示)。- 它会返回一个列表,其中包含了所有匹配的
div标签对象。
- 它会在整个
for quote_tag in quotes:: 遍历我们找到的每一个名言容器。quote_tag.find('span', class_='text'): 在当前的quote_tag(也就是一个<div class="quote">标签内部) 中,继续查找span标签,且class为'text'。find()方法只会返回第一个匹配的元素。.get_text(): 提取标签内部的纯文本内容,去除所有 HTML 标签。all_quotes_data.append(quote_data): 将每条名言和作者信息存储为一个字典,然后添加到all_quotes_data列表中。
运行这段代码,你将看到所有名言和作者清晰地打印在控制台上。
步骤五:保存数据
仅仅在控制台打印数据是不够的,通常我们需要将数据保存到文件中,以便后续分析或使用。这里我们演示如何将数据保存为 CSV (Comma Separated Values) 文件,这是一种常见的表格数据格式,可以用 Excel 或其他数据分析工具打开。
import csv
from bs4 import BeautifulSoup
import requests
url = 'http://quotes.toscrape.com/'
response = requests.get(url)
html_content = response.text
soup = BeautifulSoup(html_content, 'html.parser')
quotes = soup.find_all('div', class_='quote')
all_quotes_data = []
for quote_tag in quotes:
text = quote_tag.find('span', class_='text').get_text()
author = quote_tag.find('small', class_='author').get_text()
all_quotes_data.append({'text': text, 'author': author})
# 定义保存的文件名
filename = 'quotes.csv'
# 使用 csv 模块将数据写入 CSV 文件
with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
# 定义 CSV 文件的列名(表头)
fieldnames = ['text', 'author']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
# 写入表头
writer.writeheader()
# 写入所有数据
writer.writerows(all_quotes_data)
print(f"\n数据已成功保存到 {filename} 文件中。")
代码解释:
import csv: 导入 Python 内置的csv模块。with open(filename, 'w', newline='', encoding='utf-8') as csvfile::open()函数用于打开文件。filename: 我们指定的文件名quotes.csv。'w': 以写入模式打开文件(如果文件不存在则创建,如果存在则清空内容)。newline='': 这是csv模块推荐的参数,可以防止在 Windows 上写入空行。encoding='utf-8': 指定文件编码为 UTF-8,以支持中文字符或其他特殊字符。with语句确保文件在使用完毕后自动关闭,即使发生错误。
fieldnames = ['text', 'author']: 定义 CSV 文件的列名,这与我们字典的键相对应。writer = csv.DictWriter(csvfile, fieldnames=fieldnames): 创建一个DictWriter对象,它允许我们以字典的形式写入数据。writer.writeheader(): 写入 CSV 文件的表头。writer.writerows(all_quotes_data): 写入all_quotes_data列表中的所有字典数据。
运行这段代码后,你的项目目录下会生成一个 quotes.csv 文件,用 Excel 或文本编辑器打开,你就能看到整齐排列的名言和作者数据了!
完整代码示例
将以上所有步骤整合在一起,这就是你的第一个网络爬虫的完整代码:
import requests
from bs4 import BeautifulSoup
import csv
def scrape_quotes(url):
"""
抓取指定URL的名言和作者信息。
"""
all_quotes_data = []
try:
response = requests.get(url)
if response.status_code == 200:
print(f"成功访问 {url}")
html_content = response.text
soup = BeautifulSoup(html_content, 'html.parser')
quotes = soup.find_all('div', class_='quote')
for quote_tag in quotes:
text = quote_tag.find('span', class_='text').get_text()
author = quote_tag.find('small', class_='author').get_text()
all_quotes_data.append({'text': text, 'author': author})
print(f"成功提取 {len(all_quotes_data)} 条名言。")
else:
print(f"访问 {url} 失败,状态码:{response.status_code}")
except requests.exceptions.RequestException as e:
print(f"请求 {url} 发生错误: {e}")
return all_quotes_data
def save_to_csv(data, filename='quotes.csv'):
"""
将数据保存到CSV文件。
"""
if not data:
print("没有数据可保存。")
return
fieldnames = ['text', 'author']
try:
with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data)
print(f"数据已成功保存到 {filename}。")
except IOError as e:
print(f"保存文件时发生错误: {e}")
if __name__ == "__main__":
target_url = 'http://quotes.toscrape.com/'
quotes_data = scrape_quotes(target_url)
save_to_csv(quotes_data, 'my_first_quotes.csv')
常见问题与解决方案
在你的爬虫之路上,可能会遇到一些挑战。以下是一些常见问题及其初步解决方案:
1. 反爬机制 (Anti-Scraping)
许多网站不希望自己的数据被轻易抓取,因此会设置各种反爬机制。
-
User-Agent 检测: 网站会检查你的请求头中的
User-Agent字段,判断你是否是正常的浏览器访问。默认情况下requests的User-Agent比较特殊。- 解决方案: 在
requests.get()中添加headers参数,模拟浏览器。
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36' } response = requests.get(url, headers=headers) - 解决方案: 在
-
IP 限制: 频繁访问同一网站可能导致你的 IP 被暂时或永久封禁。
- 解决方案: 减慢请求频率 (添加
time.sleep()延迟),或者使用 IP 代理池 (更高级)。
- 解决方案: 减慢请求频率 (添加
-
robots.txt: 这是一个网站告诉爬虫哪些页面可以抓取,哪些不可以的文件。- 解决方案: 爬虫开发者应自觉遵守网站的
robots.txt规则,这是爬虫伦理的基本要求。
- 解决方案: 爬虫开发者应自觉遵守网站的
-
验证码、JavaScript 动态加载: 某些内容需要用户交互或 JavaScript 渲染才能显示。
- 解决方案: 对于验证码,可能需要人工识别或使用 OCR 服务;对于 JavaScript 动态加载,可能需要使用
Selenium等自动化浏览器工具 (超出了本入门教程范围)。
- 解决方案: 对于验证码,可能需要人工识别或使用 OCR 服务;对于 JavaScript 动态加载,可能需要使用
重要提示: 进行网络爬虫时,请务必遵守法律法规和网站的使用条款,尊重网站的 robots.txt 协议,并避免对目标网站造成过大压力。
2. 编码问题 (Encoding Issues)
有时获取到的网页内容显示乱码。
- 解决方案:
requests库通常会自动检测编码,但有时会出错。你可以手动指定或纠正编码:response.encoding = 'utf-8' # 尝试指定为 UTF-8 # 或者让 requests 自动猜测 # response.encoding = response.apparent_encoding html_content = response.text
3. 网络请求错误
网络不稳定或目标服务器问题可能导致请求失败。
- 解决方案: 使用
try-except块来捕获requests.exceptions.RequestException及其子类,如ConnectionError(连接错误)、Timeout(超时)。import requests import time # 用于添加延迟 try: response = requests.get(url, timeout=5) # 设置超时时间 # ... 处理响应 except requests.exceptions.Timeout: print("请求超时") except requests.exceptions.ConnectionError: print("连接错误,请检查网络或URL") except requests.exceptions.RequestException as e: print(f"发生未知请求错误: {e}") time.sleep(1) # 请求之间暂停1秒
总结与进阶
恭喜你!你已经成功编写了你的第一个 Python 网络爬虫。这只是冰山一角,爬虫的世界广阔而有趣。
你学到了什么?
- 如何使用
requests库发送 HTTP 请求并获取网页内容。 - 如何使用
BeautifulSoup库解析 HTML,定位并提取所需数据。 - 如何将抓取到的数据保存到 CSV 文件。
- 了解了基本的爬虫伦理和常见问题的初步解决方案。
接下来可以探索什么?
- 多页爬取 (Pagination): 许多网站都有分页,你需要找到下一页的链接或规律,循环抓取所有页面的数据。
- 数据清洗与处理: 抓取到的数据可能需要进一步清洗、格式化才能使用。
- 更复杂的数据结构: 学习如何抓取嵌套的、更复杂的数据。
- 异步爬虫: 对于需要抓取大量页面的场景,异步爬虫可以大大提高效率。
- 更强大的爬虫框架: 当项目变得复杂时,可以考虑使用像 Scrapy 这样的专业爬虫框架,它提供了更完善的结构和功能。
- API 抓取: 许多网站提供 API 接口,通过 API 获取数据通常比解析 HTML 更稳定高效。
希望这篇博客能为你打开数据抓取的大门,祝你在探索数据世界的旅途中玩得开心!
希望对初学者有帮助;致力于办公自动化的小小程序员一枚
希望能得到大家的【❤️一个免费关注❤️】感谢!
求个 🤞 关注 🤞 +❤️ 喜欢 ❤️ +👍 收藏 👍
此外还有办公自动化专栏,欢迎大家订阅:Python办公自动化专栏
此外还有爬虫专栏,欢迎大家订阅:Python爬虫基础专栏
此外还有Python基础专栏,欢迎大家订阅:Python基础学习专栏