python爬虫-多线程-数据库——WB用户

数据库database的包:

Python操作Mysql数据库-CSDN博客

效果:

控制台输出:

数据库记录:

全部代码:

import json
import os
import threading
import tracebackimport requests
import urllib.request
from utils import make_headers, base64_encode_img, url_img_cv2img
from database import MyDataBaseclass WeiboUserCrawler(threading.Thread):def __init__(self, user_id: str, path: str = "weibo", proxy_addr: str = "122.241.72.191:808"):super(WeiboUserCrawler, self).__init__(target=self.run)self.user_id = user_idself.path = pathself.proxy_addr = proxy_addrself.url = 'https://m.weibo.cn/api/container/getIndex?type=uid&value=' + self.user_idself.container_id = self.get_container_id(self.url)self.page = 1  # 微博页数self.pic_num = 0  # 图片编号self.flag = Trueself.wb_db = MyDataBase("localhost", "123456", charset="utf8mb4")self.users_sheet = "user_info"  # 所有用户信息表self.user_sheet = "user_" + self.user_id  # 单个用户内容表self.imgs_sheet = "user_imgs"  # 所有用户图片表self.create_file()self.create_db_tables()print("####" * 10)# 创建文件夹def create_file(self):if not os.path.exists(self.path):os.makedirs(self.path)if not os.path.exists(self.path + "/" + self.user_id):os.makedirs(self.path + "/" + self.user_id)# 创建三张表def create_db_tables(self):self.wb_db.connect()kwargs = {"id": "int primary key auto_increment","name": "varchar(128)","user_id": "varchar(20)","profile_url": "varchar(200)","verified": "varchar(50)","profile_image_url": "varchar(200)","description": "text","follows": "varchar(50)","fans": "varchar(50)","gender": "varchar(8)","lv": "tinyint"}self.wb_db.create_table(self.users_sheet, kwargs)kwargs = {"id": "int primary key auto_increment","u_id": "varchar(20)","url": "varchar(200)",}self.wb_db.create_table(self.imgs_sheet, kwargs)kwargs = {"id": "int primary key auto_increment","page": "int","locate": "varchar(128)","created_time": "varchar(128)","content": "text","praise": "varchar(50)","comments": "text","reposts": "varchar(50)",}self.wb_db.create_table(self.user_sheet, kwargs)def use_proxy(self, url):req = urllib.request.Request(url)req.add_header("User-Agent", make_headers()["User-Agent"])proxy = urllib.request.ProxyHandler({'http': self.proxy_addr})opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler)urllib.request.install_opener(opener)data = urllib.request.urlopen(req).read().decode('utf-8', 'ignore')return data  # 返回的是字符串def get_container_id(self, url):data = self.use_proxy(url)# 通过json从获取的网页数据中,找到datacontent = json.loads(data).get('data')# 从data中找到container_idfor data in content.get('tabsInfo').get('tabs'):if data.get('tab_type') == 'weibo':container_id = data.get('containerid')return container_iddef get_user_info(self):data = self.use_proxy(self.url)# 通过json从获取的网页数据中,找到datacontent = json.loads(data).get('data')# 从data数据中获取下列信息profile_image_url = content.get('userInfo').get('profile_image_url')description = content.get('userInfo').get('description')profile_url = content.get('userInfo').get('profile_url')verified = content.get('userInfo').get('verified')follows = content.get('userInfo').get('follow_count')name = content.get('userInfo').get('screen_name')fans = content.get('userInfo').get('followers_count')gender = content.get('userInfo').get('gender')lv = content.get('userInfo').get('urank')data = f"微博昵称:{name}\n微博主页地址:{profile_url}\n微博头像地址:{profile_image_url}\n" \f"是否认证:{verified}\n微博说明:{description}\n关注人数:{follows}\n" \f"粉丝数:{fans}\n性别:{gender}\n微博等级:{lv}\n"print(data)path = f"{self.path}/{self.user_id}/{self.user_id}.txt"with open(path, 'a', encoding='utf-8') as f:f.write(data)# 数据库存用户users_sheet_field = ("name", "user_id", "profile_url", "verified", "profile_image_url", "description", "follows","fans", "gender", "lv")data = [name, self.user_id, profile_url, verified, profile_image_url, description, follows, fans, gender,lv]res = self.wb_db.select_table_record(self.users_sheet, f"where user_id={self.user_id}")for i in res:if self.user_id in i:print("该用户已在数据库!")returnself.wb_db.insert_data(self.users_sheet, users_sheet_field, data)# 存图下载图def save_img(self, mblog):try:if mblog.get('pics'):pic_archive = mblog.get('pics')for _ in range(len(pic_archive)):self.pic_num += 1img_url = pic_archive[_]['large']['url']img_data = requests.get(img_url)path = f"{self.path}/{self.user_id}/{self.user_id}_{self.pic_num}{img_url[-4:]}"with open(path, "wb") as f:f.write(img_data.content)# 数据库存图imgs_sheet_field = ("u_id", "url")data = [self.user_id, img_url]self.wb_db.insert_data(self.imgs_sheet, imgs_sheet_field, data)except Exception as err:traceback.print_exc()def save_data(self, j, mblog, cards):path = f"{self.path}/{self.user_id}/{self.user_id}.txt"attitudes_count = mblog.get('attitudes_count')comments_count = mblog.get('comments_count')created_at = mblog.get('created_at')reposts_count = mblog.get('reposts_count')scheme = cards[j].get('scheme')text = mblog.get('text')with open(path, 'a', encoding='utf-8') as f:f.write(f"----第{self.page}页,第{j}条微博----" + "\n")f.write(f"微博地址:{str(scheme)}\n发布时间:{str(created_at)}\n微博内容:{text}\n"f"点赞数:{attitudes_count}\n评论数:{comments_count}\n转发数:{reposts_count}\n")# 数据库存微博内容user_sheet_field = ("page", "locate", "created_time", "content", "praise", "comments", "reposts")data = [self.page, scheme, created_at, text, attitudes_count, comments_count, reposts_count]self.wb_db.insert_data(self.user_sheet, user_sheet_field, data)def process_data(self, data):content = json.loads(data).get('data')cards = content.get('cards')if len(cards) > 0:for j in range(len(cards)):print(f"-----正在爬取{self.user_id}:第{self.page}页,第{j + 1}条微博------")card_type = cards[j].get('card_type')if card_type == 9:mblog = cards[j].get('mblog')self.save_img(mblog)self.save_data(j, mblog, cards)self.page += 1else:self.flag = Falsedef run(self):try:self.get_user_info()while True:weibo_url = f"{self.url}&containerid={self.container_id}&page={self.page}"try:data = self.use_proxy(weibo_url)self.process_data(data)if not self.flag:print(f">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>已完成{self.user_id}")self.wb_db.close()breakexcept Exception as err:print(err)except Exception as err:print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>异常退出!')self.wb_db.close()if __name__ == '__main__':# 1669879400   # 热巴# 5372556014 # 李一桐# 1662262590 # 张予曦# uid = "1669879400"# wb = WeiboUserCrawler(uid)# wb.start()uids = ["1669879400", "5372556014", "1662262590"]for uid in uids:t = WeiboUserCrawler(uid)t.start()

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

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

