Python爬虫技术 第18节 数据存储

Python 爬虫技术常用于从网页上抓取数据,并将这些数据存储起来以供进一步分析或使用。数据的存储方式多种多样,常见的包括文件存储和数据库存储。下面我将通过一个简单的示例来介绍如何使用 Python 爬取数据,并将其存储为 CSV 和 JSON 文件格式,以及如何将数据存储到 SQL 和 NoSQL 数据库中。

在这里插入图片描述stars

示例场景:

假设我们要爬取一个网站上的产品信息,每个产品包含以下字段:product_name, price, rating, description

步骤 1: 安装所需库

首先需要安装一些必要的 Python 库:

  • requests 用于发起 HTTP 请求
  • BeautifulSoup 用于解析 HTML 文档
  • pandas 用于数据处理
  • sqlite3pymysql (MySQL) 用于 SQL 数据库操作
  • pymongo 用于 MongoDB (NoSQL)

可以通过 pip 安装:

pip install requests beautifulsoup4 pandas sqlite3 pymysql pymongo

步骤 2: 编写爬虫代码

2.1 爬取数据
import requests
from bs4 import BeautifulSoupdef fetch_data(url):response = requests.get(url)soup = BeautifulSoup(response.text, 'html.parser')products = []for product in soup.find_all('div', class_='product'):name = product.find('h2').text.strip()price = product.find('span', class_='price').text.strip()rating = product.find('span', class_='rating').text.strip()description = product.find('p', class_='description').text.strip()products.append({'product_name': name,'price': price,'rating': rating,'description': description})return productsurl = 'http://example.com/products'
products = fetch_data(url)
print(products)
2.2 存储数据到 CSV 文件
import pandas as pddef save_to_csv(data, filename):df = pd.DataFrame(data)df.to_csv(filename, index=False)save_to_csv(products, 'products.csv')
2.3 存储数据到 JSON 文件
import jsondef save_to_json(data, filename):with open(filename, 'w') as f:json.dump(data, f, indent=4)save_to_json(products, 'products.json')

步骤 3: 存储数据到数据库

3.1 存储数据到 SQL 数据库 (SQLite)
import sqlite3def save_to_sqlite(data):conn = sqlite3.connect('products.db')c = conn.cursor()c.execute('''CREATE TABLE IF NOT EXISTS products(product_name TEXT, price TEXT, rating TEXT, description TEXT)''')placeholders = ', '.join(['?'] * len(data[0]))columns = ', '.join(data[0].keys())sql = f'INSERT INTO products ({columns}) VALUES ({placeholders})'c.executemany(sql, [list(item.values()) for item in data])conn.commit()conn.close()save_to_sqlite(products)
3.2 存储数据到 NoSQL 数据库 (MongoDB)
from pymongo import MongoClientdef save_to_mongodb(data):client = MongoClient('mongodb://localhost:27017/')db = client['products_db']collection = db['products']collection.insert_many(data)client.close()save_to_mongodb(products)

以上示例展示了如何使用 Python 抓取数据并将其存储到不同的数据存储方式中。你可以根据具体的需求选择合适的存储方式。如果需要在生产环境中使用,请确保遵守相关法律法规和网站的服务条款。

当然可以!我们可以进一步完善上面的代码,使其更加完整和实用。接下来,我们将添加异常处理、日志记录等功能,并提供完整的代码示例。

完整的代码示例

