杰瑞科技汇

Python如何提取HTML并存入数据库?

Python如何提取HTML并存入数据库?-图1
(图片来源网络,侵删)
  1. HTML提取:使用 Python 库(如 requests)从网页获取 HTML 内容。
  2. HTML解析:使用解析器(如 BeautifulSouplxml)从 HTML 中提取你想要的数据。
  3. 数据库存储:使用数据库连接库(如 sqlite3psycopg2pymysqlSQLAlchemy)将提取的数据存入数据库。

第一步:准备工作 - 安装必要的库

你需要安装几个关键的 Python 库,打开你的终端或命令行,运行以下命令:

# 用于发送 HTTP 请求,获取网页内容
pip install requests
# 用于解析 HTML/XML 文档,非常强大且易用
pip install beautifulsoup4
# 用于数据库操作(这里以 SQLite 为例,它是 Python 内置的)
# 如果你使用 MySQL/PostgreSQL,需要安装对应的驱动,如 pip install pymysql 或 pip install psycopg2
pip install lxml  # 作为 BeautifulSoup 的解析器,速度更快

第二步:HTML 提取与解析

我们将使用 requestsBeautifulSoup 来完成这个任务,假设我们要从一个电商网站(http://books.toscrape.com/,这是一个专为练习设计的数据抓取网站)上抓取书籍信息。

目标: 抓取每本书的标题、价格和评分。

示例代码:extract_data.py

import requests
from bs4 import BeautifulSoup
def scrape_books(url):
    """
    从指定 URL 抓取书籍数据
    """
    try:
        # 1. 发送 HTTP GET 请求
        # headers 模拟浏览器访问,避免被一些网站屏蔽
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
        }
        response = requests.get(url, headers=headers)
        # 检查请求是否成功 (状态码 200)
        response.raise_for_status() 
        # 2. 解析 HTML
        # 使用 'lxml' 解析器,也可以使用 'html.parser' (Python 内置)
        soup = BeautifulSoup(response.text, 'lxml')
        # 3. 提取数据
        books_data = []
        # 找到所有书籍的容器
        books = soup.find_all('article', class_='product_pod')
        for book in books:
            title = book.h3.a['title']
            price = book.find('p', class_='price_color').text
            rating = book.p['class'][1] # 评分在 class 属性中,如 'star-rating Three'
            # 将提取的数据整理成字典
            books_data.append({
                'title': title,
                'price': price,
                'rating': rating
            })
        return books_data
    except requests.exceptions.RequestException as e:
        print(f"请求错误: {e}")
        return None
    except Exception as e:
        print(f"解析错误: {e}")
        return None
# --- 执行抓取 ---
if __name__ == "__main__":
    target_url = "http://books.toscrape.com/"
    scraped_books = scrape_books(target_url)
    if scraped_books:
        for book in scraped_books:
            print(book)

代码解释:

Python如何提取HTML并存入数据库?-图2
(图片来源网络,侵删)
  1. requests.get(url, headers=headers): 向目标 URL 发送 GET 请求。headers 用来模拟浏览器,防止被反爬虫机制拦截。
  2. response.raise_for_status(): 如果请求失败(404 Not Found 或 500 Server Error),这行代码会抛出一个异常。
  3. BeautifulSoup(response.text, 'lxml'): 将获取到的 HTML 内容 (response.text) 传给 BeautifulSoup,并指定使用 lxml 解析器来创建一个解析树对象 soup
  4. soup.find_all('article', class_='product_pod'): 这是 BeautifulSoup 的核心功能,它会查找所有 <article> 标签,并且这些标签的 class 属性包含 product_pod,这返回一个列表。
  5. 循环提取: 在 for 循环中,我们对每个书籍容器进行更精细的查找:
    • book.h3.a['title']: 先找到 h3 标签,再找到其下的 a 标签,然后获取其 title 属性的值。
    • book.find('p', class_='price_color').text: 找到 classprice_colorp 标签,并获取其内部的文本内容。
    • book.p['class'][1]: 评分信息存储在 p 标签的 class 属性中,如 star-rating Three,我们通过索引 [1] 来获取 Three 这个评级。