相关文章

论文阅读-一个用于云计算中自我优化的通用工作负载预测框架,

论文标题:A Self-Optimized Generic Workload Prediction Framework for Cloud Computing 概述 准确地预测未来的工作负载,如作业到达率和用户请求率,对于云计算中的资源管理和弹性非常关键。然而,设计一个通用的工作负载预测器…

docker-compose安装配置jenkins

archery 安装docker-compose curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-uname -s-uname -m -o /usr/local/bin/docker-composechmod 755 /usr/local/bin/docker-composedocker-compose version 安装docker yum install epel-rel…

【每日一题】6.LeetCode——轮转数组

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》|《数据结构与算法》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏小杨水平有限,欢…

【nginx实战】通过nginx实现http 长连接(即keep alive)

文章目录 一. http的长连接历史1. HTTP短连接模型2. HTTP长连接模型 二. nginx作为代理时实现HTTP长连接1. nginx与client的长连接1.1. keepalive_timeout指令1.2. keepalive_requests指令* 场景分析 2. 保持和server的长连接2.1. location设置* 场景分析 2.2. upstream设置* 场…

typescript 的基本用法说明

声明数组的两种方式 let x1: number[]; x1 [1, 2, 3]; // 方式1 let x2: Array<number> [1, 2, 3]; // 泛型 元组的含义 let x3: [string, number]; // 确定数量和类型 x3 [12, 10]; 枚举 enum Color { // 默认从0开始编码 &#xff0c;或者从第一个数字开始递增…

PVE报错处理:kvm [2205]: vcpu0 ignored RDMSR: 0x1b8

PVE使用过程中如果遇到&#xff1a;kvm [2205]: vcpu0 ignored RDMSR: 0x1b8 报错信息处理方法 vim /etc/modprobe.d/kvm.conf "options kvm ignore_msrsY"&#xff0c;这里在msrsY后面加一个空格&#xff0c;然后粘贴report_ignored_msrsN&#xff0c;使其变成 op…

【pytorch进阶】| 各类张量形状变化函数总结对比分析,view,reshape,pernute,transpose,squeeze,unsqueeze

文章目录 1 view&#xff08;&#xff09;函数1.1 基本用法 2 view_as&#xff08;&#xff09;函数3 reshape&#xff08;&#xff09;函数4 permute&#xff08;&#xff09;函数5 transpose&#xff08;&#xff09; 函数6 squeeze&#xff08;&#xff09;函数 和 unsqueez…

