【互联网有记忆】爬取微博热搜榜并存入数据库(python爬虫+存储过程后端实现)

2023-11-11

一、爬虫代码

import random, time
import requests, re
import datetime
import mysql.connector

# 定义爬取间隔(minutes)
interval_time = 15

class HotSearchThread:
    def __init__(self):
        self.curTime = datetime.datetime.now()
        print('[start]开始爬取热搜榜..........')

    # 爬取html页面数据
    def getHtml(self):
        url = "https://s.weibo.com/top/summary?cate=realtimehot"
        headers = [
            {
                "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0"
            },
            {
                "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50"
            },
            {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"
            },
            {
                "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36"
            },
            {
                "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
            }
        ]
        header = headers[random.randint(0,len(headers)-1)]
        response = requests.get(url=url, headers=header)
        return response.content.decode()

    # 处理html页面数据,得到绘图所需数据
    def getData(self, html):
        pattern = '<tr.*?<td\s+class="td-01.*?>(\d{1,2})</td>.*?<td\s+class="td-02.*?<a.*?>(.*?)</a>'
        data_rank = re.compile(pattern, re.S).findall(html)

        pattern_top = '<tr.*?<td\s+class="td-(\d)1.*?icon-top.*?</td>.*?<td\s+class="td-02.*?<a.*?>(.*?)</a>'
        data_top = re.compile(pattern_top, re.S).findall(html)

        data = data_top + data_rank

        tail = (datetime.datetime.strftime(self.curTime,'%Y%m%d_%H%M%S'), interval_time)
        for i in range(0,len(data)):
            data[i]  +=  tail
        # print(data)
        print('[success]爬取成功!')
        return data

    # 存入数据库
    def saveDAO(self, data):
        # data为 list 类型
        # data[i]为 元组 类型,若len(data)为51,则data[0]为置顶
        # (ranknum, searchItem, time, duration)
        print('[start]开始写入数据库..........')
        conn = mysql.connector.connect(host="127.0.0.1", port=3306, user="WeiboHotSearch",
                                       password="ws1234.", database="WeiboHotSearch")
        cursor = conn.cursor()
        sql1="SELECT count(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='WeiboHotSearch' AND TABLE_NAME=%s;"
        tablename= "table" + datetime.datetime.strftime(self.curTime,'%Y%m')
        val1=(tablename,)
        cursor.execute(sql1, val1)
        res = cursor.fetchone()
        if res[0]==0:
            sql2="call CreateTablePro(%s);"
            val2=(tablename,)
            cursor.execute(sql2, val2)
        for item in data:
            sql3 = "call SelectDataPro(%s, %s, %s, %s, %s, @cnt);"
            sql4 = "select @cnt;"
            val3 = (tablename, int(item[0]), item[1], item[2], item[3])
            cursor.execute(sql3, val3)
            cursor.execute(sql4)
            cnt = cursor.fetchone()
            if cnt[0]==0:
                sql4="call InsertDataPro(%s, %s, %s, %s, %s)"
                val4=(tablename, int(item[0]), item[1], item[2], item[3])
                cursor.execute(sql4, val4)
                print("[Add   ]新增条目:", item)
            else:
                sql5="call UpdateDataPro(%s, %s, %s, %s, %s)"
                val5 = (tablename, int(item[0]), item[1], item[2], item[3])
                cursor.execute(sql5, val5)
                print("[Update]更新条目:", item)

        conn.commit()
        cursor.close()
        conn.close()


    def run(self):
        print("[start] Time: ", datetime.datetime.strftime(self.curTime,'%Y-%m-%d %H:%M:%S'))
        data = self.getData(self.getHtml())
        self.saveDAO(data)
        print("--------------------------------------------------------------")
        print("[over]写入结束!")
        print("--------------------------------------------------------------")
        print("")
        print("")

