Python实现小红书app版爬虫

简介:由于数据需求的日益增大,小红书网页版已经不能满足我们日常工作的需求,为此,小编特地开发了小红书手机版算法,方便大家获取更多的数据,提升工作效率。

手机版接口主要包括:搜素,详情,话题,评论,主页,用户信息,用户收藏,用户喜欢,发现页等等。

搜索页

评论页

code:

签名获取

    def get_shield_value(self, note_id, xhs_api_url, xy_common_params, method='GET', apibody=''):
        if method == 'GET':
            if note_id:
                body = f'noteid={note_id}&param={quote(xy_common_params)}&device={self.device_id}&hmac={quote(self.hmac)}&url={quote(xhs_api_url)}&direction=48'
            else:
                body = f'param={quote(xy_common_params)}&device={self.device_id}&hmac={quote(self.hmac)}&url={quote(xhs_api_url)}&direction=48'
            response = requests.post(self.get_shield_url, data=body, headers=self.headers, timeout=5)
            return response.text.strip()
        else:
            url = f'{self.post_shield_url}?url={urllib.parse.quote(xhs_api_url)}&param={urllib.parse.quote(xy_common_params)}&direction=40&body={urllib.parse.quote(apibody)}&hmac={urllib.parse.quote(self.hmac)}&device={self.device_id}'
            headers = {
                'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
                'Content-Type': 'application/json'
            }
            response = requests.post(url, headers=headers)
            response.raise_for_status()
            shield = response.text.strip()
            return shield

headers生成

    def generate_post_headers(self, note_id, xhs_api_url, custom_headers, session_id, api='', method='GET', apibody=''):
        post_headers = copy.deepcopy(custom_headers)
        post_headers['x-legacy-sid'] = f'session.{session_id}'
        post_headers['xy-common-params'] = re.sub(r'session\.\d+', f'session.{session_id}', post_headers['xy-common-params'])
        shield = self.get_shield_value(note_id, xhs_api_url, post_headers['xy-common-params'], method, apibody)
        post_headers.update({
            'shield': shield,
        })
        logger.info(shield)
        if method == 'POST':
            post_headers['xy-direction'] = '40'
        return post_headers

请求

    def spider_search(self, keyword, page='1', page_pos='0', sort='general', note_type='不限', publish_time='不限', search_type='不限', session_id=None):
        """
        搜索
        :param keyword: 关键词
        :param sort: 排序方式 general:综合 time_descending:最新 popularity_descending:最多点赞 comment_descending:最多评论 collect_descending:最多收藏
        :param note_type: 笔记类型 不限 视频笔记 普通笔记
        :param publish_time: 发布时间 不限 一天内 一周内 半年内
        :param search_type: 搜索范围 不限 已看过 未看过
        :param session_id:
        :return:
        """
        api_url_base = "https://edith.xiaohongshu.com/api/sns/v10/search/notes"
        filters = [
            {
                'tags': [sort],
                'type': 'sort_type'
            },
            {
                'tags': [note_type],
                'type': 'filter_note_type'
            },
            {
                'tags': [publish_time],
                'type': 'filter_note_time'
            },
            {
                'tags': [search_type],
                'type': 'filter_note_range'
            }
        ]
        params = {
            "keyword": keyword,
            "filters": json.dumps(filters, ensure_ascii=False, separators=(',', ':')),
            "sort": "",
            "page": page,
            "page_size": "20",
            "source": "explore_feed",
            "search_id": "2ehsgm5x5z2etryfwa5ts",
            "session_id": "2ehsglrpf9h3h4y091csg",
            "api_extra": "",
            "page_pos": page_pos,
            "pin_note_id": "",
            "allow_rewrite": "1",
            "geo": "",
            "loaded_ad": "",
            "query_extra_info": "",
            "rec_extra_params": "",
            "preview_ad": "",
            "scene": "",
            "is_optimize": "0",
            "location_permission": "0",
            "is_out_of_china": "0",
            "device_level": "4",
            "refresh_type": "0",
            "in_map_card_exp": "0",
            "search_tab": ""
        }
        xhs_api_url = api_url_base + '?' + urllib.parse.urlencode(params)
        post_headers = self.generate_post_headers('', xhs_api_url, self.custom_headers, session_id, api=xhs_api_url)
        # logger.info(post_headers)
        response = requests.get(xhs_api_url, headers=post_headers, timeout=5)
        res_json = response.json()
        logger.info(f'请求数据: {json.dumps(res_json, ensure_ascii=False)}')
        return res_json

