爬虫实现基本流程
一.明确需求
明确采集的网站及数据内容
- 目标:根据小红书作者主页链接,采集作者主页所有笔记,并保存为excel表格。
采集的字段包括作者、笔记类型、标题、点赞数、笔记链接。 - 网址:https://www.xiaohongshu.com/user/profile/64c38af4000000000e026b43
二. 分析思路
分析爬虫思路,概括如下:
- 打开小红书主页与登录
- 打开小红书作者主页,获取作者信息
- 提取页面笔记数据
- 循环下滑页面刷新数据,循环获取笔记数据
- 处理获取到的数据,去重,排序
- 保存到本地excel文件
三. 代码实现
1.导入库
from DrissionPage import ChromiumPage
from DataRecorder import Recorder
import pandas as pd
from tqdm import tqdm
import time
import random
import re
import openpyxl
import os
import math
2. 登录小红书网站
def countdown(n):
for i in range(n, 0, -1):
print(f'\r倒计时{i}秒', end='') # \r让光标回到行首 ,end=''--结束符为空,即不换行
time.sleep(1) # 让程序等待1秒
else:
print('\r倒计时结束')
使用 DrissionPage 库,打开小红书主页https://www.xiaohongshu.com,设置 30 秒延时,这时可以使用手机扫码登录账号。在登录的函数里调用倒计时函数。
def sign_in():
sign_in_page = ChromiumPage()
sign_in_page.get('https://www.xiaohongshu.com')
# 第一次运行需要扫码登录
print("请扫码登录")
# 倒计时30s
countdown(30)
只有第 1 次运行代码需要登录,浏览器会保存登录状态信息。第 2 次之后再运行代码,就免登录了,可以把 sign_in()步骤注释掉。
3. 打开小红书作者主页,获取作者信息
与登录小红书方法一样,只是要把打开的网址改为作者主页链接
在这里使用DrissionPage 库的定位元素方法,定位提取作者名字,方便后续写入excel文件和给excel文件命名。
def open(url):
global page, author
page = ChromiumPage()
page.get(f'{url}')
# 页面最大化
page.set.window.max()
# 定位作者信息
user = page.ele('.info')
# 作者名字
author = user.ele('.user-name', timeout=0).text
4. 提取页面笔记数据
使用DrissionPage库定位元素方法,定位到包含笔记信息的sections,定位标题,点赞,笔记链接信息。
def get_info():
# notes列表存放当前页面的笔记
notes = []
# 定位包含笔记信息的sections
container = page.ele('.feeds-container')
sections = container.eles('.note-item')
for section in sections:
# 笔记类型
if section.ele('.play-icon', timeout=0):
note_type = "视频"
else:
note_type = "图文"
# 文章链接
note_link = section.ele('tag:a', timeout=0).link
# 标题
footer= section.ele(".footer")
title = footer.ele('.title', timeout=0).text
# 作者
author_wrapper = footer.ele('.author-wrapper')
# 点赞
like = author_wrapper.ele('.count').text
notes.append([note_type,like])
# 写入数据,r为全局变量
r.add_data(notes)
5. 向下滑动页面刷新数据
为了防止被检测到,每次下滑页面设置一个1秒至2秒之前的随机睡眠时间。使用DrissionPage库scroll.to_bottom()操作页面方法,将页面滑到底部,小红书会刷新出新的数据
def page_scroll_down():
print(f"********下滑页面********")
page.scroll.to_bottom()
# 生成一个1-2秒随机时间
random_time = random.uniform(1, 2)
# 暂停
time.sleep(random_time)
6. 循环调用采集函数和翻页函数
在crawler(times)函数中,调用get_info()函数自动提取页面数据,调用page_scroll_down()函数自动下滑页面,程序会跟踪笔记总数,计算出向下滑动页面次数,可以自动刷新数据,提取数据。
def crawler(times):
global i
for i in tqdm(range(1, times + 1)):
get_info()
page_scroll_down()
计算向下滑动页面次数的方法如下
#note_num是笔记数量
note_num=630
#times是计算得到的翻页次数,笔记数量除以20,调整系数,再向上取整
times= math.ceil(note_num/20*1.1)
printf(f"需要执行翻页次数为: {times}")
7. 保存数据
继续使用DataReCorder库来记录数据到文件,这个库使用方便,代码简洁,用起来很可靠,省心,非常适合爬虫使用
# 获取当前时间
current_time = time.localtime()
# 格式化当前时间
formatted_time = time.strftime("%Y-%m-%d %H%M%S", current_time)
# 初始化文件
init_file_path = f'小红书作者主页所有笔记-{formatted_time}.xlsx'
r = Recorder(path=init_file_path, cache_size=100)
#记录数据到缓存
r.add_data(notes)
8. 处理excel数据去重,排序
定义一个re_save_excel()函数,负责处理excel表格数据去重,排序,计算总数,再将总数信息加到文件命中。
使用pandas库,读取初始化的excel文件,对笔记数据去重处理,然后根据笔记的点赞数降序排列。再加上作者名和笔记数量,给excel重新命名
最后,再给excel表重新调整表格列宽,方便查看数据。
def re_save_excel(file_path):
# 读取excel文件
df = pd.read_excel(file_path)
print(f"总计向下翻页{times}次,获取{df.shape[0]}条笔记(含重复获取)。")
# 将点赞数转换为整数
df['点赞数'] = df['点赞数'].apply(convert_likes).astype(int)
# 删除重复行
df = df.drop_duplicates()
# 按点赞 降序排序
df = df.sort_values(by='点赞数', ascending=False)
# 文件路径
final_file_path = f"小红书作者主页所有笔记-{author}-{df.shape[0]}条.xlsx"
df.to_excel(final_file_path, index=False)
print(f"总计向下翻页{times}次,笔记去重后剩余{df.shape[0]}条,保存到文件:{final_file_path}。")
print(f"数据已保存到:{final_file_path}")
同时为了更好处理点赞数带有“万”的数据,因此需要对点赞数进行转换。
# 定义转换点赞数的函数
def convert_likes(likes):
# 移除'+'字符
likes = likes.replace('+', '')
# 检查是否包含'万'或'千'单位,并进行相应的转换
if '万' in likes:
return int(likes.replace('万', '')) * 10000
elif '千' in likes:
return int(likes.replace('千', '')) * 1000
else:
return int(likes)
9. 删除初始excel文件
由于已经得到一个最终的excel文件,这个文件是去重,排序的,最终效过很方便查看,因此可以删除初始的excel文件
def delete_file(file_path):
# 检查文件是否存在
if os.path.exists(file_path):
# 删除文件
os.remove(file_path)
print(f"已删除初始化excel文件:{file_path}")
else:
print(f"文件不存在:{file_path} ")
三. 全部代码
最后通过指定author_url和note_num就可以爬取指定作者的笔记了。
# 1、第1次运行需要登录,需要执行sign_in()步骤。第2次之后不用登录,可以注释掉sign_in()步骤。
# sign_in()
# 2、设置主页地址url
author_url = "https://www.xiaohongshu.com/user/profile/64c38af4000000000e026b43"
# 3、设置向下翻页爬取次数
# 根据小红书作者主页“当前发布笔记数”计算浏览器下滑次数。
# “当前发布笔记数” 获取方法参考https://www.sohu.com/a/473958839_99956253
# note_num是笔记数量
note_num = 62
# times是计算得到的翻页次数,笔记数量除以20,调整系数,再向上取整
times = math.ceil(note_num / 20 * 1.1)
print(f"需要执行翻页次数为:{times}")
# 4、设置要保存的文件名file_path
# 获取当前时间
current_time = time.localtime()
# 格式化当前时间
formatted_time = time.strftime("%Y-%m-%d %H%M%S", current_time)
# 初始化文件
init_file_path = f'小红书作者主页所有笔记-{formatted_time}.xlsx'
r = Recorder(path=init_file_path, cache_size=100)
# 下面不用改,程序自动执行
# 打开主页
open(author_url)
# 根据设置的次数,开始爬取数据
crawler(times)
# 避免数据丢失,爬虫结束时强制保存excel文件
r.record()
# 数据去重、排序,另存为新文件
re_save_excel(init_file_path)