本人长期出售超大量微博数据、旅游网站评论数据,并提供各种指定数据爬取服务,Message to YuboonaZhang@Yahoo.com。同时欢迎加入社交媒体数据交流群:99918768

前言

  由于硬件等各种原因需要把大概170多万2t左右的微博图片数据存到Mysql中.之前存微博数据一直用的非关系型数据库mongodb,由于对Mysql的各种不熟悉,踩了无数坑,来来回回改了3天才完成。

挖坑填坑之旅

建表

存数据的时候首先需要设计数据库,我准备设计了3个表

微博表:[id, userid, blog_text, lat, lng, created_time, reserve]   pkey: id

图片表:[md5, pic_url, pic_bin, exif, reserve]   pkey: md5

关系表:[id, md5, reserve]   pkey: (id, md5)   fkey: (id, 微博表id)  (md5, 图片表md5)

  建表的时候别的问题都还好,主要是 pic_bin 的类型和 blog_text 的类型有很大的问题,首先是pic_bin的类型,开始设置的为BLOB,但是运行之后发现BLOB最大只能存1M的数据,并不能满足微博图片的存储,后改成MEDIUMBLOB(16M)基本能够满足要求了。再后来就是blog_text,我遇到的第一个大坑

  开始的时候很自然的设置blog_text的类型为TEXT,但跑起来发现有些数据存不进去,会报错,经筛查发现是有些微博文本中包含了emoji表情…随后找了很多资料发现是因为utf8下文字是三字节,但是emoji是四字节,需要将编码改成utf8mb4。然而我在mac上整mysql的配置文件报各种奇葩错误,一怒之下把TEXT改成了BLOB,就好了。因为本地是MAC,我要连接到远程的一台Windows上才能通过那个Windows连接到群晖的Mysql上…本地配置改了也白改。

存图片

  然后这就是一个大坑!!! 由于我使用的python3,所以读取图片得到的二进制的结果前面会有一个b’, 表示bytes,正是由于这个b’导致sql语句拼接的时候这个b后面的单引号会和sql语句的引号结合,导致后面的二进制没有在引号里面出错!二进制编码又不像string可以对字符转义,试了好多方法都不行!最后没有办法使用base64 对二进制进行加密转化成字符串,存到数据库中,然后要用时的时候再解密。

pic_bin = str(base64.b64encode(pic_bin))[2:-1]

改配置文件

  由于使用Python多进程,一个小时8G数据量,图片数据比较大,发包的时候回超过mysql的默认限制,出现Mysql server has gone away, 这个时候要改配置文件,在配置文件中参数

max_allowed_packet = 600M
wait_timeout = 60000

Lost connection to Mysql server during query

  程序跑着跑着总会出现这个错误,一直找原因,试了各种办法看了好多资料,一直都是错误。实在不知道什么原因了…后来一想,我管他什么原因,失去连接之后重新连接就行了。使用conn.Ping(True) 判断是否连接mysql成功。如果失去连接就重新连接就行了!最后解决了这个问题