为什么建议不要买入耳式的耳机?有没有不伤听力的蓝牙耳机

为什么建议不要买入耳式的耳机&#xff1f;因为长时间佩戴入耳式耳机可能会导致耳朵不适甚至疼痛&#xff0c;且存在听力损伤、耳膜损伤的风险&#xff0c;还可能诱发耳道发炎。那么有没有不伤听力的蓝牙耳机呢&#xff1f;当然是有的&#xff0c;我建议尝试一下骨传导蓝牙耳机…

简单实践 java spring cloud 负载均衡

1 概要 1.1 实现一个最简单的微服务。远程调用负载均衡&#xff0c;基本上完成了最核心的微服务框架。 远程调用&#xff1a;RestTemplate 注册中心&#xff1a;eureka 负载均衡&#xff1a;Ribbon 1.2 要点 1.2.1 依赖 1.2.1.1 主框架依赖 spring boot 依赖 <depe…

HarmonyOS鸿蒙 虚拟像素 图片显示

Android中&#xff0c;有的sp&#xff0c;dp&#xff0c;dpi&#xff0c;px等概念。 dpi&#xff0c;dots per inch&#xff0c;代表屏幕像素密度。是指屏幕上每英寸&#xff08;1英寸 2.54 厘米&#xff09;距离中有多少个像素点。 dp&#xff0c;device independent pixels&…

Camille-接口测试

* 接口&#xff1a;不同的系统之间相互连接的部分&#xff0c;是一个传递数据的通道 * 接口测试&#xff1a;检查数据的交换、传递和控制管理过程 网络模型&#xff1a; OSI七层模型 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 TCP/IP四层模型 应用层 传输层 网络…

GPT-4 Vision根据应用程序截图生成博客和Readme 升级Streamlit八

GPT-4 Vision 系列: 翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式一翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式二翻译: GPT-4 Vision静态图表转换为动态数据可视化 升级Streamlit 三翻译: GPT-4 Vision从图像转换为完全可编辑的表格 升级St…

虚拟机(VMware)ubuntu16.04 直接连接网口设备 USRP 吊舱

编辑虚拟网络编辑器 点击之后 选择网卡之后&#xff0c;点击确定。 电脑配置 使用了&#xff1a;192.168.2.56 虚拟机内部配置 和PC的配置一致

leetcode刷题(剑指offer) 101.对称二叉树

101.对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false提示&#xff1a; …

Elasticsearch性能调优

背景 项目上是用 ES 做数据库&#xff0c;存储的告警数据&#xff0c;量级在千万级别左右。测试在压测之后&#xff0c;系统频繁出现告警记录查询报错&#xff0c;系统不可用。基于此排查分析项目上 Elasticsearch 的使用是否合理。 版本及硬件 环境&#xff1a;10.xx.xxx.x…

vue前端html导出pdf

package.json中添加依赖 调用方&#xff1a; import htmlToPdf from ../../../utils/file/htmlToPdf.js// 下载方法&#xff0c;pdfDownloadDpi为onClickDownLoad() {htmlToPdf.getPdf(标题1, jsfgyzcpgxmShow, this.pdfDownloadDpi)}htmlToPdf.js // 页面导出为pdf格式 imp…

漏洞01-目录遍历漏洞/敏感信息泄露/URL重定向

目录遍历漏洞/敏感信息泄露/URL重定向 文章目录 目录遍历敏感信息泄露URL重定向 目录遍历 敏感信息泄露 于后台人员的疏忽或者不当的设计&#xff0c;导致不应该被前端用户看到的数据被轻易的访问到。 比如&#xff1a; ---通过访问url下的目录&#xff0c;可以直接列出目录下…

秋招面试—JS篇

2024 JavaScript面试题 1.new 操作符的工作原理 ①.创建一个新的空对象 ②.将这个对象的原型设置为函数的 prototype 对象 ③.让函数的this指向该对象&#xff0c;为函数添加属性和方法 ④.最后返回这个对象 2.什么是DOM&#xff0c;什么是BOM? DOM&#xff1a;文档对象…

代码随想录算法训练营第二十二天|235 二叉搜索树的最近公共祖先、701 二叉搜索树中的插入操作、450 删除二叉搜索树中的节点

235 二叉搜索树的最近公共祖先 题目链接&#xff1a;二叉搜索树的最近公共祖先 思路 因为二叉搜索树是有序的&#xff0c;因此p和q的最近公共祖先一定在两者之间&#xff0c;所以每到一个节点&#xff0c;该节点的数值如果大于p和q&#xff0c;则朝左子树走&#xff1b;如果…

C/C++ - 函数模板

目录 函数模板基础 函数模板定义 函数模板实例 函数模板调用 函数模板本质 模板函数特化 模板参数限定 默认模板参数 多个模板参数 非类型模板参数 函数模板拓展 模板参数匹配规则 函数模板基础 函数模板定义 使用 template <typename T>​​​​​ 或 templ…