本文共 3982 字,大约阅读时间需要 13 分钟。
现有的爬虫项目主要负责从斗图网爬取表情包,并将这些图片存储在本地硬盘上。然而,随着数据量的不断增加,本地存储方式逐渐显得不够高效。为了更好地管理和利用这些图片资源,我们决定对爬虫进行改进,采用MySQL数据库来存储这些图片数据。
在本次改进中,我们需要解决以下几个关键问题:
存什么?
我们需要将爬取到的图片文件存储到数据库中。图片的来源主要有以下几种:照片的主要属性包括文件名称、文件大小和文件格式等。
存放的必要性思考
将图片存入数据库可以带来以下好处:数据存放形式
在数据库中存储图片文件需要注意以下几点:TINYBLOB:最大存储256KB。BLOB:最大存储65KB。MEDIUMBLOB:最大存储16MB。LONGBLOB:最大存储4GB。MEDIUMBLOB能够满足大部分图片存储需求。为了实现图片存入数据库的功能,我们需要设计一个适合存储和检索图片的数据库表结构。
以下是我们设计的数据库表结构:
CREATE TABLE IF NOT EXISTS `picture` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `PicData` MEDIUMBLOB, PRIMARY KEY (`ID`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
ID:图片的唯一标识符,自增。PicData:存储图片文件的二进制数据。我们设计了一个Save_Picture类来负责将图片文件存入数据库。以下是类的实现代码:
import MySQLdbclass Save_Picture: def __init__(self, host, user, passwd, dbname): self.conn = MySQLdb.connect( host=host, user=user, passwd=passwd, db=dbname ) def setup(self): cursor = self.conn.cursor() cursor.execute(""" CREATE TABLE IF NOT EXISTS `picture` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `PicData` MEDIUMBLOB, PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1; """) cursor.close() def save_pic(self, file_path): with open(file_path, 'rb') as f: pic_data = f.read() cursor = self.conn.cursor() cursor.execute('INSERT INTO picture (PicData) VALUES (%s)', (MySQLdb.Binary(pic_data),)) self.conn.commit() cursor.close() 为了让图片能够被读取和显示,我们需要从数据库中取出图片数据并写入文件。以下是读取图片的实现代码:
import MySQLdbclass Read_Picture: def __init__(self, host, user, passwd, dbname): self.conn = MySQLdb.connect( host=host, user=user, passwd=passwd, db=dbname ) def read_pic(self): cursor = self.conn.cursor() cursor.execute('SELECT PicData FROM picture ORDER BY ID DESC LIMIT 1') result = cursor.fetchone() if result: pic_data = result[0] with open('output.jpg', 'wb') as f: f.write(pic_data) cursor.close() 为了实现从斗图网爬取表情包并存入数据库的功能,我们需要编写一个爬虫脚本。以下是爬虫的实现代码:
import requestsimport reimport timedef save_to_database(host, user, passwd, dbname, url): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36" } for page in range(0, 2): # 假设只爬取前两页 current_url = f"{url}{page+1}" response = requests.get(current_url, headers=headers) response.encoding = 'utf-8' # 突出提取图片链接 pattern = r'data-backup="(.*?)"' pic_links = re.findall(pattern, response.text) for link in pic_links: # 爬取单张图片 pic_response = requests.get(link, headers=headers) pic_data = pic_response.content # 连接数据库 db_conn = MySQLdb.connect( host=host, user=user, passwd=passwd, db=dbname ) db_cursor = db_conn.cursor() # 插入数据库 db_cursor.execute('INSERT INTO picture (PicData) VALUES (%s)', (MySQLdb.Binary(pic_data),)) db_conn.commit() db_cursor.close() db_conn.close() 数据库连接管理:在爬虫过程中,建议使用数据库连接池来管理数据库连接,以避免连接泄漏和性能问题。
图片大小优化:根据爬取到的图片大小选择合适的BLOB类型。例如,对于大多数表情包,MEDIUMBLOB已经足够。
异常处理:在实际应用中,需要对爬虫过程中的异常进行处理,确保数据库连接能够被正确关闭。
通过本次改进,我们成功地将之前依赖本地存储的爬虫项目迁移到了基于MySQL数据库的存储方式。这不仅提高了数据管理的效率,也为未来的扩展和维护提供了更好的基础。
转载地址:http://ulkr.baihongyu.com/