代码实现

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Created by Baoyi on 2017/10/16
from multiprocessing.pool import Poolimport pymysql
import requests
import json
import exifread
from io import BytesIO
import configparser
import hashlib
import logging
import base64# 配置logging
logging.basicConfig(level=logging.WARNING,format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',datefmt='%a, %d %b %Y %H:%M:%S',filename='weibo.log',filemode='w')cf = configparser.ConfigParser()
cf.read("ConfigParser.conf")# 读取配置mysql
db_host = cf.get("mysql", "db_host")
db_port = cf.getint("mysql", "db_port")
db_user = cf.get("mysql", "db_user")
db_pass = cf.get("mysql", "db_pass")
db = cf.get("mysql", "db")# 创建连接
conn = pymysql.connect(host=db_host, user=db_user, passwd=db_pass, db=db, port=db_port, charset='utf8')
# 获取游标
cursor = conn.cursor()# 创建insert_sql
insert_blog_sql = ("INSERT IGNORE INTO blog(userid, id, blog_text, lat, lng, created_time) VALUES('{uid}', '{id}','{blog_text}','{lat}','{lng}','{created_time}')"
)insert_pic_sql = ("INSERT IGNORE INTO pics(pic_url, pic_bin, md5, exif) VALUES ('{pic_url}','{pic_bin}','{md5}','{exif}')"
)insert_relationship_sql = ("INSERT IGNORE INTO relationship(id, md5) VALUES ('{id}','{md5}')"
)uid = []with open('./data/final_id.txt', 'r') as f:for i in f.readlines():uid.append(i.strip('\r\n'))# 处理图片数据
def handle_pic(pic_url):large_pic_url = pic_url.replace('thumbnail', 'large')large_bin = requests.get(large_pic_url)return large_bin.contentdef get_poiid_info(uid):try:url = 'https://api.weibo.com/2/statuses/user_timeline.json'load = {'access_token': 'xxxxxxxxxx','uid': uid,'count': 100,'feature': 2,'trim_user': 1}get_info = requests.get(url=url, params=load, timeout=(10, 10))if get_info.status_code != 200:logging.warning(ConnectionError)passinfo_json = json.loads(get_info.content)info_json['uid'] = uidstatuses = info_json['statuses']# 处理筛选微博数据for status in statuses:id = status['idstr']if status['geo'] is not None:lat = status['geo']['coordinates'][0]lng = status['geo']['coordinates'][1]pic_urls = status['pic_urls']# 判断是否在北京if (115.7 < lng < 117.4) and (39.4 < lat < 41.6):# 若在北京,插入blog数据进库blog_text = status['text'].replace('\'', '\'\'')created_time = status['created_at']try:cursor.execute(insert_blog_sql.format(uid=uid, id=id, blog_text=blog_text, lat=lat, lng=lng,created_time=created_time))except pymysql.err.OperationalError as e_blog:logging.warning(e_blog.args[1])pass# conn.commit()# 处理图片for pic_url in pic_urls:# 获取原图片二进制数据pic_bin = handle_pic(pic_url['thumbnail_pic'])# 读取exif 数据pic_file = BytesIO(pic_bin)  # 将二进制数据转化成文件对象便于读取exif数据信息和生成MD5tag1 = exifread.process_file(pic_file, details=False, strict=True)tag = {}for key, value in tag1.items():if key not in ('JPEGThumbnail', 'TIFFThumbnail', 'Filename','EXIF MakerNote'):  # 去除四个不必要的exif属性,简化信息量tag[key] = str(value)tags = json.dumps(tag)  # dumps为json类型 此tag即为exif的json数据# 生成MD5MD5 = hashlib.md5(pic_file.read()).hexdigest()# 首先把二进制图片用base64 转成字符串之后再存try:cursor.execute(insert_pic_sql.format(pic_url=pic_url['thumbnail_pic'].replace('thumbnail', 'large'),pic_bin=str(base64.b64encode(pic_bin))[2:-1], md5=MD5,exif=tags))except pymysql.err.OperationalError as e_pic:logging.warning(e_pic.args[1])passtry:cursor.execute(insert_relationship_sql.format(id=id, md5=MD5))except pymysql.err.OperationalError as e_relation:logging.warning(e_relation)passconn.commit()else:logging.info(id + " is Not in Beijing")passelse:logging.info(id + ' Geo is null')passexcept pymysql.err.OperationalError as e:logging.error(e.args[1])passdef judge_conn(i):global conntry:conn.ping(True)get_poiid_info(i)except pymysql.err.OperationalError as e:logging.error('Reconnect')conn = pymysql.connect(host=db_host, user=db_user, passwd=db_pass, db=db, charset='utf8')get_poiid_info(i)def handle_tuple(a_tuple):read_uid_set = []for i in a_tuple:read_uid_set.append(i[0])return set(read_uid_set)if __name__ == '__main__':sql_find_uid = ("SELECT userid FROM blog")cursor.execute(sql_find_uid)read_uid_tuple = cursor.fetchall()read_list = handle_tuple(read_uid_tuple)print(len(read_list))new_uid = set(uid).difference(read_list)print(len(new_uid))pool = Pool()pool.map(judge_conn, list(new_uid))

个人博客

8aoy1.cn

爬取微博图片数据存到Mysql中遇到的各种坑\mysql存储图片\爬取微博图片相关推荐

  1. 爬取图片到mysql数据库_爬取微博图片数据存到Mysql中遇到的各种坑\mysql存储图片\爬取微博图片...

    前言 由于硬件等各种原因需要把大概170多万2t左右的微博图片数据存到Mysql中.之前存微博数据一直用的非关系型数据库mongodb,由于对Mysql的各种不熟悉,踩了无数坑,来来回回改了3天才完成 ...

  2. 爬虫图片mysql_爬取微博图片数据存到Mysql中遇到的各种坑\爬取微博图片\Mysql存储图片\微博爬虫...

    本人长期出售超大量微博数据.旅游网站评论数据,并提供各种指定数据爬取服务,Message to YuboonaZhang@Yahoo.com.同时欢迎加入社交媒体数据交流群:99918768 前言 由 ...

  3. mysql存储爬虫图片_爬取微博图片数据存到Mysql中遇到的各种坑\爬取微博图片\Mysql存储图片\微博爬虫...

    本人长期出售超大量微博数据.旅游网站评论数据,并提供各种指定数据爬取服务,Message to YuboonaZhang@Yahoo.com.同时欢迎加入社交媒体数据交流群:99918768 前言 由 ...

  4. python爬取图片存入mysql_python爬取微博图片数据存到Mysql中遇到的各种坑

    前言 由于硬件等各种原因需要把大概170多万2t左右的微博图片数据存到Mysql中.之前存微博数据一直用的非关系型数据库mongodb,由于对Mysql的各种不熟悉,踩了无数坑,来来回回改了3天才完成 ...

  5. 小猪的Python学习之旅 —— 14.项目实战:抓取豆瓣音乐Top 250数据存到Excel中

    小猪的Python学习之旅 -- 14.项目实战:抓取豆瓣音乐Top 250数据存到Excel中 标签:Python 一句话概括本文: 利用Excel存储爬到的抓取豆瓣音乐Top 250数据信息,还有 ...

  6. 抓取豆瓣音乐Top 250数据存到Excel中

    点击上方"程序员大咖",选择"置顶公众号" 关键时刻,第一时间送达! 引言: 失踪人口回归,最近比较迷茫,不知道是回头深究Android,还是继续 学Pytho ...

  7. mysql double 存储_关于MYSQL中FLOAT和DOUBLE类型的存储-阿里云开发者社区

    关于MYSQL中FLOAT和DOUBLE类型的存储 重庆八怪 2016-04-12 844浏览量 简介: 关于MYSQL中FLOAT和DOUBLE类型的存储 其实在单精度和双精度浮点类型存储中其存储方 ...

  8. 关于MYSQL中FLOAT和DOUBLE类型的存储

    关于MYSQL中FLOAT和DOUBLE类型的存储 其实在单精度和双精度浮点类型存储中其存储方式和C/C++一致准守IEEE标准他们都是浮点型的,所谓的浮点型,是小数点的位置可变,其能够表示的范围比定 ...

  9. mysql doen s exist_Mysql实例Mysql中大小写敏感问题导致的MySql Error 1146 Tabel doen’t exist错误...

    <Mysql实例Mysql中大小写敏感问题导致的MySql Error 1146 Tabel doen't exist错误>要点: 本文介绍了Mysql实例Mysql中大小写敏感问题导致的 ...

最新文章

  1. 3d查看器无法加载三维模型_珠峰登顶成功,送套三维模型给你
  2. 微信小程序之授权登录--项目需要
  3. matlab armax 无法识别,求教:Java调用系统辨识工具箱内的armax函数出错
  4. vtun中setsockopt fcntl等有关套接字设置
  5. php 公众号验证回调方法_微信公众号关键词自动回复设置方法!
  6. 持续集成部署Jenkins工作笔记0020---20.在GitHub上创建WebHook
  7. 客房预订+餐饮预订+酒店app+移动端通用版电商app模板+Axure高保真酒店预订管理系统+积分商城+餐饮预订系统+优惠券+订单管理+移动端酒店管理原型+酒店电商原型
  8. java在linux生成pdf文件,从 Java 应用程序动态生成 PDF 文件
  9. 牛客 128A 礼物 (组合计数)
  10. mysql 5.6 在线DDL
  11. 怎样将优酷独播1080P视频KUX格式转换成MP4
  12. 计算机技术手段在材料中的应用,计算机在材料加工中的应用.docx
  13. 如何拟合幂率分布的幂率
  14. html页面嵌入百度地图
  15. MSCOCO检测数据集类别中文名
  16. Matlab课后笔记之霍夫变换(Hough Transform)
  17. 2010中国互联网哈哈榜
  18. 怎样看 计算机类b0809,计算机类(B0809、A0812、A0854)为什么是神?
  19. 2022级计算机保研历程
  20. es使用教程之_score(评分)介绍

热门文章

  1. 好评如潮的手机APP送给你!
  2. 面试官:听说你还不知道条件熵是什么?
  3. 华为通用软件开发实习一面综合面总结
  4. 在Python中安装GDAL(最简单,最详细图文教程)
  5. C# winform制作文件分类管理器gui
  6. “万能的”电脑重装系统教程
  7. mac无法将xxx.zip解压缩到下载(错误 - 无此文件或目录)
  8. python:实现绘制png图片(附完整源码)
  9. 一招搞定可视化工作流设计器开发 巧用draw2d绝战可视化工作流设计器 友好的开源协议MIT
  10. echarts字变大_echarts饼图字体大小修改