【python爬虫案例】爬取微博任意搜索关键词的结果,以“唐山打人”为例

一、爬取目标

大家好,我是马哥

今天分享一期python爬虫案例,爬取目标是新浪微博的微博数据,包含:

页码, 微博id, 微博bid, 微博作者, 发布时间, 微博内容, 转发数, 评论数, 点赞数

经过分析调研,发现微博有3种访问方式,分别是:

  1. PC端网页:https://weibo.com/

  2. 移动端:https://weibo.cn/

  3. 手机端:https://m.weibo.cn/

最终决定,通过手机端爬取。

这里,给大家分享一个爬虫小技巧。当目标网站既存在PC网页端,又有手机移动端,建议爬取移动端,原因是:移动端一般网页结构简单,并且反爬能力较弱,更方便爬虫爬取。

二、展示爬取结果

我通过爬虫代码,爬取了“唐山打人”这个关键字下的前80页微博,部分数据如下:爬取结果
一共635条数据,共80页,差不多每页不到10条的数据。

三、讲解代码

首先,导入需要用到的库:

import os
import re  # 正则表达式提取文本
from jsonpath import jsonpath  # 解析json数据
import requests  # 发送请求
import pandas as pd  # 存取csv文件
import datetime  # 

然后,定义一个转换时间字符串的函数,因为爬取到的时间戳是GMT格式(类似这种:Fri Jun 17 22:21:48 +0800 2022)的,需要转换成标准格式:

def trans_time(v_str):
	"""转换GMT时间为标准格式"""
	GMT_FORMAT = '%a %b %d %H:%M:%S +0800 %Y'
	timeArray = datetime.datetime.strptime(v_str, GMT_FORMAT)
	ret_time = timeArray.strftime("%Y-%m-%d %H:%M:%S")
	return ret_time

定义一个请求头,后面发送请求的时候带上它,防止反爬:

# 请求头
headers = {
	"User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Mobile Safari/537.36",
	"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
	"accept-encoding": "gzip, deflate, br",
}

打开chrome浏览器,按F12进入开发者模式,按照下图操作,分析出目标请求地址:开发者模式
根据分析结果,编写请求代码:

# 请求地址
url = 'https://m.weibo.cn/api/container/getIndex'
# 请求参数
params = {
	"containerid": "100103type=1&q={}".format(v_keyword),
	"page_type": "searchall",
	"page": page
}
# 发送请求
r = requests.get(url, headers=headers, params=params)

直接用json格式,接收返回的数据:

# 解析json数据
cards = r.json()["data"]["cards"]

下面,通过jsonpath,快速解析出各个字段数据。

科普知识:jsonpath是一种快速解析json数据的方法,语法规则有点像xpath,这里就不展开讲了,

详细介绍,请见:

JsonPath完全介绍及详细使用教程_Sunny蔬菜小柠的博客-CSDN博客_jsonpath

下面展示部分字段解析过程:

# 转发数
reposts_count_list = jsonpath(cards, '$..mblog.reposts_count')
# 评论数
comments_count_list = jsonpath(cards, '$..mblog.comments_count')
# 点赞数
attitudes_count_list = jsonpath(cards, '$..mblog.attitudes_count')

把所有的字段的list数据,拼装成DataFrame格式数据:

# 把列表数据保存成DataFrame数据
df = pd.DataFrame(
	{
		'页码': [page] * len(id_list),
		'微博id': id_list,
		'微博bid': bid_list,
		'微博作者': author_list,
		'发布时间': time_list,
		'微博内容': text2_list,
		'转发数': reposts_count_list,
		'评论数': comments_count_list,
		'点赞数': attitudes_count_list,
	}
)

最后,通过to_csv,(记得加上参数 encoding='utf_8_sig')把数据持久化存储下来。
需要说明的是,微博数据爬取下来后,会存在少量重复数据,所以,去重处理一下:

# 删除重复数据
df.drop_duplicates(subset=['微博bid'], inplace=True, keep='first')
# 再次保存csv文件
df.to_csv(v_weibo_file, index=False, encoding='utf_8_sig')
print('数据清洗完成')

最终,数据保存完毕。

四、同步视频

4.1 演示视频

https://www.zhihu.com/zvideo/1521809935360385024

4.2 讲解视频

https://www.zhihu.com/zvideo/1521898658362155008


我是马哥,感谢您的阅读。

posted @ 2022-06-26 18:22  马哥python说  阅读(50)  评论(0编辑  收藏  举报