58·模块十二:网络编程进阶

网页爬虫基础:requests + BeautifulSoup

web-scrapingbeautifulsouphtml-parsing

第58课:网页爬虫基础:requests + BeautifulSoup

学习目标

完成本课学习后,你将能够:

  1. 理解网络爬虫的基本工作原理与流程
  2. 使用 requests 库向网页服务器发送HTTP请求并获取HTML内容
  3. 使用 BeautifulSoup 库解析HTML文档,高效提取所需数据
  4. 遵守网络爬虫的道德规范,编写对服务器友好的爬虫程序

核心概念

1. 什么是网页爬虫?

网页爬虫(Web Crawler)就像一个自动化的"数据采集员"。它模拟浏览器的行为,自动访问网页、下载内容,并从中提取出我们需要的信息(如商品价格、新闻标题、电影评分等)。这极大地节省了我们手动复制粘贴的时间。

2. 两个核心库的作用

  • requests:这是我们的"快递员"。它的任务是向目标网站的服务器发送一个"请给我这个页面"的请求(HTTP请求),然后把服务器返回的网页源代码(HTML文档)带回来。
  • BeautifulSoup:这是我们的"翻译官"兼"资料整理员"。它将 requests 带回来的、像一长串天书一样的HTML源代码,转换成一个结构清晰、易于查找的树状结构。我们可以用它来轻松地定位并提取特定的标签、属性或文本。

3. 爬虫的基本流程

确定目标URL → 发送HTTP请求(requests) → 获取HTML响应 → 解析HTML(BeautifulSoup) → 提取目标数据 → 存储数据

代码示例

示例1:基础爬取 - 获取网页标题

# 导入必要的库
import requests
from bs4 import BeautifulSoup

# 1. 定义目标网页的URL (以一个简单的静态页面为例)
url = "http://example.com"  # 这是一个用于示例的网站

# 2. 使用 requests 发送 GET 请求
#    模拟浏览器访问,建议加上 headers,避免被某些网站简单拒绝
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
try:
    response = requests.get(url, headers=headers, timeout=5) # 设置超时时间
    # 检查请求是否成功 (状态码 200 表示成功)
    response.raise_for_status()
    
    # 3. 获取HTML文本内容
    html_content = response.text
    print("网页源代码获取成功!")
    
    # 4. 使用 BeautifulSoup 解析HTML
    soup = BeautifulSoup(html_content, 'html.parser') # 'html.parser' 是解析器
    
    # 5. 提取数据 (例如:提取网页的标题)
    #    <title>标签的内容就是浏览器标签页上显示的文字
    title = soup.find('title').get_text()
    print(f"网页标题是: {title}")
    
    # 6. (扩展) 提取所有段落 (<p>标签) 的文本
    paragraphs = soup.find_all('p') # find_all 返回一个列表
    print("\n页面中的所有段落内容:")
    for i, p in enumerate(paragraphs, 1):
        print(f"{i}. {p.get_text().strip()}") # get_text() 提取标签内的文本

except requests.exceptions.RequestException as e:
    print(f"请求出错: {e}")
except Exception as e:
    print(f"解析或提取数据时出错: {e}")

示例2:提取带有特定属性的元素

假设我们要从一个虚构的新闻页面提取所有带有 class="news-title" 的标题。

import requests
from bs4 import BeautifulSoup

# ... (前文的请求和解析代码类似,此处省略)

# 假设已成功获取并解析了HTML,得到了`soup`对象

# 提取所有 class="news-title" 的元素
# BeautifulSoup中,class是Python的关键字,所以用 class_ 来代替
news_titles = soup.find_all('h2', class_='news-title')

print("新闻标题列表:")
for title in news_titles:
    # 提取链接和文本
    link = title.find('a') # 查找标题下的<a>链接标签
    if link:
        href = link.get('href', '无链接') # 获取href属性
        text = link.get_text().strip()
        print(f"- {text} (链接: {href})")
    else:
        print(f"- {title.get_text().strip()} (无链接)")

实践练习

练习1:基础数据抓取 (易)

要求: 访问 http://quotes.toscrape.com/,提取页面中前5位名言的作者和名言内容。 预期输出格式:

名言1: "The world as we have created it is a process of our thinking..." - Albert Einstein
名言2: "It is our choices, Harry, that show what we truly are..." - J.K. Rowling
...

练习2:表格数据提取 (中)

要求: 访问 https://en.wikipedia.org/wiki/List_of_countries_by_GDP_(nominal),使用 BeautifulSoup 提取表格中前10个国家的"Country/Territory"和"IMF"两列的数据。 提示: HTML表格使用 <table><tr>(行)、<td>(单元格)等标签。

练习3:处理相对链接 (难)

要求: 继续使用练习1的网站 http://quotes.toscrape.com/。提取第一页中所有名言作者的个人资料链接(该链接通常是相对路径,如 /author/Albert-Einstein),并将它们转换为完整的URL(如 http://quotes.toscrape.com/author/Albert-Einstein)。 提示: 可以使用 urljoin 函数处理链接拼接。

from urllib.parse import urljoin
base_url = "http://quotes.toscrape.com"
full_url = urljoin(base_url, relative_link)

常见错误

  1. 编码错误 (乱码):获取的网页内容显示为乱码。
    • 原因:网页使用了非UTF-8编码。
    • 解决:尝试使用 response.encoding = response.apparent_encoding 来自动识别编码,或在 response.text 前手动设置编码 response.encoding = 'gbk'
  2. 选择器错误 (NoneType):使用 find() 后报错 'NoneType' object has no attribute 'get_text'
    • 原因:你的选择器没有匹配到任何元素,find() 返回了 None
    • 解决:打印 soup 对象检查HTML结构,或在使用提取结果前先判断是否为 None
  3. 过于频繁的请求 (被封IP):短时间内对同一网站发送了大量请求,导致IP被临时或永久封禁。
    • 解决:在每次请求后使用 time.sleep(seconds) 进行延时;为请求设置合理的 User-Agent;遵守网站的 robots.txt 规则。
  4. 忽略道德与法律:爬取了受版权保护的个人隐私数据或明确禁止爬取的内容。
    • 解决永远先查看网站的 robots.txt 文件(在域名后加 /robots.txt),并尊重其规则。仅爬取公开、可合法获取的数据。

小结

  • requests 是发起HTTP请求的利器,负责"获取"网页。
  • BeautifulSoup 是解析HTML的专家,负责"理解"和"提取"数据。
  • 爬虫的典型流程是:请求 → 获取 → 解析 → 提取 → 存储
  • 务必遵守网络礼仪:设置合理的请求头、添加请求间隔、尊重 robots.txt
  • 在解析前,先用浏览器"检查元素"功能观察网页的HTML结构,这是编写选择器的关键。

掌握 requests + BeautifulSoup 这套组合,你已经具备了爬取绝大多数静态网站数据的能力。下一课,我们将学习功能更强大、更适合大型爬取项目的 Scrapy 框架。

练习编辑器

python
Loading...

继续学习

完成本课后,建议继续学习下一课「进阶爬虫:Scrapy 框架入门」 以巩固所学知识。