第三步:将数据存入数据库

现在我们有了抓取到的数据(一个包含字典的列表),下一步就是将它们存入数据库,我们将使用 SQLite 作为例子,因为它无需额外安装数据库服务器,非常适合演示。

设计数据库表

我们需要在数据库中创建一个表来存储书籍信息,表结构应该与我们抓取的数据字典的键对应。

字段名 数据类型 描述
id INTEGER 主键,自动递增
price TEXT 价格 (抓取时是字符串)
rating TEXT 评级 (如 'One', 'Two')

完整代码:抓取 + 存储

我们将上面的抓取代码和数据库操作结合起来。

import requests
from bs4 import BeautifulSoup
import sqlite3 # Python 内置的 SQLite 库
# --- 数据库设置 ---
DB_NAME = 'books.db'
def create_database_table():
    """创建数据库和表"""
    conn = sqlite3.connect(DB_NAME)
    cursor = conn.cursor()
    # 创建表,如果它不存在
    # 使用 IF NOT EXISTS 防止重复创建
    cursor.execute('''
    CREATE TABLE IF NOT EXISTS books (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        price TEXT NOT NULL,
        rating TEXT NOT NULL
    )
    ''')
    conn.commit()
    conn.close()
    print("数据库和表准备就绪。")
def insert_books_into_database(books_data):
    """将书籍数据插入数据库"""
    if not books_data:
        print("没有数据可插入。")
        return
    conn = sqlite3.connect(DB_NAME)
    cursor = conn.cursor()
    # 使用 ? 作为占位符,防止 SQL 注入
    # executemany 可以高效地执行多条 INSERT 语句
    cursor.executemany('''
    INSERT INTO books (title, price, rating) VALUES (?, ?, ?)
    ''', [(book['title'], book['price'], book['rating']) for book in books_data])
    conn.commit()
    conn.close()
    print(f"成功插入 {len(books_data)} 条数据到数据库。")
def scrape_books(url):
    """从指定 URL 抓取书籍数据 (同上)"""
    try:
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'}
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        soup = BeautifulSoup(response.text, 'lxml')
        books_data = []
        books = soup.find_all('article', class_='product_pod')
        for book in books:
            title = book.h3.a['title']
            price = book.find('p', class_='price_color').text
            rating = book.p['class'][1]
            books_data.append({'title': title, 'price': price, 'rating': rating})
        return books_data
    except requests.exceptions.RequestException as e:
        print(f"请求错误: {e}")
        return None
    except Exception as e:
        print(f"解析错误: {e}")
        return None
# --- 主程序 ---
if __name__ == "__main__":
    # 1. 准备数据库
    create_database_table()
    # 2. 抓取数据
    target_url = "http://books.toscrape.com/"
    scraped_books = scrape_books(target_url)
    # 3. 存储数据
    if scraped_books:
        insert_books_into_database(scraped_books)
        print("数据抓取和存储完成!")
    else:
        print("数据抓取失败。")

数据库代码解释:

Python如何提取HTML并存入数据库?-图3
(图片来源网络,侵删)
  1. sqlite3.connect(DB_NAME): 连接到一个名为 books.db 的 SQLite 数据库文件,如果文件不存在,它会自动创建。
  2. conn.cursor(): 创建一个游标对象,用于执行 SQL 命令。
  3. cursor.execute('''...'''): 执行一条 SQL 语句,我们用 CREATE TABLE IF NOT EXISTS 来确保脚本能多次运行而不会报错。
  4. conn.commit(): 非常重要! 在执行了 INSERT, UPDATE, DELETE 等修改数据的操作后,必须调用 commit() 来将更改保存到数据库。
  5. conn.close(): 关闭数据库连接。
  6. cursor.executemany(...): 这是批量插入数据的高效方式,它接受一个 SQL 模板和一个列表(列表中的每个元素都是一组参数)。 是参数占位符,它可以有效防止 SQL 注入攻击,强烈推荐使用

