Python-抓取小红书文章的心路历程

2023-11-20

在这之前从未了解过小红书,然后习惯性地百度了一下。发现是这样的

研究发现,这玩意没有pc端的接口,也就是说没办法直接从pc端抓取数据。好吧,放弃。不过pc端还是有用处的

打开社区精选,点开几个推送详情页看了看,发现所有的文章url都是https://www.xiaohongshu.com/discovery/item/ + 文章绑定的一串字符,这个很关键。然后pc端不行,就只能从手机端想办法,下载了小红书的app,又看了一下微信的小红书小程序,试着用fidder抓包,然后发现小程序的更好抓,还是得借马爸爸的门啊!

采集路径有了,第一个问题顺利解决,然后开始fidder抓包。

json文件找到了。观察一下json文件里的参数,会发现。跟每一个title的同级都有一个绑定的id。看起来有点眼熟啊,是不是跟刚才社区精选看到的url的id很像?于是复制一个到pc端测试,果然

好了,第二个问题解决,现在就要思考如何拿到json文件的数据。然后批量访问

试了一下添加cookie,ua,referer。结果失败

然后一股脑把所有参数都带上了去访问,结果成功

没挨个测试反正能成功就行,有兴趣的朋友可以挨个测试,看看哪些是必要参数。

交个底,大部分参数都是固定的,只有请求头里的keyword跟X-Sign是变动的,需要手动获取。自此大部分问题解决

还有个最操蛋的问题,就是小红书对访问频率太敏感,正常的套路去爬基本上两三篇文章最多就给你弹验证,然后程序就挂了。试过添加随机请求头,不过不管用。唯一的两个办法是使用代理,这样的话基本上你要爬多少篇文章就得准备多少代理,免费ip不好用,又没钱买付费代理,这条路我不走了,有条件的朋友可以去试试,我是用的第二个方法,selenium+time降低访问速度。反正不要求效率,让程序慢慢跑就完事了,省钱省事不香吗?哈哈哈

好了,直接贴代码。

import time
import pymysql
import requests
import re
import urllib3
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
import json