if __name__ == '__main__':
    print("[Initialized] 开机自启动加载完成!等待运行!")
    time.sleep(60) # 开机等待60秒再运行,防止数据库服务未启动等异常
    while 1:
        HotSearchThread().run()
        time.sleep(interval_time * 60)

二、数据库实现

防止数据库单个表太大,按月份自动生成表,使用存储过程进行管理

 存储过程:

--- CreateTablePro
CREATE DEFINER=`WeiboHotSearch`@`%` PROCEDURE `CreateTablePro`(IN `tableName` varchar(50))
BEGIN
 	set @tname = tableName;
	set @sql_create_table = concat(
	'CREATE TABLE IF NOT EXISTS ', @tname,
	'(num int(2),searchItem varchar(255) primary key,hotTime varchar(255),duration int(5))'
	);
	PREPARE sql_create_table from @sql_create_table;
	EXECUTE sql_create_table;
END
--- SelectDataPro
CREATE DEFINER=`WeiboHotSearch`@`%` PROCEDURE `SelectDataPro`(IN `tableName` varchar(50),IN `num` int(2),IN `searchItem` varchar(255),IN `hotTime` varchar(255),IN `duration` int(5), OUT `cnt` int(5))
BEGIN
	 	set @tname = tableName;
		set @num = num;
		set @sItem = searchItem;
		set @hTime = hotTime;
		set @dur = duration;
		
		set @sql_query_data = concat(
			'select count(@sItem) into @cnt from ', @tname, ' where searchItem =  @sItem' 
		);
		PREPARE sql_query_data from @sql_query_data;
		EXECUTE sql_query_data;
		set cnt=@cnt;
		
END
--- InsertDataPro
CREATE DEFINER=`WeiboHotSearch`@`%` PROCEDURE `InsertDataPro`(IN `tableName` varchar(50),IN `num` int(2),IN `searchItem` varchar(255),IN `hotTime` varchar(255),IN `duration` int(5))
BEGIN
	 	set @tname = tableName;
		set @num = num;
		set @sItem = searchItem;
		set @hTime = hotTime;
		set @dur = 0;
		
		set @sql_insert_data = concat(
		'insert into ', @tname,' values( @num, @sItem, @hTime, @dur);'
		);
		PREPARE sql_insert_data from @sql_insert_data;
		EXECUTE sql_insert_data;
END
--- UpdateDataPro
CREATE DEFINER=`WeiboHotSearch`@`%` PROCEDURE `UpdateDataPro`(IN `tableName` varchar(50),IN `num` int(2),IN `searchItem` varchar(255),IN `hotTime` varchar(255),IN `duration` int(5))
BEGIN
	 	set @tname = tableName;
		set @num = num;
		set @sItem = searchItem;
		set @hTime = hotTime;
		set @dur = duration;
		
		set @sql_insert_data1 = concat(
		'update ', @tname,' set duration=duration+@dur where searchItem = @sItem'
		);
		PREPARE sql_insert_data1 from @sql_insert_data1;
		EXECUTE sql_insert_data1;
		
		
		set @sql_insert_data = concat(
		'update ', @tname,' set num=@num, hotTime=@hTime where searchItem = @sItem and num>@num'
		);
		PREPARE sql_insert_data from @sql_insert_data;
		EXECUTE sql_insert_data;
END

其他 :

--- 建表模板
drop table tablename;
CREATE table tablename (
	num int(2),
	searchItem varchar(255) primary key,
	hotTime varchar(255),
	duration int(5)
)