进阶与最佳实践

使用 ORM (SQLAlchemy) 进行更高级的数据库操作

对于大型项目,直接写 SQL 语句会比较繁琐,ORM(Object-Relational Mapping,对象关系映射)库如 SQLAlchemy 允许你用 Python 类和对象来操作数据库,更加直观和强大。

示例 (SQLAlchemy + SQLite):

# 首先安装: pip install sqlalchemy
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
# 1. 定义模型 (Python 类)
Base = declarative_base()
class Book(Base):
    __tablename__ = 'books_sqlalchemy' # 映射到数据库中的表名
    id = Column(Integer, primary_key=True)= Column(String, nullable=False)
    price = Column(String, nullable=False)
    rating = Column(String, nullable=False)
    def __repr__(self):
        return f"<Book(title='{self.title}', price='{self.price}')>"
# 2. 创建数据库连接和引擎
# 'sqlite:///books.db' 表示连接到当前目录下的 books.db 文件
engine = create_engine('sqlite:///books.db')
# 3. 创建表 (如果不存在)
Base.metadata.create_all(engine)
# 4. 创建会话
Session = sessionmaker(bind=engine)
session = Session()
# 5. 插入数据 (使用 ORM)
# 假设 scraped_books 是之前抓取到的数据列表
for book_data in scraped_books:
    # 创建一个新的 Book 对象
    book_obj = Book(title=book_data['title'], price=book_data['price'], rating=book_data['rating'])
    session.add(book_obj)
# 6. 提交会话
session.commit()
print(f"使用 SQLAlchemy 成功插入 {len(scraped_books)} 条数据。")
# 7. 查询数据示例
all_books = session.query(Book).all()
print("\n从数据库查询所有书籍:")
for book in all_books[:5]: # 只打印前5条
    print(book)
session.close()

分页抓取

大多数网站不会把所有数据都放在一页,你需要处理分页。

# 在 scrape_books 函数中修改 URL
base_url = "http://books.toscrape.com/catalogue/page-{}.html"
all_books_data = []
for page_num in range(1, 51): # 假设最多50页
    url = base_url.format(page_num)
    print(f"正在抓取: {url}")
    books_on_page = scrape_books(url) # 假设 scrape_books 返回一个列表或 None
    if books_on_page:
        all_books_data.extend(books_on_page)
    else:
        break # 如果某一页没有数据,就停止
# 最后将 all_books_data 存入数据库
insert_books_into_database(all_books_data)

处理 JavaScript 渲染的网站

requests 这样的库只能获取初始的 HTML,无法执行 JavaScript,如果网站内容是通过 JS 动态加载的,你需要使用 SeleniumPlaywright 这样的浏览器自动化工具。

# 安装 Selenium 和对应浏览器的 WebDriver
pip install selenium
# 使用 Chrome 浏览器,需要下载 chromedriver 并配置到 PATH

Selenium 会启动一个真实的浏览器(或无头浏览器),访问网页,等待 JS 渲染完成后再获取最终的 HTML 源码,后续的解析步骤和 BeautifulSoup 是一样的。

步骤 工具/库 关键代码/概念
HTML 提取 requests requests.get(url, headers=headers)
HTML 解析 BeautifulSoup soup.find(), soup.find_all(), tag.text, tag['attr']
数据库存储 sqlite3 / SQLAlchemy CREATE TABLE, INSERT INTO, executemany, ORM 模型
进阶 Selenium 处理 JS 渲染的网页

通过以上步骤,你就可以构建一个完整的、从网页抓取数据并存入数据库的 Python 应用程序。

分享:
扫描分享到社交APP
上一篇
下一篇