class Fuck_xhs(object):
    def __init__(self):
        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
        self.conn = pymysql.connect(xxxxx, 自己写)
        self.cursor = self.conn.cursor()
        self.url = 'https://www.xiaohongshu.com/fe_api/burdock/weixin/v2/search/notes?'
        self.key_dict = {
            '1': 'Xd44b23783ad8f18c2e41c045a0cda867',
            '2': 'Xe8b3f71b7585c080e9ca55e7d1b034e0',
            '3': 'X2351ff0514bb05145e8171975fe1d96d',
            '4': 'X2422fd5312cf50b12c722e1d63b2f9aa',
            '5': 'X44d5cf63fb658c609be10404b77291d5',
        }
        with open('小红书url.txt', 'r', encoding='utf-8')as f:
            r = f.read().replace('\ufeff', '')
            self.old_list = r.split('\n')
            print(self.old_list)
        options = Options()
        options.add_argument('--headless')
        self.chrome = Chrome(options=options)

    def get_detail_url(self):
        for key, value in self.key_dict.items():
            headers = {
                'Host': 'www.xiaohongshu.com',
                'Connection': 'keep-alive',
                'Authorization': 'wxmp.4aad8f54-3422-4d76-b440-5f4cce8d0907',
                'Device-Fingerprint': 'WHJMrwNw1k/Ff2NfArpikjizTJkAdQe2Y1P0AQTa74gJcSlBSWoMjTXYq+VUDRGsE9VCMBXrfD5W9YT2GqNMbnISuxoWerClbdCW1tldyDzmauSxIJm5Txg==1487582755342',
                'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat',
                'X-Sign': value,
                'content-type': 'application/json',
                'Referer': 'https://servicewechat.com/wxffc08ac7df482a27/378/page-frame.html',
                'Accept-Encoding': 'gzip, deflate, br',
            }
            params = {
                'keyword': '揭阳周边游',
                'sortBy': 'general',
                'page': key,
                'pageSize': '20',
                'needGifCover': 'true',
            }
            res = requests.get(self.url, headers=headers, params=params, verify=False).text
            print(res)
            res_dict = json.loads(res)
            notes = res_dict['data']['notes']
            for note in notes:
                id = note['id']
                print(id)
                self.detail_url = 'https://www.xiaohongshu.com/discovery/item/' + id
                print(self.detail_url)
                if self.detail_url in self.old_list:
                    print('链接已存在。')
                    continue
                else:
                    with open('小红书url.txt', 'a', encoding='utf-8')as w:
                        w.write('\n')
                        w.write(self.detail_url)
                    self.get_detail()
                    continue
        self.conn.close()

    def get_detail(self):
        self.chrome.get(self.detail_url)
        time.sleep(1.5)
        try:
            video = self.chrome.find_element_by_xpath('//div[@class="videoframe"]')
            if video:
                return None
        except:
            pass
        self.content_pic = '<ul>' + str(self.chrome.find_element_by_class_name("slide").get_attribute('innerHTML')) + '</ul>'
        print(self.content_pic)
        urls = re.findall(r'style="background-image.*?;"', self.content_pic, re.DOTALL)
        for ur in urls:
            print('ur的值为%s' % ur)
            u = ''.join(re.findall(r'url\((.*?)\)', ur))
            url = 'http:' + u.replace('&quot;', '').replace('&quot', '').replace('https:', '').replace('http:',
                                                                                                       '') + '.jpg'
            print(url)
            self.content_pic = str(self.content_pic).replace(ur, 'src=' + '"' + url + '"').replace('span', 'img').replace(
                '<i data',
                '<img data').replace(
                '</i>', '</img>')
        print(self.content_pic)
        self.content = self.chrome.find_element_by_class_name('content').get_attribute('innerHTML')
        try:
            self.author = self.chrome.find_element_by_class_name('name-detail').text
            print(self.author)
        except:
            self.author = ' '
        try:
            self.title = self.chrome.find_element_by_class_name('title').text
            if not self.title:
                self.title = self.chrome.find_element_by_class_name('as-p').text
            print(self.title)
        except:
            self.title = ' '
        try:
            span = self.chrome.find_elements_by_xpath('//div[@class="operation-block"]/span')
            self.like = span[0].find_element_by_xpath('./span').text
            self.comment = span[1].find_element_by_xpath('./span').text
            self.star = span[2].find_element_by_xpath('./span').text
            print(self.like, self.comment, self.star)
        except:
            self.like = ' '
            self.comment = ' '
            self.star = ' '
        try:
            self.b_q = self.chrome.find_elements_by_xpath('//div[@class="keywords"]/a[@class="keyword category"]')
            print(self.b_q)
            a_l = []
            for bq in self.b_q:
                a = bq.text
                a_l.append(a)
            self.a_l = str(a_l).replace('[', '').replace(']', '').replace("'", '').replace(',', ',')
            print(self.a_l)
        except:
            self.a_l = ' '
        try:
            self.pub_time = str(self.chrome.find_element_by_xpath('//div[@class="publish-date"]/span').text).replace(
                '发布于', '')
            print(self.pub_time)
        except:
            self.pub_time = ' '
        try:
            self.author_img = self.chrome.find_element_by_xpath('//div[@class="left-img"]/img').get_attribute('src')
            print(self.author_img)
        except:
            self.author_img = ' '
        time.sleep(5)
        self.create_time = time.strftime("%Y-%m-%d %H:%M:%S")
        print(self.create_time)
        self.is_import = '0'
        time.sleep(3)
        self.deposit_mysql()

    def deposit_mysql(self):
        sql = "insert into xhs_article(id, author, author_img, title, text_img, content, like_count, review_count, collect_count, org_url, publish_time, keyword_tag, create_time, is_import, import_time) values(null,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,null)"
        self.cursor.execute(sql, (
            str(self.author), str(self.author_img), str(self.title), str(self.content_pic), str(self.content),
            str(self.like), str(self.comment),
            str(self.star), str(self.detail_url), str(self.pub_time), str(self.a_l), str(self.create_time),
            str(self.is_import)))
        self.conn.commit()
        return None


if __name__ == '__main__':
    xhs = Fuck_xhs()
    xhs.get_detail_url()

入库

代码2020/08/14下午刚做了优化,测试可用,分享。

2020-10-12记 如果报错,先考虑参数过期情况,毕竟都两月了,自行更换最新的cookie再尝试!

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

Python-抓取小红书文章的心路历程 的相关文章

