# 基于selenium的小红书文章图片无水印爬取 **Repository Path**: knighthood2001/xhs_img_get ## Basic Information - **Project Name**: 基于selenium的小红书文章图片无水印爬取 - **Description**: 小红书文章图片无水印爬取 - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2024-04-10 - **Last Updated**: 2024-04-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 比如下面的的小红书链接 [100篇阅读理解刷爆大纲5500词|2001年Text3 - 小红书](https://www.xiaohongshu.com/explore/66074a84000000001a015777) 我需要将其中的图片下载下来,并且还是无水印的。 # 前言 右键检查,可以发现图片一般有专门的网址,并且点击进去后是无水印的。 ![img.png](readme_img/img.png) 你可以自己多研究一下 然后右键,`查看网页源代码`,可以发现图片链接都在这个地方出现。 ![img_1.png](readme_img/img_1.png) 因此你可以通过正则表达式进行图片链接的提取。 下面这张图片中的代码就是将图片链接保存为本地图片。这也是我之前讲过的内容,相对于这些都是可以即插即用的模板。 ![img_2.png](readme_img/img_2.png) 因此实现爬取小红书指定文章的图片的一般步骤就是: `获取网页源代码`->`使用正则表达式筛选出图片链接`->`将图片链接的内容保存为本地图片` # 项目准备 ## 针对xhs的反爬 由于小红书反爬比较恶心,我这里采用的是selenium操作已经打开的浏览器。这个好处就是不需要登录(没有很好措施的话,很容易扫码登录也失败,再加上笔者好久没有深入研究cookie这方面内容了,很多东西忘了) 如果这方面不太会的,可以看看我下面这篇文章,或者你们使用保存cookie的方法进行登录。 [最新:Selenium操作已经打开的Chrome(免登录)](https://blog.csdn.net/knighthood2001/article/details/136549809) ## 简单例子 比如你已经打开了一个链接 ![img_3.png](readme_img/img_3.png) ```python from selenium import webdriver from selenium.webdriver.chrome.options import Options # TODO 实现免登录爬虫 options = Options() options.add_experimental_option("debuggerAddress", "127.0.0.1:9527") driver = webdriver.Chrome(options=options) # 打印网页title print(driver.current_url) print(driver.title) ``` 使用上面的方法,你用selenium,就不需要弹出登录让你登录(有时候爬虫最难的就是登录问题) 运行结果如下,是不是比较轻松。 ![img_4.png](readme_img/img_4.png) ## 编写其他代码 解决了登录问题,后面的就比较好解决了。 但是这次代码,相对于我上面那个即插即用的模板来说,不太一样。因为我上面的那个模板,每次保存图片,由于时间戳一样,就会导致即使有多个图片链接,但是最后都是以一个时间戳命名,最后就保存为1张照片(被反复覆盖了)。 因此我需要进行代码的重构,我的想法是把for循环遍历放到保存图片中,原先保存图片是传入的一个链接,我这时候传入的是一个列表,然后通过for循环进行图片的保存。 并且图片的上一级目录还有一个时间戳,可以帮助你排序,分辨下载先后顺序。 ![img_5.png](readme_img/img_5.png) 这一部分的代码,和之前版本来说,还是有较大区别的。 ```python #TODO 实现输入一个图片url列表,将其中的图片保存到目录中,并按照1-nums排序,这样可以保证下载下来的图片顺序不乱。 #TODO 比如输入[图片链接1,图片链接2,图片链接3]和"image",最后就会生成image/时间戳的目录,然后在里面保存1.png,2.png,3.png def image_save_batch(image_urls, save_dir): time_path = get_time() path = os.path.join(save_dir, str(time_path)) if not os.path.exists(path): os.makedirs(path) for i, url in enumerate(image_urls): # 发送 GET 请求获取图片数据 response = requests.get(url) # 确保请求成功 if response.status_code == 200: # 生成图片文件名 image_name = f"{time_path}/{i}.png" # 拼接图片保存路径 save_path = os.path.join(save_dir, image_name) # 将图片数据写入文件 with open(save_path, 'wb') as f: f.write(response.content) print(f'图片{i+1}已保存为: {save_path}') else: print(f'下载图片{i+1}失败,状态码: {response.status_code}') def get_img_url_list(content): # 使用正则表达式提取网址 url_pattern = re.compile(r'') matches = url_pattern.findall(content) if matches: # 去重+顺序 # unique_matches = list(set(matches)) # 会乱序 unique_matches = list(Counter(matches)) nums = len(unique_matches) print(f"图片数量:{nums}, 图片去重数量:{len(matches)-nums}") print(unique_matches) # # 打印每个网址 # for i in range(nums): # print(unique_matches[i]) # image_save(unique_matches[i], "images") image_save_batch(unique_matches, "images") else: print("No URL found.") ``` 需要注意的一点是,matches中的图片链接有时候会有重复,因此需要去重操作,但是set函数的去重操作是无序的,会导致最终图片保存顺序为乱序。 因此我这里采用调用collections的Counter,解决去重+乱序的问题。 # 最后 这个项目也算是搭积木吧,但是我觉得应该挺多人需要。因为有时候一张一张手动保存有水印的小红书图片,慢且有水印。 当然,代码中有一些细节,我并没有讲到,因为我发现,**写文档真的太折磨人了**。