### 小红书评论爬取教程 #### 使用Scrapy与Selenium结合的方式抓取小红书评论 在实际开发过程中,小红书作为一个动态加载内容较多的平台,其网页中的评论部分往往由JavaScript渲染生成。因此,在使用传统的静态爬虫工具(如Requests库)时可能会遇到困难。此时,可以通过结合Scrapy和Selenium的方式来解决这一问题。 以下是具体实现方法: 1. **配置环境** 安装必要的依赖包:`scrapy`, `selenium` 和对应的浏览器驱动程序(如ChromeDriver)。安装命令如下: ```bash pip install scrapy selenium ``` 2. **设置Scrapy项目** 创建一个新的Scrapy项目并进入该项目目录。 ```bash scrapy startproject xiaohongshu cd xiaohongshu ``` 3. **修改Settings文件** 打开`settings.py`文件,进行以下配置以优化性能[^4]: ```python ROBOTSTXT_OBEY = False # 不遵循Robots协议 LOG_LEVEL = 'ERROR' # 设置日志级别为错误 USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' # 自定义User-Agent DOWNLOAD_DELAY = 1 # 下载延迟时间 ``` 4. **集成Selenium到Scrapy** 编写中间件用于启动Selenium WebDriver实例,并将其返回给Spider处理。创建一个名为`selenium_middleware.py`的文件,代码如下: ```python from selenium import webdriver from scrapy.http import HtmlResponse class SeleniumMiddleware: def __init__(self): options = webdriver.ChromeOptions() options.add_argument('--headless') # 无头模式运行 self.driver = webdriver.Chrome(options=options) def process_request(self, request, spider): self.driver.get(request.url) body = str.encode(self.driver.page_source) return HtmlResponse( url=self.driver.current_url, status=200, body=body, encoding='utf-8', request=request ) def __del__(self): self.driver.quit() # 关闭WebDriver ``` 5. **启用中间件** 修改`settings.py`文件,激活自定义的Selenium中间件: ```python DOWNLOADER_MIDDLEWARES = { 'xiaohongshu.middlewares.SeleniumMiddleware': 543, } ``` 6. **编写Spider逻辑** 在Spiders目录下新建一个Python脚本,例如命名为`comments_spider.py`,具体内容如下: ```python import scrapy class CommentsSpider(scrapy.Spider): name = 'xiaohongshu_comments' allowed_domains = ['www.xiaohongshu.com'] start_urls = [ 'https://www.xiaohongshu.com/explore', # 替换为目标URL ] def parse(self, response): comments = response.css('div.comment-content::text').getall() # 提取评论内容 for comment in comments: yield {'comment': comment.strip()} next_page = response.css('a.next-page::attr(href)').get() # 查找下一页链接 if next_page is not None: yield response.follow(next_page, callback=self.parse) ``` 7. **执行爬虫任务** 运行以下命令启动爬虫: ```bash scrapy crawl xiaohongshu_comments -o comments.json ``` 此过程利用了Selenium模拟真实用户的浏览行为,从而解决了因JavaScript动态加载而导致的数据无法直接获取的问题[^2]。 --- ### 注意事项 由于小红书可能存在反爬机制,建议适当调整请求频率以降低被封禁的风险。此外,需注意遵守目标网站的服务条款及相关法律法规。 ---
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

才华是浅浅的耐心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值