随机推荐

  • 推荐一篇详细的Nginx 配置清单

    Nginx 是一个高性能的 HTTP 和反向代理 web 服务器 同时也提供了 IMAP POP3 SMTP 服务 其因丰富的功能集 稳定性 示例配置文件和低系统资源的消耗受到了开发者的欢迎 本文 我们总结了一些常用的 Nginx 配置代码
  • Obsidian 入门使用手册

    文章目录 一 Obsidian 入门 1 1 什么是 Obsidian 1 2 安装 Obsidian 二 Obsidian 配置 2 1 创建第一个笔记 2 2 设置界面语言使用中文 2 3 主题 三 小结 一 Obsidian 入门 1
  • VScode配置文档

    vscode配置 常用插件 View In Browser 预览页面 ctrl F1 vscode icons 侧栏的图标 对于一个有视觉强迫症的人是必须要的 HTML Snippets 支持HTML5的标签提示 JS CSS HTML F
  • 泰凌微 IDE使用心得

    Telink IDE 1 5 这可能是我用过最难用的IDE 没有之一
  • ARL资产侦察灯塔系统搭建及使用

    ARL资产侦察灯塔系统搭建及使用 ARL Asset Reconnaissance Lighthouse 资产侦查灯塔旨在快速发现并整理企业外网资产并为资产构建基础数据库 无需登录凭证或特殊访问即可主动发现并识别资产 让甲方安全团队或者渗透
  • 微机原理:汽车速度控制系统的设计与实现

    一 设计内容 汽车速度控制系统 在自行设计接口板的按键转换汽车的挡位 发光二极管显示挡位 数码管显示汽车的速度 加速控制 拨动对应的档位再拨动加速开关 数码管显示速度递增至99 加速要与档位匹配 若不匹配则 加速失效 减速控制 拨动减速开关
  • 学习DOM

    DOM的概述 DOM document object model 文档对象模型 顾名思义他就是用于操作对应的文档的 也就是操作你写的html文档 DOM是一个遵从文档流的语句 所以他是同步机制 DOM的分类 document dom操作中最
  • mybatis异常:nested exception is org.apache.ibatis.builder.BuilderException

    这里我使用的是Mybatis plus然后报的异常 接口如下 xml如下 本来以为一切正常却忽略了接收参数的实体参数名字 也就是接受参数名和xml当中的参数名不一致导致异常 其次是接参里面并没有这几个参数 以至于他也会报这种错误的
  • Python GUI案例之看图猜成语开发(第二篇)

    Python GUI案例之看图猜成语 第二篇 前言 看图猜成语小程序开发 第二篇 游戏选择模式页面 游戏训练模式页面 Python GUI案例之看图猜成语开发 第一篇 Python GUI案例之看图猜成语开发 第三篇 Python GUI案
  • QString转const char*

    QString str hello world 转成const char const char arr str toStdString c str const char arr str toLatin1 constData toUtf8 转
  • [从零开始学习FPGA编程-28]:进阶篇 - 基本组合电路-奇偶校验生成器(Verilog语言版本)

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 第1章 奇偶校验生成器 1 1 什么是奇校验 1 2 Verilog语言描述
  • devtools安装_R语言入门之R包的安装

    R语言是一个强大的数据分析工具 其强大之处在于有各种各样的R包帮助其实现各种各样的功能 通常来说 R包的安装主要有四种方法 包括 1 从R语言官网上直接下载相关R包并安装 2 从Bioconductor上下载R包并安装 3 从Github上
  • 华为OD机试真题2022(JavaScript)

    华为OD机试真题题库已换 华为OD机试真题2023 JavaScript 本栏有100 道算法题 并提供正确解法 JavaScript 和解题思路 保证都是华为机试真题 非练习题 大概率会考到原题 大家有什么问题可以留言探讨和交流 华为机试
  • Tomcat 系统架构与设计模式之工作原理篇

    本文以 Tomcat 5 为基础 也兼顾最新的 Tomcat 6 和 Tomcat 4 Tomcat 的基本设计思路和架构是具有一定连续性的 Tomcat 总体结构 Tomcat 的结构很复杂 但是 Tomcat 也非常的模块化 找到了 T
  • MySQL 5.5.62下载、安装与卸载详细步骤

    目录 下载地址 安装过程 测试安装 卸载过程 下载地址 安装包我传到了CSDN 下载不需要积分 是从官网下载上传的 可以放心使用 CSDN下载地址 mysql 5 5 62 winx64 msi 官网下载地址 地址 安装过程 双击安装包打开
  • 计算机网络笔记Part2 物理层(Physical Layer)

    计算机网络笔记Part2 物理层 Physical Layer 一 物理层基本概念 二 数据通信 1 一个数据通信例子 2 相关术语 3 三种通讯方式 4 两种数据传输方式 5 码元 Symbol 波特 Baud 速率 带宽 Band Wi
  • 创建自定义的archetype(项目模板)

    一 archetype简介 Archetype是一个Maven项目的模板工具包 它定义了一类项目的基本架构 Archetype为开发人员提供了创建Maven项目的模板 同时它也可以根据已有的Maven项目生成参数化的模板 通过archety
  • G1垃圾回收器简介及回收过程

    一 什么是G1 同CMS一样 G1也是关注停顿时间 不过它是可控的 它被设计用来取代CMS 因为它是空间整理所以没有CMS那么严重的空间碎片问题 同时提供可控的停顿时间 特性 1 G1不同于之前的那些垃圾收集器分为连续的年轻代 老年代和永久
  • leetcode-跳跃游戏系列

    1 跳跃游戏 leetcode 55 跳跃游戏 1 问题描述 给定一个非负整数数组 n u m s nums nums 你最初位于数组的 第一个下标 数组中的每个元素代表你在该位置可以跳跃的最大长度 判断你是否能够到达最后一个下标 示例 1
  • Python-抓取小红书文章的心路历程

    在这之前从未了解过小红书 然后习惯性地百度了一下 发现是这样的 研究发现 这玩意没有pc端的接口 也就是说没办法直接从pc端抓取数据 好吧 放弃 不过pc端还是有用处的 打开社区精选 点开几个推送详情页看了看 发现所有的文章url都是htt