--- 判断数据库中是否存在某张表
SELECT count(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='WeiboHotSearch' AND TABLE_NAME='test';


--- 存储过程的调用
call CreateTablePro('test')

call InsertDataPro('table202003', 0, '复工复产保卫战', '20200324_165840', 20)

call SelectDataPro('table202003', 0, '复工复产保卫战', '20200324_165840', 20, @cnt);
select @cnt;

call UpdateDataPro('table202003', 30, '方方', '20200324_165840', 20)

--- select 查询验证
select * from table202003 where duration = 20


--- mysql创建并调用含有out参数的存储过程
CREATE PROCEDURE sp_add(a int, b int,out c int)
begin

 set c=a+ b;

end;
--- 调用过程:
call sp_add (1,2,@a);
select @a;

 
 三、aliyun部署 

# 脚本路径:
/root/myPyProgram/Weibo.py
# 脚本日志:
/root/myPyProgram/logs/Weibo.log

# 设置开机启动
chmon +x /etc/rd.local
vim /etc/rd.local

#追加内容:
/usr/bin/python3 -u /root/myPyProgram/Weibo.py  &>> /root/myPyProgram/logs/Weibo.log


# 查看进程状态
ps -aux|grep "Weibo.py"   # 会显示开始运行时间,结束时间等
ps -ef|grep "Weibo.py"   # 只显示进程相关信息

# 查询进程id
ps -ef | grep Weibo.py | grep -v grep | awk '{print $2}'
# 查询进程id并杀死该进程
ps -ef | grep Weibo.py | grep -v grep | awk '{print $2}' | xargs kill -9

# 杀死进程
kill -9 [进程id]

 shell 脚本杀死进程 dsp-admin

echo "开始查询DSP2.0运行的进程编号,查出将其kill"
dsp_admin_id=`ps -ef | grep dsp-admin | grep -v "grep" | awk '{print $2}'`
echo $dsp_admin_id

for id in $dsp_admin_id
do
    kill -9 $id  
    echo "killed $id"  
done

四、运行截图 

 

 

五、相关问题及解决方案

1、日志文件创建了,程序执行了,但是日志为0K,tail -f Weibo.log查看为空:

                python程序输出无内容问题

2、/usr/local/bin/python3不存在,需要添加软连接

               Linux下开机启动python脚本详解

3、mysql存储过程相关

              mysql存储过程用表名做参数 并获取execute执行语句的结果 

              MySql存储过程动态创建表并插入数据 

              Mysql中表名作为参数的问题

4、linux查看进程状态

              linux命令ps aux|grep xxx详解 

5、Linux中没有rc.local文件的完美解决方法

             解决办法步骤一

             解决办法步骤二

6、python获取当前系统时间并格式化

            python 如何获取当前系统的时间

7、linux脚本设置开机启动(后台)

            链接 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【互联网有记忆】爬取微博热搜榜并存入数据库(python爬虫+存储过程后端实现) 的相关文章

  • 用定点迭代求解该方程

    我怎样才能解这个方程 x3 x 1 0 使用定点迭代 有没有定点迭代我可以在网上找到代码 尤其是Python 吗 Using scipy optimize fixed point http docs scipy org doc scipy
  • WordPress 访问

    我正在与朋友一起开发一个网站 使用Wordpress我们正在尝试从我的计算机和他的计算机访问同一个 WordPress 帐户 以便我们可以一起在网站上工作 我们尝试将彼此添加为管理员 但只能从创建管理员的计算机上访问新帐户 有谁知道如何做到
  • 可以memmap pandas系列。数据框怎么样?

    看来我可以通过创建 mmap d ndarray 并使用它来初始化系列来对 python 系列的底层数据进行内存映射 def assert readonly iloc try iloc 0 999 Should be non editabl
  • 如何在 MySql Workbench 中禁用 INVISIBLE 索引选项?

    我刚刚安装了MySqlWorkbench我发现了实施INVISIBLE index所描述的here https dev mysql com doc refman 8 0 en invisible indexes html 我想禁用此功能 因
  • 在我的 Mac 上以 root 身份运行 pip 时出现“权限被拒绝”

    我开始使用我的 Mac 来安装 Python 包 就像我在工作中使用 Windows PC 一样 然而在我的 Mac 上我经常遇到没有权限写入日志文件或站点包时出错 于是我想到了跑步pip install
  • Selenium 上的切换窗口

    我在 Python 中使用 Selenium 和 PhantomJS 我需要打开一个新窗口并控制它 出于测试目的 我这样做 from selenium import webdriver driver webdriver PhantomJS
  • 错误:NVIDIA-SMI 失败,因为无法与 NVIDIA 驱动程序通信

    NVIDIA SMI 抛出此错误 NVIDIA SMI 失败 因为无法与 NVIDIA 通信 司机 确保安装了最新的 NVIDIA 驱动程序并且 跑步 我清除了 NVIDIA 并按照提到的步骤重新安装了它here https askubun
  • Linux命令列出所有可用命令和别名

    是否有一个 Linux 命令可以列出该终端会话的所有可用命令和别名 就好像您输入 a 并按下 Tab 键一样 但针对的是字母表中的每个字母 或者运行 别名 但也返回命令 为什么 我想运行以下命令并查看命令是否可用 ListAllComman
  • 更新或插入 MySQL Python

    如果记录已存在 我需要更新一行 如果不存在 我需要创建一个新记录 我理解 ON DUPLICATE KEY 将使用 MYSQLdb 完成此操作 但是我无法使其正常工作 我的代码如下 cursor database cursor cursor
  • 在 grpc python 中处理异步流请求

    我试图了解如何使用双向流处理 grpc api 使用 Python API 假设我有以下简单的服务器定义 syntax proto3 package simple service TestService rpc Translate stre
  • Google App Engine self.redirect() POST 方法

    在 GAE Python 中 使用 webApp 框架 调用 self redirect some url 通过 GET 方法将用户重定向到该 URL 是否也可以通过带有一些参数的 POST 方法进行 重定向 如果可以的话 怎样做 Than
  • Python:如何对数组 X 进行排序,但对 Y 进行相同的相对排序?

    例如 X 5 6 2 3 1 Y 7 2 3 4 6 我对X进行排序 X 1 2 3 5 6 但我希望对 Y 应用相同的相对排序 以便数字保持与以前相同的相对位置 Y 6 3 4 7 2 我希望这是有道理的 通常 你会做一个zip sort
  • 访问 Scrapy 内的 django 模型

    是否可以在 Scrapy 管道内访问我的 django 模型 以便我可以将抓取的数据直接保存到我的模型中 我见过this https scrapy readthedocs org en latest topics djangoitem ht
  • gstreamer 中的无缝视频循环

    我正在尝试使用 gstreamer 循环播放视频 它是 python 绑定 第一次尝试是hook EOSmessage并为管道生成搜索消息 import gi gi require version Gst 1 0 from gi repos
  • 在Python中通过sys.stdout写入unicode字符串

    暂时假设一个人无法使用print 从而享受自动编码检测的好处 所以这给我们留下了sys stdout 然而 sys stdout太蠢了不做任何合理的编码 http bugs python org issue4947 现在人们阅读 Pytho
  • *Python 内的 Kaggle API 文档?

    我想写一个python从 Kaggle com 下载公共数据集的脚本 Kaggle API 是用 python 编写的 但是我能找到的几乎所有文档和资源都是关于如何在命令行中使用该 API 的 而关于如何使用kaggle图书馆内python
  • Spark (Python) 中的 Kolmogorov Smirnov 测试不起作用?

    我正在 Python Spark ml 中进行正态性测试 看到了我的结果think是一个错误 这是设置 我有一个标准化的数据集 范围 1 到 1 当我做直方图时 我可以清楚地看到数据不正常 gt gt gt prices norm hist
  • MySQL-分割字符串

    我的问题与这篇文章类似 MySQL 中的 反向 GROUP CONCAT https stackoverflow com questions 17308669 reverse group concat in mysql 然而 而不是反转gr
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理
  • 查询中的存储过程

    有一个程序获取文件列表 顾名思义 返回一个文件列表以及更多选项 那么是否可以在查询选择中使用此过程 像这样的东西 select Field1 from Image where Field2 IN call GetFileList 你应该把它

随机推荐