1. 导入必要的库
import requests
from bs4 import BeautifulSoup
import pandas as pd
import json
import sqlite3
from pymongo import MongoClient
import logging
2. 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
3. 网页数据抓取函数
def fetch_data(url):try:response = requests.get(url)response.raise_for_status()  # 检查响应状态码是否正常soup = BeautifulSoup(response.text, 'html.parser')products = []for product in soup.find_all('div', class_='product'):name = product.find('h2').text.strip()price = product.find('span', class_='price').text.strip()rating = product.find('span', class_='rating').text.strip()description = product.find('p', class_='description').text.strip()products.append({'product_name': name,'price': price,'rating': rating,'description': description})logging.info(f"Fetched {len(products)} products.")return productsexcept Exception as e:logging.error(f"Error fetching data: {e}")return []url = 'http://example.com/products'
products = fetch_data(url)
4. CSV 文件存储
def save_to_csv(data, filename):try:df = pd.DataFrame(data)df.to_csv(filename, index=False)logging.info(f"Data saved to {filename}.")except Exception as e:logging.error(f"Error saving to CSV: {e}")save_to_csv(products, 'products.csv')
5. JSON 文件存储
def save_to_json(data, filename):try:with open(filename, 'w') as f:json.dump(data, f, indent=4)logging.info(f"Data saved to {filename}.")except Exception as e:logging.error(f"Error saving to JSON: {e}")save_to_json(products, 'products.json')
6. SQLite 数据库存储
def save_to_sqlite(data):try:conn = sqlite3.connect('products.db')c = conn.cursor()c.execute('''CREATE TABLE IF NOT EXISTS products(product_name TEXT, price TEXT, rating TEXT, description TEXT)''')placeholders = ', '.join(['?'] * len(data[0]))columns = ', '.join(data[0].keys())sql = f'INSERT INTO products ({columns}) VALUES ({placeholders})'c.executemany(sql, [list(item.values()) for item in data])conn.commit()conn.close()logging.info("Data saved to SQLite database.")except Exception as e:logging.error(f"Error saving to SQLite: {e}")save_to_sqlite(products)
7. MongoDB 数据库存储
def save_to_mongodb(data):try:client = MongoClient('mongodb://localhost:27017/')db = client['products_db']collection = db['products']collection.insert_many(data)client.close()logging.info("Data saved to MongoDB database.")except Exception as e:logging.error(f"Error saving to MongoDB: {e}")save_to_mongodb(products)

完整的脚本

将上述所有部分组合成一个完整的脚本如下所示:

import requests
from bs4 import BeautifulSoup
import pandas as pd
import json
import sqlite3
from pymongo import MongoClient
import logginglogging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')def fetch_data(url):try:response = requests.get(url)response.raise_for_status()soup = BeautifulSoup(response.text, 'html.parser')products = []for product in soup.find_all('div', class_='product'):name = product.find('h2').text.strip()price = product.find('span', class_='price').text.strip()rating = product.find('span', class_='rating').text.strip()description = product.find('p', class_='description').text.strip()products.append({'product_name': name,'price': price,'rating': rating,'description': description})logging.info(f"Fetched {len(products)} products.")return productsexcept Exception as e:logging.error(f"Error fetching data: {e}")return []def save_to_csv(data, filename):try:df = pd.DataFrame(data)df.to_csv(filename, index=False)logging.info(f"Data saved to {filename}.")except Exception as e:logging.error(f"Error saving to CSV: {e}")def save_to_json(data, filename):try:with open(filename, 'w') as f:json.dump(data, f, indent=4)logging.info(f"Data saved to {filename}.")except Exception as e:logging.error(f"Error saving to JSON: {e}")def save_to_sqlite(data):try:conn = sqlite3.connect('products.db')c = conn.cursor()c.execute('''CREATE TABLE IF NOT EXISTS products(product_name TEXT, price TEXT, rating TEXT, description TEXT)''')placeholders = ', '.join(['?'] * len(data[0]))columns = ', '.join(data[0].keys())sql = f'INSERT INTO products ({columns}) VALUES ({placeholders})'c.executemany(sql, [list(item.values()) for item in data])conn.commit()conn.close()logging.info("Data saved to SQLite database.")except Exception as e:logging.error(f"Error saving to SQLite: {e}")def save_to_mongodb(data):try:client = MongoClient('mongodb://localhost:27017/')db = client['products_db']collection = db['products']collection.insert_many(data)client.close()logging.info("Data saved to MongoDB database.")except Exception as e:logging.error(f"Error saving to MongoDB: {e}")if __name__ == '__main__':url = 'http://example.com/products'products = fetch_data(url)save_to_csv(products, 'products.csv')save_to_json(products, 'products.json')save_to_sqlite(products)save_to_mongodb(products)

这个脚本包含了基本的数据抓取、存储到文件和数据库的功能,并且具有错误处理和日志记录机制,可以作为实际项目的基础。请注意,在实际部署时还需要考虑更详细的错误处理、性能优化等细节问题。

好的,我们可以在现有的基础上进一步完善代码,增加更多的功能和健壮性。以下是针对现有代码的一些改进点:

  1. 参数化 URL: 允许用户指定要抓取的 URL。
  2. 异常处理: 增加更详细的异常处理。
  3. 日志文件: 将日志输出到文件而不是控制台。
  4. 命令行参数: 使用命令行参数来控制程序行为。
  5. 数据验证: 对抓取的数据进行简单的验证。
  6. 数据库连接池: 使用连接池提高数据库操作效率。

下面是根据以上改进点修改后的代码:

import requests
from bs4 import BeautifulSoup
import pandas as pd
import json
import sqlite3
from pymongo import MongoClient
import logging
from argparse import ArgumentParser
from contextlib import closing
from urllib.parse import urlparse# 设置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)# 创建命令行参数解析器
parser = ArgumentParser(description="Web scraper and data storage tool.")
parser.add_argument("url", help="The URL of the web page to scrape.")
parser.add_argument("--output-csv", help="Save data to a CSV file.", default=None)
parser.add_argument("--output-json", help="Save data to a JSON file.", default=None)
parser.add_argument("--output-sqlite", help="Save data to an SQLite database.", action="store_true")
parser.add_argument("--output-mongodb", help="Save data to a MongoDB database.", action="store_true")# 网页数据抓取函数
def fetch_data(url):try:response = requests.get(url)response.raise_for_status()soup = BeautifulSoup(response.text, 'html.parser')products = []for product in soup.find_all('div', class_='product'):name = product.find('h2').text.strip()price = product.find('span', class_='price').text.strip()rating = product.find('span', class_='rating').text.strip()description = product.find('p', class_='description').text.strip()products.append({'product_name': name,'price': price,'rating': rating,'description': description})logger.info(f"Fetched {len(products)} products.")return productsexcept requests.exceptions.HTTPError as errh:logger.error(f"HTTP Error: {errh}")except requests.exceptions.ConnectionError as errc:logger.error(f"Error Connecting: {errc}")except requests.exceptions.Timeout as errt:logger.error(f"Timeout Error: {errt}")except requests.exceptions.RequestException as err:logger.error(f"OOps: Something Else: {err}")except Exception as e:logger.error(f"Error fetching data: {e}")return []# CSV 文件存储
def save_to_csv(data, filename):try:df = pd.DataFrame(data)df.to_csv(filename, index=False)logger.info(f"Data saved to {filename}.")except Exception as e:logger.error(f"Error saving to CSV: {e}")# JSON 文件存储
def save_to_json(data, filename):try:with open(filename, 'w') as f:json.dump(data, f, indent=4)logger.info(f"Data saved to {filename}.")except Exception as e:logger.error(f"Error saving to JSON: {e}")# SQLite 数据库存储
def save_to_sqlite(data):try:with closing(sqlite3.connect('products.db')) as conn:c = conn.cursor()c.execute('''CREATE TABLE IF NOT EXISTS products(product_name TEXT, price TEXT, rating TEXT, description TEXT)''')placeholders = ', '.join(['?'] * len(data[0]))columns = ', '.join(data[0].keys())sql = f'INSERT INTO products ({columns}) VALUES ({placeholders})'c.executemany(sql, [list(item.values()) for item in data])conn.commit()logger.info("Data saved to SQLite database.")except Exception as e:logger.error(f"Error saving to SQLite: {e}")# MongoDB 数据库存储
def save_to_mongodb(data):try:client = MongoClient('mongodb://localhost:27017/')db = client['products_db']collection = db['products']collection.insert_many(data)client.close()logger.info("Data saved to MongoDB database.")except Exception as e:logger.error(f"Error saving to MongoDB: {e}")# 主程序入口
if __name__ == '__main__':args = parser.parse_args()url = args.urlif not url.startswith(('http://', 'https://')):logger.error("Invalid URL format. Please ensure it starts with http:// or https://.")exit(1)products = fetch_data(url)if args.output_csv:save_to_csv(products, args.output_csv)if args.output_json:save_to_json(products, args.output_json)if args.output_sqlite:save_to_sqlite(products)if args.output_mongodb:save_to_mongodb(products)

代码解释

  • 命令行参数: 使用 argparse 解析命令行参数,允许用户指定 URL 以及输出文件名或数据库。
  • 日志: 使用标准的日志配置,可以方便地修改日志级别或输出位置。
  • 异常处理: 添加了针对网络请求的异常处理,包括常见的 HTTP 错误、连接错误等。
  • 数据验证: 在实际应用中,可能还需要对数据进行更严格的验证,例如检查数据是否符合预期格式。
  • 数据库连接: 使用 with closing() 语句管理 SQLite 连接,确保连接正确关闭。
  • URL 校验: 确保提供的 URL 是有效的 HTTP/HTTPS URL。

这个版本的代码提供了更多的灵活性和健壮性,可以根据具体需求进一步调整和完善。如果需要在生产环境中使用,还应考虑其他因素,如并发处理、更高级的错误恢复机制等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/49808.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LangChain4j-RAG高级-核心概念

RetrievalAugmentor整体概念 简单总结一下 LangChain4j中对于RetrievalAugmentor这里官方描述的比较模糊, 只在 DefaultRetrievalAugmentor章节给出来了一个灵感来源的文章(LangChain框架中的设计思路)和一个研究报告, 有兴趣可以看一下: Deconstructing RAGhttps://arxiv.o…

FRP配置内网穿透52版本以上适用

简述 适用frp配置内网穿透来说我们需要进行简单的区分,具有公网IP的服务器我们简称为服务端,内网的服务器我们可以简称为客户端,frp需要针对不同的服务器配置不同的文件 下载安装包 Linux下载地址 https://github.com/fatedier/frp/relea…

Flink SQL 的工作机制

前言 Flink SQL 引擎的工作流总结如图所示。 从图中可以看出,一段查询 SQL / 使用TableAPI 编写的程序(以下简称 TableAPI 代码)从输入到编译为可执行的 JobGraph 主要经历如下几个阶段: 将 SQL文本 / TableAPI 代码转化为逻辑执…

svelte - 5. 动画

动画函数 函数作用使用场景示例引入的模块使用示例tweened运动动画,做到渐变的效果控制进度条速度svelte/motion函数:tweened(0, { duration: 400 })spring运动动画,用于频繁变化的值控制鼠标红点顺滑度svelte/motion函数:spring({ x: 50, y: 50 }, { stiffness: 0.1, damp…

华为ensp中ISIS原理与配置(超详细)

isis原理与配置 8-20字节; 地址组成:area id,system id,set三部分组成; system id占6个字节;sel占一个,剩下的为area id区域号; system id 唯一, 一般将router id 配…

深入学习H264和H265

目录 前言 一 什么是H264/H265? H.264 (MPEG-4 AVC) H.265 (HEVC) 二 为什么要学习H264和H265? 1. 深入理解视频压缩原理 2. 硬件优化与集成 3. 调试与故障排除 4. 持续的技术更新 三 NAL(Network Abstraction Layer)详解…

【前端 11】初探DOM

JavaScript 对象 - DOM 初探 在Web开发中,DOM(Document Object Model,文档对象模型)是一个至关重要的概念。它不仅仅是一个API,更是Web页面与JavaScript代码之间的桥梁,允许开发者通过编程的方式动态地访问…

Redis:快速键值存储的入门指南

一、什么是Redis? Redis,全称为Remote Dictionary Server,是一种开源的、高性能的键值(Key-Value)存储系统。与传统的关系型数据库不同,Redis将数据主要存储在内存中,因此能够提供极低延迟的数…

【Unity2D 2022:UI】TextMeshPro组件无法显示中文

在Unity中创建了一个预制体Card,上面挂载了一些Text Mesh Pro组件用来显示卡牌信息。但是在输入文字后,发现无法显示中文: 解决方法如下: 一、导入字体文件(ttf格式)和常用字字集(txt格式&…

Linux--Socket编程UDP

前文:Socket套接字编程 UDP协议特点 无连接:UDP在发送数据之前不需要建立连接,减少了开销和发送数据之前的时延。尽最大努力交付:UDP不保证可靠交付,主机不需要维持复杂的连接状态表。面向报文:UDP对应用层…

算法:[递归/搜索/回溯]二叉树的深搜

目录 题目一:计算布尔二叉树的值 题目二:求根节点到叶节点数字之和 题目三:二叉树剪枝 题目四:验证二叉搜索树 题目五:二叉搜索树中第k小的元素 题目六:二叉树的所有路径 题目一:计算布尔…

【C语言】宏定义常量加 ; 的错误

我在使用宏定义常量定义二维数组的时候,编译器报错:应输入“]”,如下: 原因是宏定义不是C语言规定的语句,它的结尾不加 ; 。在上图的 int mine[EASY_ROWS][EASY_COLS]; 中,把 EASY_ROWS 替换为了 9;2; &…

【秋招笔试题】小明的美食

解析&#xff1a;思维题。由于需要互不相同&#xff0c;每次操作取重复的值与最大值相加即可&#xff0c;这样即可保证相加后不会新增重复的值。因此统计重复值即可。 #include <iostream> #include <algorithm>using namespace std; const int maxn 1e5 5; int…

大模型算法面试题(十一)

本系列收纳各种大模型面试题及答案。 1、说一下目前主流或前沿的预训练模型&#xff0c;包括nlp&#xff08;百度ERNIE3.0&#xff0c;华为NEZHA&#xff0c;openAI gpt-3&#xff0c;nvidia MegatronLM&#xff0c;macrosoft T5&#xff09;和cv&#xff08;我只知道CLIP&…

wordpress主题Typecho仿百度响应式主题Xaink

wordpress主题Typecho仿百度响应式主题Xaink 新闻类型博客主题&#xff0c;简洁好看&#xff0c;适合资讯类、快讯类、新闻类博客建站&#xff0c;响应式设计&#xff0c;支持明亮和黑暗模式 直接下载 zip 源码->解压后移动到 Typecho 主题目录->改名为xaink->启用

内衣洗衣机和手洗哪个干净?推荐五款品质优良精品

在日常生活中&#xff0c;内衣洗衣机已成为现代家庭必备的重要家电之一。选择一款耐用、质量优秀的内衣洗衣机&#xff0c;不仅可以减少洗衣负担&#xff0c;还能提供高效的洗涤效果。然而&#xff0c;市场上众多内衣洗衣机品牌琳琅满目&#xff0c;让我们往往难以选择。那么&a…

实时捕获数据库变更

1.CDC概述 CDC 的全称是 Change Data Capture &#xff0c;在广义的概念上&#xff0c;只要能捕获数据变更的技术&#xff0c;我们都可以称为 CDC 。我们目前通常描述的CDC 技术主要面向数据库的变更&#xff0c;是一种用于捕获数据库中数据变更的技术&#xff0c;CDC 技术应用…

Linux嵌入式学习——数据结构——队列

一、概念 1&#xff09;定义 是只允许在一端进行插入操作&#xff0c;而在另一端进行删除操作的线性表 队列 是一种 先进先出&#xff08;First In First Out&#xff09; 的线性表 线性表有顺序存储和链式存储&#xff0c;栈是线性表&#xff0c;所以有这两种存储方式 同样…

【在开发小程序的时候如何排查问题】

在开发小程序的时候如何排查问题 在最近开发小程序的时候&#xff0c;经常出现本地在浏览器中调试没有问题&#xff0c;但是一发布到预发环境就出现各种个样的问题 手机兼用性问题 有时候会出现苹果&#x1f34e;手机键盘弹出&#xff0c;导致ui界面高度出现异常边界问题&#…

Arduino IDE界面和设置(基础知识)

Arduino IDE界面和设置&#xff08;基础知识&#xff09; 1-2 Arduino IDE界面和设置如何来正确选择Arduino开发板型号如何正确选择Arduino这个端口如何来保存一个Arduino程序Arduino ide 的界面功能按钮验证编译上传新建打开保存工作状态 1-2 Arduino IDE界面和设置 大家好这…