在职场中,你是不是也经常需要从各种网站上获取信息?
市场调研:需要收集竞品官网的商品价格、库存信息。
我们将手把手教你如何利用Python的Requests库和BeautifulSoup库,轻松实现:
发送网络请求: 像浏览器一样访问网页。
解析网页内容: 从复杂的HTML中精准提取你想要的数据。
自动化数据采集: 批量高效地获取网站信息。
要像Python一样从网站上获取信息,我们首先要了解两个基础概念:
HTTP请求
网页结构
如何实现: 每次你在浏览器输入网址,点击链接,其实就是浏览器向网站服务器发送了一个HTTP请求。服务器收到请求后,返回网页数据(HTML、CSS、JavaScript等)。
HTTP方法:
GET: 最常见,用于获取资源,如访问网页、下载图片。
POST: 用于提交数据,如登录、提交表单。
URL: 统一资源定位符,即网址,指明了要访问的资源位置。
请求头 (Headers): 包含浏览器信息(User-Agent)、Cookie等,告诉服务器你是谁、想做什么。
响应 (Response): 服务器返回的数据,包括状态码(200 OK,404 Not Found等)和响应体(通常是HTML内容)。
作用: 网页内容主要是由HTML编写的。HTML使用标签()来定义网页的结构和内容,例如标题(
)、链接()、图片()、表格(
)等。标签与属性: 标签可以有属性,提供额外信息。
例如,href是属性。
嵌套结构: HTML元素可以嵌套,形成树形结构,方便我们层层深入找到想要的数据
代码:
<div class="news-item">
<h2><a href="/news/detail/123">最新新闻标题</a></h2>
<p class="summary">这是一段新闻摘要...</p>
<span class="date">2023-10-27</span>
</div>
Requests库是Python中发送HTTP请求的利器,它比Python内置的urllib更简单、更人性化。它是实现Python网页数据抓取的第一步。
作用: Requests将复杂的HTTP请求封装成简单的函数调用,你只需要指定URL,就能获取网页内容
安装;
pip install requests
让我们来发送你的第一个HTTP GET请求,获取一个网页的HTML内容!
代码:
import requests # 导入requests库
def fetch_webpage_content(url):
"""
发送HTTP GET请求,获取网页内容。
这是Requests库基础用法,你的第一个HTTP请求。
:param url: 目标网页的URL
:return: 网页的HTML文本,或None如果请求失败
"""
print(f" 正在发送GET请求到:{url}")
try:
# 发送GET请求,获取响应
response = requests.get(url)
response.raise_for_status() # 检查请求是否成功(200 OK),如果不是则抛出异常
# 打印响应状态码
print(f" ✅ 请求成功!状态码:{response.status_code}")
# 返回响应的文本内容(即网页的HTML代码)
return response.text
except requests.exceptions.RequestException as e:
print(f"❌ 请求失败:{e}")
return None
if __name__ == "__main__":
# 请替换为你要抓取的网页URL
# 建议选择一个内容简单、不涉及登录的静态网页进行测试
# 例如:一个新闻网站的某个文章页,或一个简单的博客页面
test_url = "https://www.example.com" # 替换为你自己的测试URL
html_content = fetch_webpage_content(test_url)
if html_content:
print("\n--- 网页HTML内容截取 (前500字符) ---")
print(html_content[:500]) # 打印HTML内容的前500字符
步骤:
安装库: pip install requests。
修改代码URL: 复制上方代码到VS Code,保存为fetch_html.py。修改 test_url 为你要抓取的网页URL。
运行: 在VS Code终端运行 python fetch_html.py。## 2.2 处理请求头与参数:模拟浏览器访问
场景: 有些网站会检测你是否是真实的浏览器访问,或者需要你在请求中带上特定的参数(如查询参数)。直接发送请求可能会被拒绝。
方案: Requests允许你轻松添加自定义的请求头(如User-Agent)和URL查询参数,模拟更真实的浏览器行为。
代码:
import requests
def fetch_with_headers_params(url, headers=None, params=None):
"""
发送带请求头和/或URL参数的HTTP GET请求。
模拟浏览器访问,这是Python Requests教程的进阶用法。
:param url: 目标网页的URL
:param headers: 请求头字典 (如 {'User-Agent': '...'})
:param params: URL查询参数字典 (如 {'query': 'python'})
:return: 网页的HTML文本,或None
"""
print(f" 正在发送带Headers/Params的GET请求到:{url}")
print(f" Headers: {headers}")
print(f" Params: {params}")
try:
response = requests.get(url, headers=headers, params=params)
response.raise_for_status()
print(f" ✅ 请求成功!状态码:{response.status_code}")
# 打印最终请求的URL,可以看到参数被正确拼接
print(f" 实际请求URL:{response.url}")
return response.text
except requests.exceptions.RequestException as e:
print(f"❌ 请求失败:{e}")
return None
if __name__ == "__main__":
# 模拟浏览器User-Agent,防止被网站识别为爬虫
my_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
}
# 搜索查询参数 (例如:在Baidu搜索“Python自动化”)
search_params = {
'wd': 'Python自动化',
'ie': 'utf-8'
}
# 示例1:带User-Agent访问网站
# test_url_with_headers = "https://www.baidu.com" # 访问百度
# fetch_with_headers_params(test_url_with_headers, headers=my_headers)
# 示例2:带查询参数进行搜索
search_url = "https://www.baidu.com/s" # 百度搜索的URL
fetch_with_headers_params(search_url, headers=my_headers, params=search_params)
拿到网页的HTML内容后,它还是一堆字符串。我们需要BeautifulSoup这个强大的利器,它能将杂乱的HTML代码解析成易于操作的结构,让我们精准定位和提取
作用: BeautifulSoup将HTML/XML文档解析成一个树形结构,你可以像导航文件目录一样,通过标签名、属性、CSS选择器等方式找到你想要的元素。
安装BeautifulSoup:
pip install beautifulsoup4
让我们来解析一份HTML内容,体验BeautifulSoup的基础用法。
代码:
from bs4 import BeautifulSoup # 导入BeautifulSoup类
import requests # 假设requests已安装
def parse_html_basic(html_content):
"""
使用BeautifulSoup解析HTML内容并提取基本信息。
这是BeautifulSoup教程的入门。
:param html_content: 网页的HTML文本
"""
if not html_content: return print("❌ HTML内容为空,无法解析。")
print(" 正在使用BeautifulSoup解析HTML内容...")
# **核心操作:创建BeautifulSoup对象**
soup = BeautifulSoup(html_content, 'html.parser') # 'html.parser'是Python内置的HTML解析器
# 获取页面标题
title = soup.title.string if soup.title else "无标题"
print(f" ✅ 页面标题:{title}")
# 获取所有段落文本
paragraphs = soup.find_all('p') # 查找所有<p>标签
print("\n --- 所有段落内容 ---")
for i, p in enumerate(paragraphs[:3]): # 只打印前3个
print(f" [{i+1}] {p.get_text()[:50]}...") # get_text()提取标签内的纯文本
# 获取所有链接
links = soup.find_all('a') # 查找所有<a>标签
print("\n --- 所有链接 (前5个) ---")
for i, link in enumerate(links[:5]):
href = link.get('href') # 获取href属性值
text = link.get_text() # 获取链接文本
print(f" [{i+1}] 文本:'{text[:30]}...' | 链接:'{href}'")
print("✨ HTML内容解析完成!")
if __name__ == "__main__":
# 示例HTML内容
sample_html = """
示例网页
欢迎来到自动化世界!
-item">
这是第一段内容。
这是第二段,/
about">了解更多。
这是第三段,用于演示。
/contact">联系我们
"""
parse_html_basic(sample_html)
步骤:
安装库: pip install beautifulsoup4。
修改代码HTML: 复制上方代码到VS Code,保存为
parse_html.py。你可以修改sample_html内容来测试。
运行: 运行 python parse_html.py。
场景: 网页内容复杂,你只想提取某个特定区域(如新闻列表)中的标题或价格,而不是所有p标签或a标签。
方案: BeautifulSoup支持通过标签名、属性、CSS类名、ID等多种方式精准定位你想要的HTML元素。
find() / find_all(): 最常用的查找方法,查找第一个匹配的标签或所有匹配的标签。
select(): 使用CSS选择器语法进行查找,非常强大和灵活。
代码:
from bs4 import BeautifulSoup
import requests
def extract_specific_data(url):
"""
从指定URL的网页中提取特定数据(如新闻标题和链接)。
这是Python网页数据抓取和网页信息提取的关键。
:param url: 目标网页URL
"""
html_content = requests.get(url).text # 假设请求成功
if not html_content: return print(f"❌ 无法获取网页内容:{url}")
print(f" 正在从 '{url}' 提取特定数据...")
soup = BeautifulSoup(html_content, 'html.parser')
# 示例:假设网页中有这样的结构
# <div id="news-list">
# <div class="item">
# <h3><a href="/news/1">新闻标题1</a></h3>
# <p>摘要1</p>
# </div>
# <div class="item">
# <h3><a href="/news/2">新闻标题2</a></h3>
# <p>摘要2</p>
# </div>
# </div>
# **核心操作1:按ID查找元素**
news_list_div = soup.find(id="news-list")
if not news_list_div:
print(" ℹ️ 未找到ID为 'news-list' 的元素。")
return
print("\n --- 新闻标题和链接 ---")
# **核心操作2:按CSS选择器查找所有匹配元素**
# 查找 news_list_div 内所有 class 为 'item' 的 div,再查找其下的 h3 > a 标签
news_items = news_list_div.select('div.item h3 > a')
if not news_items:
print(" ℹ️ 未找到新闻条目。")
return
for i, item_link in enumerate(news_items):
title = item_link.get_text(strip=True) # 提取文本并去除首尾空白
link_href = item_link.get('href') # 获取链接属性
print(f" [{i+1}] 标题:'{title}' | 链接:'{link_href}'")
print("✨ 特定数据提取完成!")
if __name__ == "__main__":
# 使用一个模拟的包含新闻列表的URL进行测试
# 实际项目中需要替换为真实的网页URL,并根据其HTML结构调整选择器
# 建议创建一个简单的本地HTML文件用于测试,或使用允许爬取的网站
test_news_url = "https://www.example.com/news" # 替换为你自己的测试URL
extract_specific_data(test_news_url)
现在,你已经掌握了Python网页数据抓取的核心技巧——Requests和BeautifulSoup。
作用: 整合HTTP请求(Requests)和HTML解析(BeautifulSoup),实现数据从网页到结构化输出(如列表、字典,最终可保存为CSV或Excel)的自动化流程。
场景: 每天都需要收集某个新闻网站的最新头条,并整理成链接列表。
方案: 结合Requests获取网页,BeautifulSoup解析,然后提取所有新闻标题和链接。
代码:
import requests
from bs4 import BeautifulSoup
import os
def scrape_news_headlines(url, output_file="news_headlines.csv"):
"""
抓取指定新闻网站的标题和链接,并保存到CSV文件。
这是Python网页数据抓取和自动化数据采集的典型案例。
:param url: 新闻网站的URL
:param output_file: 输出CSV文件路径
"""
print(f" 正在抓取新闻标题和链接从:{url}")
try:
response = requests.get(url)
response.raise_for_status() # 检查HTTP请求状态
soup = BeautifulSoup(response.text, 'html.parser')
# 假设新闻标题和链接在一个特定的div下,例如 id="main-news-list"
# 并且每个新闻条目在一个class="news-item"的div里,标题在h2/h3的a标签里
news_container = soup.find(id="main-news-list") # 根据实际网站结构调整
if not news_container:
print("❌ 未找到新闻列表容器,请检查选择器。")
return
headlines_data = []
# 查找所有新闻条目
items = news_container.find_all('div', class_='news-item') # 根据实际网站结构调整
if not items:
print("❌ 未找到新闻条目,请检查选择器。")
return
for item in items:
title_tag = item.find('h3') # 查找标题标签 (h2/h3等)
link_tag = title_tag.find('a') if title_tag else None # 查找链接标签
if title_tag and link_tag:
title = title_tag.get_text(strip=True)
link = link_tag.get('href')
# 确保链接是完整的,如果网站返回相对路径,需要拼接
if link and not link.startswith('http'):
link = requests.utils.urljoin(url, link) # 自动拼接完整URL
headlines_data.append({'标题': title, '链接': link})
print(f" ✅ 抓取:'{title}'")
# 将数据保存到CSV文件
if headlines_data:
df = pd.DataFrame(headlines_data)
df.to_csv(output_file, index=False, encoding='utf-8')
print(f"✨ 新闻标题和链接已保存到:'{output_file}'")
else:
print("ℹ️ 未抓取到任何新闻标题。")
except requests.exceptions.RequestException as e:
print(f"❌ 请求失败:{e}")
except Exception as e:
print(f"❌ 抓取或解析失败:{e}")
if __name__ == "__main__":
# 请替换为你要抓取的新闻网站URL,并根据其HTML结构调整代码中的find/select方法
# 建议选择一个内容简单、结构清晰的公开新闻页面进行测试
news_url = "https://example.com/news" # 替换为真实的URL
output_csv_path = os.path.expanduser("~/Desktop/latest_news.csv")
# 注意:需要根据实际网页的HTML结构来调整 soup.find() 和 .select() 的参数
# 如果网站结构复杂或有反爬机制,可能需要更高级的技术(如Selenium,将在下篇介绍)
scrape_news_headlines(news_url, output_csv_path)
操作:
安装库: pip install requests beautifulsoup4 pandas。
找网站: 找到一个你想抓取新闻标题的网站URL,并检查其HTML结构(F12开发者工具)。
修改代码: 修改 news_url,并最重要的是根据实际网页结构调整 soup.find() 和 item.find() 等选择器。
场景: 你需要监控竞品电商网站上的商品价格和库存,手动逐个查看耗时且容易漏掉变化。
方案: 结合Requests和BeautifulSoup,批量访问商品列表页,提取每个商品的名称和价格。
代码:
```go
import requests
from bs4 import BeautifulSoup
import pandas as pd
import os
def scrape_ecommerce_products(url, output_file="ecommerce_products.csv"):
"""
抓取电商网站的商品名称和价格,并保存到CSV文件。
这是Python网页数据抓取和自动化数据采集的进阶案例。
:param url: 电商网站商品列表页的URL
:param output_file: 输出CSV文件路径
"""
print(f" 正在抓取电商商品信息从:{url}")
try:
response = requests.get(url)
response.raise_for_status()
soup = BeautifulSoup(response.text, 'html.parser')
# 假设商品信息在一个class为 'product-list' 的div中
# 每个商品在一个 class为 'product-item' 的div里
# 商品名称在 class='product-title' 的h3/a标签里
# 价格在 class='product-price' 的span标签里
product_list_container = soup.find('div', class_='product-list') # 根据实际网站结构调整
if not product_list_container:
print("❌ 未找到商品列表容器,请检查选择器。")
return
products_data = []
items = product_list_container.find_all('div', class_='product-item') # 根据实际网站结构调整
if not items:
print("❌ 未找到商品条目,请检查选择器。")
return
for item in items:
title_tag = item.find('h3', class_='product-title') # 查找商品标题
price_tag = item.find('span', class_='product-price') # 查找商品价格
product_name = title_tag.get_text(strip=True) if title_tag else "N/A"
product_price = price_tag.get_text(strip=True) if price_tag else "N/A"
products_data.append({'商品名称': product_name, '价格': product_price})
print(f" ✅ 抓取:'{product_name}' - '{product_price}'")
if products_data:
df = pd.DataFrame(products_data)
df.to_csv(output_file, index=False, encoding='utf-8')
print(f"✨ 商品信息已保存到:'{output_file}'")
else:
print("ℹ️ 未抓取到任何商品信息。")
except requests.exceptions.RequestException as e:
print(f"❌ 请求失败:{e}")
except Exception as e:
print(f"❌ 抓取或解析失败:{e}")
if __name__ == "__main__":
# 请替换为你要抓取的电商网站商品列表URL
# 建议选择一个内容简单、结构清晰的公开电商列表页进行测试
ecommerce_url = "https://example.com/products" # 替换为真实的URL
output_csv_path = os.path.expanduser("~/Desktop/ecommerce_products.csv")
# 注意:务必根据实际网页的HTML结构来调整 soup.find() 和 .find_all() 的参数
# 如果网站有反爬机制,或者商品信息是动态加载的,可能需要更高级的技术(如Selenium,将在下篇介绍)
scrape_ecommerce_products(ecommerce_url, output_csv_path)
`
操作步骤: 参照2.1节准备环境。找一个包含商品列表的电商网站URL,并检查其HTML结构。
最重要的是根据实际网页结构调整代码中的 find() 和 find_all() 选择器。修改代码URL,运行脚本。
效果展示:
恭喜你!通过本篇文章,你已经掌握了Python网页数据抓取的核心技能,亲手打造了一个能够秒抓网站信息的的痛点出发,学会了:
HTTP请求基础: 了解浏览器如何与网站交互的原理。
Requests库: 你的利器,轻松发送HTTP请求,获取网页内容,并处理请求头与参数。
BeautifulSoup库: 你的解析工具,将杂乱的HTML代码解析成结构化数据,实现网页信息提取的精准定位。
实战案例: 成功抓取新闻标题和链接,以及电商商品信息,实现自动化数据采集。
[表格:Requests vs BeautifulSoup功能协作]
库名 | 核心功能 | 作用 |
---|---|---|
Requests | 发送HTTP请求 | 获取网页的原始HTML内容 |
BeautifulSoup | 解析HTML,提取数据 | 从HTML中找到并提取你想要的信息 |
现在,你不再需要为手动复制粘贴网页数据而烦恼。
除了今天学到的静态网页抓取,你还希望Python爬虫能帮你解决哪些数据获取问题?比如:需要登录的网站数据?动态加载内容的网站?或者处理验证码?在评论区分享你的需求和想法,你的建议可能会成为我们下一篇文章的灵感来源!
敬请期待! 网页数据抓取系列还有更精彩的内容!在下一篇文章中,我们将探索如何利用Selenium库,应对更复杂的动态网页和需要模拟浏览器操作的网站,让你的Python网页数据抓取能力无所不能!同时,本系列所有代码都将持续更新并汇总在我的GitHub仓库中,敬请关注!未来,这个**“Python职场效率专家实战包”还将包含更多开箱即用、功能强大**的自动化工具,