From dc9a5cdb4d0cb7b0668744e3c67ca8013976d102 Mon Sep 17 00:00:00 2001 From: ReaJason Date: Tue, 27 Feb 2024 14:41:26 +0000 Subject: [PATCH] deploy: 94bd0318825ed56eb2b9802a3522702fe6c7e18c --- .buildinfo | 2 +- _modules/index.html | 2 +- _modules/xhs/core.html | 185 +++++++++++++++++++++++++------ _sources/index.rst.txt | 1 - _static/documentation_options.js | 2 +- basic.html | 2 +- crawl.html | 2 +- creator.html | 2 +- genindex.html | 22 +++- index.html | 2 +- objects.inv | Bin 855 -> 928 bytes search.html | 2 +- searchindex.js | 2 +- source/xhs.html | 62 ++++++++++- 14 files changed, 241 insertions(+), 47 deletions(-) diff --git a/.buildinfo b/.buildinfo index 5346a6a..042eb56 100644 --- a/.buildinfo +++ b/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 579085b1ee81349f69de64b6e3b2e113 +config: 496c554a013a2b9a9fa47504ea006d82 tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/_modules/index.html b/_modules/index.html index 4136ca3..7297fbf 100644 --- a/_modules/index.html +++ b/_modules/index.html @@ -5,7 +5,7 @@ - 概览:模块代码 — xhs 0.2.7 文档 + 概览:模块代码 — xhs 0.2.10 文档 diff --git a/_modules/xhs/core.html b/_modules/xhs/core.html index 6ebcaf6..641dca1 100644 --- a/_modules/xhs/core.html +++ b/_modules/xhs/core.html @@ -5,7 +5,7 @@ - xhs.core — xhs 0.2.7 文档 + xhs.core — xhs 0.2.10 文档 @@ -36,24 +36,19 @@

xhs.core 源代码

 import os
 import re
 import time
+from datetime import datetime
 from enum import Enum
 from typing import NamedTuple
-from datetime import datetime
 
 import requests
+from lxml import etree
 
-from xhs.exception import DataFetchError, IPBlockError, SignError, ErrorEnum
+from xhs.exception import DataFetchError, ErrorEnum, IPBlockError, SignError
 
-from .help import (
-    cookie_jar_to_cookie_str,
-    download_file,
-    get_imgs_url_from_note,
-    get_search_id,
-    get_valid_path_name,
-    get_video_url_from_note,
-    sign,
-    update_session_cookies_from_cookie,
-)
+from .help import (cookie_jar_to_cookie_str, download_file,
+                   get_imgs_url_from_note, get_search_id, get_valid_path_name,
+                   get_video_url_from_note, parse_xml, sign,
+                   update_session_cookies_from_cookie)
 
 
 
[文档]class FeedType(Enum): @@ -136,8 +131,9 @@

xhs.core 源代码

         self.proxies = proxies
         self.__session: requests.Session = requests.session()
         self.timeout = timeout
-        self.sign = sign
+        self.external_sign = sign
         self._host = "https://edith.xiaohongshu.com"
+        self._creator_host = "https://creator.xiaohongshu.com"
         self.home = "https://www.xiaohongshu.com"
         user_agent = user_agent or (
             "Mozilla/5.0 "
@@ -184,7 +180,7 @@ 

xhs.core 源代码

             self.__session.headers.update({"x-s-common": signs["x-s-common"]})
         else:
             self.__session.headers.update(
-                self.sign(
+                self.external_sign(
                     url,
                     data,
                     a1=self.cookie_dict.get("a1"),
@@ -198,7 +194,10 @@ 

xhs.core 源代码

         )
         if not len(response.text):
             return response
-        data = response.json()
+        try:
+            data = response.json()
+        except json.decoder.JSONDecodeError:
+            return response
         if data.get("success"):
             return data.get("data", data.get("success"))
         elif data["code"] == ErrorEnum.IP_BLOCK.value.code:
@@ -213,13 +212,15 @@ 

xhs.core 源代码

         if isinstance(params, dict):
             final_uri = f"{uri}?" f"{'&'.join([f'{k}={v}' for k, v in params.items()])}"
         self._pre_headers(final_uri, is_creator=is_creator)
-        return self.request(method="GET", url=f"{self._host}{final_uri}", **kwargs)
+ return self.request(method="GET", url=f"{self._creator_host if is_creator else self._host}{final_uri}", + **kwargs)
[文档] def post(self, uri: str, data: dict, is_creator: bool = False, **kwargs): self._pre_headers(uri, data, is_creator=is_creator) json_str = json.dumps(data, separators=(",", ":"), ensure_ascii=False) return self.request( - method="POST", url=f"{self._host}{uri}", data=json_str.encode("utf-8"), **kwargs + method="POST", url=f"{self._creator_host if is_creator else self._host}{uri}", data=json_str.encode(), + **kwargs )
[文档] def get_note_by_id(self, note_id: str): @@ -357,6 +358,20 @@

xhs.core 源代码

         uri = "/api/sns/web/v2/user/me"
         return self.get(uri)
+
[文档] def get_user_by_keyword(self, keyword: str, + page: int = 1, + page_size: int = 20, ): + uri = "/api/sns/web/v1/search/usersearch" + data = { + "search_user_request": { + "keyword": keyword, "search_id": get_search_id(), + "page": page, "page_size": page_size, + "biz_type": "web_search_user", + "request_id": f"{int(round(time.time()))}-{int(round(time.time() * 1000))}", + } + } + return self.post(uri, data)
+
[文档] def get_user_info(self, user_id: str): """ :param user_id: user_id you want fetch @@ -469,8 +484,7 @@

xhs.core 源代码

                 try:
                     note = self.get_note_by_id(note_id)
                 except DataFetchError as e:
-                    if (ErrorEnum.NOTE_ABNORMAL.value.msg in e.__repr__()
-                            or ErrorEnum.NOTE_SECRETE_FAULT.value.msg in e.__repr__()):
+                    if ErrorEnum.NOTE_ABNORMAL.value.msg in e.__repr__() or ErrorEnum.NOTE_SECRETE_FAULT.value.msg in e.__repr__():
                         continue
                     else:
                         raise
@@ -553,10 +567,8 @@ 

xhs.core 源代码

                 cur_sub_comment_count = int(comment["sub_comment_count"])
                 cur_sub_comments = comment["sub_comments"]
                 result.extend(cur_sub_comments)
-                sub_comments_has_more = (
-                        comment["sub_comment_has_more"]
-                        and len(cur_sub_comments) < cur_sub_comment_count
-                )
+                sub_comments_has_more = comment["sub_comment_has_more"] and len(
+                    cur_sub_comments) < cur_sub_comment_count
                 sub_comment_cursor = comment["sub_comment_cursor"]
                 while sub_comments_has_more:
                     page_num = 30
@@ -564,9 +576,7 @@ 

xhs.core 源代码

                         note_id, comment["id"], num=page_num, cursor=sub_comment_cursor
                     )
                     sub_comments = sub_comments_res["comments"]
-                    sub_comments_has_more = (
-                            sub_comments_res["has_more"] and len(sub_comments) == page_num
-                    )
+                    sub_comments_has_more = sub_comments_res["has_more"] and len(sub_comments) == page_num
                     sub_comment_cursor = sub_comments_res["cursor"]
                     result.extend(sub_comments)
                     time.sleep(crawl_interval)
@@ -660,8 +670,8 @@ 

xhs.core 源代码

         return self.post(uri, data={})
[文档] def send_code(self, phone: str, zone: str = 86): - uri = "/api/sns/web/v1/login/send_code" - params = {"phone": phone, "zone": zone} + uri = "/api/sns/web/v2/login/send_code" + params = {"phone": phone, "zone": zone, "type": "login"} return self.get(uri, params)
[文档] def check_code(self, phone: str, code: str, zone: str = 86): @@ -688,6 +698,53 @@

xhs.core 源代码

         uri = "/api/im/redmoji/detail"
         return self.get(uri)["emoji"]["tabs"][0]["collection"]
+
[文档] def get_mention_notifications(self, num: int = 20, cursor: str = ""): + uri = "/api/sns/web/v1/you/mentions" + params = {"num": num, "cursor": cursor} + return self.get(uri, params)
+ +
[文档] def get_like_notifications(self, num: int = 20, cursor: str = ""): + uri = "/api/sns/web/v1/you/likes" + params = {"num": num, "cursor": cursor} + return self.get(uri, params)
+ +
[文档] def get_follow_notifications(self, num: int = 20, cursor: str = ""): + uri = "/api/sns/web/v1/you/connections" + params = {"num": num, "cursor": cursor} + return self.get(uri, params)
+ +
[文档] def get_notes_summary(self): + uri = "/api/galaxy/creator/data/note_detail_new" + headers = { + "Referer": "https://creator.xiaohongshu.com/creator/notes?source=official" + } + return self.get(uri, headers=headers, is_creator=True)
+ +
[文档] def get_notes_statistics(self, page: int = 1, page_size: int = 48, sort_by="time", note_type=0, time=30, + is_recent=True): + """ + :param page: page num default is 1 + :param page_size: page size, 12 or 24 or 36 or 48 + :param sort_by: time default + :param note_type: 0 is all, 1 is images, 2 is video + :param time: fetch date + :param is_recent: default is false, when time is 7, this should be false + :return: + """ + uri = "/api/galaxy/creator/data/note_stats/new" + params = { + "page": page, + "page_size": page_size, + "sort_by": sort_by, + "note_type": note_type, + "time": time, + "is_recent": is_recent + } + headers = { + "Referer": "https://creator.xiaohongshu.com/creator/notes?source=official" + } + return self.get(uri, params, is_creator=True, headers=headers)
+
[文档] def get_upload_files_permit(self, file_type: str, count: int = 1) -> tuple: """获取文件上传的 id @@ -703,11 +760,65 @@

xhs.core 源代码

             "version": "1",
             "source": "web",
         }
-        temp_permit = self.get(uri, params)["uploadTempPermits"][0]
+        res = self.get(uri, params)
+        temp_permit = res["uploadTempPermits"][0]
         file_id = temp_permit["fileIds"][0]
         token = temp_permit["token"]
         return file_id, token
+
[文档] def get_upload_id(self, file_id, token): + headers = {"X-Cos-Security-Token": token} + res = self.request("POST", f"https://ros-upload.xiaohongshu.com/{file_id}?uploads", headers=headers) + return parse_xml(res.text)["UploadId"]
+ +
[文档] def create_complete_multipart_upload(self, file_id: str, token: str, upload_id: str, parts: list): + root = etree.Element("CompleteMultipartUpload") + for part in parts: + part_elem = etree.Element("Part") + part_number_elem = etree.Element("PartNumber") + part_number_elem.text = str(part['PartNumber']) + part_elem.append(part_number_elem) + + etag_elem = etree.Element("ETag") + etag_elem.text = part['ETag'].replace('"', '&quot;') + part_elem.append(etag_elem) + root.append(part_elem) + xml_string = ("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + etree.tostring(root, + encoding='UTF-8').decode( + "UTF-8").replace("&amp;", "&")) + print(xml_string) + print(file_id) + print(token) + print(upload_id) + headers = {"X-Cos-Security-Token": token, "Content-Type": "application/xml"} + url = f"https://ros-upload.xiaohongshu.com/{file_id}?uploadId={upload_id}" + return self.request("POST", url, data=xml_string, headers=headers)
+ +
[文档] def upload_file_with_slice(self, file_id: str, token: str, + file_path: str): + headers = {"X-Cos-Security-Token": token} + url = "https://ros-upload.xiaohongshu.com/" + file_id + upload_id = self.get_upload_id(file_id, token) + parts = [] + part_num = 1 + with open(file_path, "rb") as f: + # read with 5M each time to upload + while True: + data = f.read(1024 * 1024 * 5) + if not data: + break + params = { + "partNumber": part_num, + "uploadId": upload_id + } + res = self.request("PUT", url, params=params, data=data, headers=headers) + parts.append({ + "PartNumber": part_num, + "ETag": res.headers["Etag"] + }) + part_num += 1 + return self.create_complete_multipart_upload(file_id, token, upload_id, parts)
+
[文档] def upload_file( self, file_id: str, @@ -723,10 +834,16 @@

xhs.core 源代码

         :param content_type:  【"video/mp4","image/jpeg","image/png"】
         :return:
         """
+        # 5M 为一个 part
+        max_file_size = 5 * 1024 * 1024
         url = "https://ros-upload.xiaohongshu.com/" + file_id
-        headers = {"X-Cos-Security-Token": token, "Content-Type": content_type}
-        with open(file_path, "rb") as f:
-            return self.request("PUT", url, data=f, headers=headers)
+ if os.path.getsize(file_path) > max_file_size and content_type == "video/mp4": + raise Exception("video too large, < 5M") + # return self.upload_file_with_slice(file_id, token, file_path) + else: + headers = {"X-Cos-Security-Token": token, "Content-Type": content_type} + with open(file_path, "rb") as f: + return self.request("PUT", url, data=f, headers=headers)
[文档] def get_suggest_topic(self, keyword=""): """通过关键词获取话题信息,发布笔记用 @@ -796,7 +913,7 @@

xhs.core 源代码

             "Referer": "https://creator.xiaohongshu.com/"
         }
         print(data)
-        return self.post(uri, data, headers=headers)
+ return self.post(uri, data, headers=headers, is_creator=True)
[文档] def create_image_note( self, diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt index bc9eb79..94d0c69 100644 --- a/_sources/index.rst.txt +++ b/_sources/index.rst.txt @@ -33,4 +33,3 @@ basic crawl creator - diff --git a/_static/documentation_options.js b/_static/documentation_options.js index 18b901e..08d37ca 100644 --- a/_static/documentation_options.js +++ b/_static/documentation_options.js @@ -1,6 +1,6 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '0.2.7', + VERSION: '0.2.10', LANGUAGE: 'zh_CN', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/basic.html b/basic.html index 4ed1a42..f6948b5 100644 --- a/basic.html +++ b/basic.html @@ -5,7 +5,7 @@ - 快速入门 — xhs 0.2.7 文档 + 快速入门 — xhs 0.2.10 文档 diff --git a/crawl.html b/crawl.html index e99eb50..9139c1e 100644 --- a/crawl.html +++ b/crawl.html @@ -5,7 +5,7 @@ - 主页爬取 — xhs 0.2.7 文档 + 主页爬取 — xhs 0.2.10 文档 diff --git a/creator.html b/creator.html index 0f3bd97..0be72cb 100644 --- a/creator.html +++ b/creator.html @@ -5,7 +5,7 @@ - 笔记发布 — xhs 0.2.7 文档 + 笔记发布 — xhs 0.2.10 文档 diff --git a/genindex.html b/genindex.html index 150a3e3..484a249 100644 --- a/genindex.html +++ b/genindex.html @@ -5,7 +5,7 @@ - 索引 — xhs 0.2.7 文档 + 索引 — xhs 0.2.10 文档 @@ -82,6 +82,8 @@

C

  • cookie_dict (xhs.XhsClient property)
  • COSMETICS (xhs.FeedType 属性) +
  • +
  • create_complete_multipart_upload() (xhs.XhsClient 方法)
  • create_image_note() (xhs.XhsClient 方法)
  • @@ -140,10 +142,16 @@

    G

  • get() (xhs.XhsClient 方法)
  • get_emojis() (xhs.XhsClient 方法) +
  • +
  • get_follow_notifications() (xhs.XhsClient 方法)
  • get_home_feed() (xhs.XhsClient 方法)
  • get_home_feed_category() (xhs.XhsClient 方法) +
  • +
  • get_like_notifications() (xhs.XhsClient 方法) +
  • +
  • get_mention_notifications() (xhs.XhsClient 方法)
  • get_note_all_comments() (xhs.XhsClient 方法)
  • @@ -157,10 +165,14 @@

    G

  • get_note_sub_comments() (xhs.XhsClient 方法)
  • -
  • get_qrcode() (xhs.XhsClient 方法) +
  • get_notes_statistics() (xhs.XhsClient 方法)
    • upload_file() (xhs.XhsClient 方法) +
    • +
    • upload_file_with_slice() (xhs.XhsClient 方法)
    • user_agent (xhs.XhsClient property)
    • diff --git a/index.html b/index.html index 38cd097..896a2dd 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,7 @@ - 介绍 — xhs 0.2.7 文档 + 介绍 — xhs 0.2.10 文档 diff --git a/objects.inv b/objects.inv index 1419f7c185ba6d924c229628a02aa5e37aee83a2..b2bdf16ebf427a45cbf69022045228ffc77bcaec 100644 GIT binary patch delta 827 zcmV-B1H}B-2A~I!a(|dXYZNgQ$M5qg7WBFmJ@&S2r@G*FWOpszhHU1|Zrsddnq<12 zn;?Q9QU$dai?kpVEaE|-P{A+LweGhtlbLO&T5*#(wPfD!pO?IsmzUici~c>`dxR>Y4?pu zx9bf$-i9%^-s)Rnoxz6NH+OU0^VW=^yREKk4Bhh{_WI^n*W2uvQ$4rsb-V6{`Pv4( z)~0)ZS?tkRv?+mDE|ZKG#w!R*vW=up;RxiI1xsOg40z&W7TAGX+y-To0+xQv%-v;C zr2f`HQvuuQw1hUD5!s;luD8yuKZ6ZLxJfE3ON#? z5m;?r!P}GDBmic^2cXxVlYSXOQw1U@nbf5%Tn|;Av#CwOjX;_cK1A#>5f)(Ss9GWk z2}Y8z*hXf|BJe|1_3E&`njc1tXBHxhK-F4Bo+Apat$(947E!v$J8O+$=98cn?1!91 zer{SrW&+uiacf8F?t(~%bv1-9qzb2y1lN#AqX=1Lr`27Vg8~r8V>R<=1R_sID-9a@ zBo0{}_Kpo)cv0HPxs?PvaWzm^8L;4l6ayp7f_gsw;&O zY%HP++NeANOKcft9Ip9=rTI5eeKl9%Yo5gapnoqdo6Zmkb!P|}tOg9{fF97cjoFV+ z^Cur>&pyugjvUO{Ma_tiaV22VDkOEc{A_jJCj);R@MQ$Q5r)l zPFFESLbPtT1WP!ETQl`KkRiQsv(>g{HSJ2bGqCMJjvy&H8Gk1dmcpE2-yZe4Lv7OT zJENYnq0Oy#hDKO#v|$hR(_D9)HErl_r*CUR_ne1=p+44kHhcQi!0tNzzP+Kpw$Y%o zY2RNKdlZN+B@oGFn(;!sg0LjpNER&|f()3q6ov!9Qx`MO4BX--D5DgxbR(vpE(=5T zY=R~NxHihBq<@$%<}3y-Qw_}Z2$uRR2USd$glGart1WqRa+`R-On46{R5QEPp6f;+ zf|6-d+8}jbH746J>5vIXeZqy1Jto2c3|I)Rul%J6>ta>s3FE0jkfOSX(nXDgX^e5| z60Z^L`kaMsE^QEI3h55x#)&lD1(A%K#4vK<929^!4u912lL-h(SY#A~`Ywrl)`Y!d z0+(64$Y{?Nv}7^C27D4zhE($r3c^*s9ugA=$gQUMj`B7TrUB{)s&Np*5*F-*;Tq3w z3YW)}Pq-?j&r!HIGPO;m!HHvf+)y?lk;&aFW?SqDvM|GO4}uqxrFMu!9?S|gMPs13elc1BUk|hI zZ>>vR6}2WgJAH9}`qB!ScTKc7Z7*Jw>Yqmk+5TP?w)XZv*n?D+Ke|enNA^{)9IK{! j^ - 搜索 — xhs 0.2.7 文档 + 搜索 — xhs 0.2.10 文档 diff --git a/searchindex.js b/searchindex.js index 14c2725..5405362 100644 --- a/searchindex.js +++ b/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["basic","crawl","creator","index","source/xhs"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":5,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["basic.rst","crawl.rst","creator.rst","index.rst","source/xhs.rst"],objects:{"xhs.FeedType":[[4,1,1,"","CAREER"],[4,1,1,"","COSMETICS"],[4,1,1,"","EMOTION"],[4,1,1,"","FASION"],[4,1,1,"","FITNESS"],[4,1,1,"","FOOD"],[4,1,1,"","GAME"],[4,1,1,"","HOURSE"],[4,1,1,"","MOVIE"],[4,1,1,"","RECOMMEND"],[4,1,1,"","TRAVEL"]],"xhs.XhsClient":[[4,2,1,"","activate"],[4,2,1,"","check_code"],[4,2,1,"","check_qrcode"],[4,2,1,"","collect_note"],[4,2,1,"","comment_note"],[4,2,1,"","comment_user"],[4,3,1,"","cookie"],[4,3,1,"","cookie_dict"],[4,2,1,"","create_image_note"],[4,2,1,"","create_note"],[4,2,1,"","create_video_note"],[4,2,1,"","delete_note_comment"],[4,2,1,"","dislike_comment"],[4,2,1,"","dislike_note"],[4,2,1,"","follow_user"],[4,2,1,"","get"],[4,2,1,"","get_emojis"],[4,2,1,"","get_home_feed"],[4,2,1,"","get_home_feed_category"],[4,2,1,"","get_note_all_comments"],[4,2,1,"","get_note_by_id"],[4,2,1,"","get_note_by_id_from_html"],[4,2,1,"","get_note_by_keyword"],[4,2,1,"","get_note_comments"],[4,2,1,"","get_note_sub_comments"],[4,2,1,"","get_qrcode"],[4,2,1,"","get_search_suggestion"],[4,2,1,"","get_self_info"],[4,2,1,"","get_self_info2"],[4,2,1,"","get_suggest_ats"],[4,2,1,"","get_suggest_topic"],[4,2,1,"","get_upload_files_permit"],[4,2,1,"","get_user_all_notes"],[4,2,1,"","get_user_collect_notes"],[4,2,1,"","get_user_info"],[4,2,1,"","get_user_like_notes"],[4,2,1,"","get_user_notes"],[4,2,1,"","get_video_first_frame_image_id"],[4,2,1,"","like_comment"],[4,2,1,"","like_note"],[4,2,1,"","login_code"],[4,2,1,"","post"],[4,2,1,"","report_note_metrics"],[4,2,1,"","request"],[4,2,1,"","save_files_from_note_id"],[4,2,1,"","send_code"],[4,3,1,"","session"],[4,2,1,"","uncollect_note"],[4,2,1,"","unfollow_user"],[4,2,1,"","upload_file"],[4,3,1,"","user_agent"]],xhs:[[4,0,1,"","FeedType"],[4,0,1,"","XhsClient"]]},objnames:{"0":["py","class","Python \u7c7b"],"1":["py","attribute","Python \u5c5e\u6027"],"2":["py","method","Python \u65b9\u6cd5"],"3":["py","property","Python property"]},objtypes:{"0":"py:class","1":"py:attribute","2":"py:method","3":"py:property"},terms:{"10":[1,4],"11":4,"12":4,"20":4,"2023":4,"280148":4,"30":4,"5005":0,"86":4,"87323168":4,"default":4,"enum":4,"for":4,"function":4,"if":4,"in":4,"int":4,"return":4,"true":4,"with":4,a1:0,abnorm:4,activ:4,all:4,an:4,and:4,api:[0,4],argument:4,as:4,ats:4,author:4,basic_sign_serv:0,basic_sign_usag:0,basic_usag:0,be:4,bool:4,by:4,can:4,career:4,career_v3:4,cdn:0,check_cod:4,check_qrcod:[1,4],code:4,collect_not:[1,4],com:[3,4],comment:4,comment_id:4,comment_not:[1,4],comment_us:4,content:4,content_typ:4,cooki:[0,1,4],cookie_dict:4,core:4,cosmet:4,cosmetics_v3:4,count:4,cover:4,cover_path:4,crawl:4,crawl_interv:4,creat:4,create_image_not:4,create_not:4,create_video_not:4,creator:3,curl:0,cursor:4,data:4,delete_note_com:[1,4],desc:4,dict:4,dir_path:4,directori:4,dislike_com:[1,4],dislike_not:[1,4],display_titl:4,docker:0,don:4,emot:4,enumer:4,equal:4,explor:4,fact:4,fals:4,fashion_v3:4,fasion:4,feed_typ:4,feedtyp:1,fetch:4,file:4,file_id:4,file_path:4,file_typ:4,first:4,fit:4,fitness_v3:4,flask:3,follow:4,follow_us:[1,4],followed_author:4,food:4,food_v3:4,from:4,game:4,gaming_v3:4,gener:4,get:4,get_emoji:4,get_home_fe:[1,4],get_home_feed_categori:4,get_note_all_com:4,get_note_by_id:[1,4],get_note_by_id_from_html:4,get_note_by_keyword:[1,4],get_note_com:[1,4],get_note_sub_com:[1,4],get_qrcod:[1,4],get_search_suggest:4,get_self_info2:4,get_self_info:[1,4],get_suggest_at:4,get_suggest_top:4,get_upload_files_permit:4,get_user_all_not:4,get_user_collect_not:[1,4],get_user_info:[1,4],get_user_like_not:[1,4],get_user_not:[1,4],get_video_first_frame_image_id:4,gevent:0,gh:0,greater:4,has:4,has_mor:4,have:4,homefe:4,homefeed_recommend:4,hours:4,household_product_v3:4,http:[0,4],id:[1,4],ignor:4,imag:4,image_info:4,includ:4,info:4,input:4,instal:0,interact:4,interact_info:4,interv:4,is:4,is_creat:4,is_priv:4,it:[0,4],item:4,jpeg:4,js:0,jsdelivr:0,just:4,keyword:4,kwarg:4,last:4,latest:0,like_com:[1,4],like_not:[1,4],list:4,login_cod:4,love_v3:4,method:4,metric:4,min:0,mobile_token:4,more:4,movi:4,movie_and_tv_v3:4,mp4:4,multi_flag:4,must:4,net:0,none:4,note:4,note_id:4,note_titl:4,note_typ:4,note_user_id:4,num:4,number:4,obj:4,object:4,onli:4,option:4,order:4,other:4,page:4,page_s:4,param:4,parent:4,phone:4,pip:0,playwright:0,png:4,post:4,post_tim:4,properti:4,proxi:[1,4],py:0,python:4,qr_id:4,qrcode:4,reajason:[0,4],recommend:[1,4],report:4,report_note_metr:4,report_typ:4,request:[0,4],requirecool:0,respons:4,root_comment_id:4,run:0,same:4,save:4,save_files_from_note_id:4,search:4,searchnotetyp:4,searchsorttyp:4,second:4,send_cod:4,session:4,sign:4,simpl:4,size:4,sleep:4,so:4,sort:4,stai:4,stay_second:4,stealth:0,store:4,str:4,sub:4,that:4,thi:4,timeout:[1,4],titl:4,to:4,token:4,topic:4,trasform:4,travel:4,travel_v3:4,tupl:4,twice:4,type:4,uncollect_not:[1,4],unfollow_us:[1,4],upload_fil:4,uri:4,url:4,user:4,user_ag:[1,4],user_id:4,valu:4,video:4,video_id:4,video_info:4,video_path:4,viewer:4,viewer_user_id:4,wait_tim:4,want:4,web_sess:0,webid:0,what:4,which:4,will:4,www:[3,4],xhs:[0,1,3,4],xhs_client:1,xhsclient:[1,3],xhsdiscov:4,xiaohongshu:[3,4],you:4,your:4,zone:4},titles:["\u5feb\u901f\u5165\u95e8","\u4e3b\u9875\u722c\u53d6","\u7b14\u8bb0\u53d1\u5e03","\u4ecb\u7ecd","Documentation"],titleterms:{"class":4,document:4,feedtyp:4,flask:0,the:4,xhsclient:[0,4]}}) \ No newline at end of file +Search.setIndex({docnames:["basic","crawl","creator","index","source/xhs"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":5,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["basic.rst","crawl.rst","creator.rst","index.rst","source/xhs.rst"],objects:{"xhs.FeedType":[[4,1,1,"","CAREER"],[4,1,1,"","COSMETICS"],[4,1,1,"","EMOTION"],[4,1,1,"","FASION"],[4,1,1,"","FITNESS"],[4,1,1,"","FOOD"],[4,1,1,"","GAME"],[4,1,1,"","HOURSE"],[4,1,1,"","MOVIE"],[4,1,1,"","RECOMMEND"],[4,1,1,"","TRAVEL"]],"xhs.XhsClient":[[4,2,1,"","activate"],[4,2,1,"","check_code"],[4,2,1,"","check_qrcode"],[4,2,1,"","collect_note"],[4,2,1,"","comment_note"],[4,2,1,"","comment_user"],[4,3,1,"","cookie"],[4,3,1,"","cookie_dict"],[4,2,1,"","create_complete_multipart_upload"],[4,2,1,"","create_image_note"],[4,2,1,"","create_note"],[4,2,1,"","create_video_note"],[4,2,1,"","delete_note_comment"],[4,2,1,"","dislike_comment"],[4,2,1,"","dislike_note"],[4,2,1,"","follow_user"],[4,2,1,"","get"],[4,2,1,"","get_emojis"],[4,2,1,"","get_follow_notifications"],[4,2,1,"","get_home_feed"],[4,2,1,"","get_home_feed_category"],[4,2,1,"","get_like_notifications"],[4,2,1,"","get_mention_notifications"],[4,2,1,"","get_note_all_comments"],[4,2,1,"","get_note_by_id"],[4,2,1,"","get_note_by_id_from_html"],[4,2,1,"","get_note_by_keyword"],[4,2,1,"","get_note_comments"],[4,2,1,"","get_note_sub_comments"],[4,2,1,"","get_notes_statistics"],[4,2,1,"","get_notes_summary"],[4,2,1,"","get_qrcode"],[4,2,1,"","get_search_suggestion"],[4,2,1,"","get_self_info"],[4,2,1,"","get_self_info2"],[4,2,1,"","get_suggest_ats"],[4,2,1,"","get_suggest_topic"],[4,2,1,"","get_upload_files_permit"],[4,2,1,"","get_upload_id"],[4,2,1,"","get_user_all_notes"],[4,2,1,"","get_user_by_keyword"],[4,2,1,"","get_user_collect_notes"],[4,2,1,"","get_user_info"],[4,2,1,"","get_user_like_notes"],[4,2,1,"","get_user_notes"],[4,2,1,"","get_video_first_frame_image_id"],[4,2,1,"","like_comment"],[4,2,1,"","like_note"],[4,2,1,"","login_code"],[4,2,1,"","post"],[4,2,1,"","report_note_metrics"],[4,2,1,"","request"],[4,2,1,"","save_files_from_note_id"],[4,2,1,"","send_code"],[4,3,1,"","session"],[4,2,1,"","uncollect_note"],[4,2,1,"","unfollow_user"],[4,2,1,"","upload_file"],[4,2,1,"","upload_file_with_slice"],[4,3,1,"","user_agent"]],xhs:[[4,0,1,"","FeedType"],[4,0,1,"","XhsClient"]]},objnames:{"0":["py","class","Python \u7c7b"],"1":["py","attribute","Python \u5c5e\u6027"],"2":["py","method","Python \u65b9\u6cd5"],"3":["py","property","Python property"]},objtypes:{"0":"py:class","1":"py:attribute","2":"py:method","3":"py:property"},terms:{"10":[1,4],"11":4,"12":4,"20":4,"2023":4,"24":4,"280148":4,"30":4,"36":4,"48":4,"5005":0,"86":4,"87323168":4,"default":4,"enum":4,"for":4,"function":4,"if":4,"in":4,"int":4,"return":4,"true":4,"with":4,a1:0,abnorm:4,activ:4,all:4,an:4,and:4,api:[0,4],argument:4,as:4,ats:4,author:4,basic_sign_serv:0,basic_sign_usag:0,basic_usag:0,be:4,bool:4,by:4,can:4,career:4,career_v3:4,cdn:0,check_cod:4,check_qrcod:[1,4],code:4,collect_not:[1,4],com:[3,4],comment:4,comment_id:4,comment_not:[1,4],comment_us:4,content:4,content_typ:4,cooki:[0,1,4],cookie_dict:4,core:4,cosmet:4,cosmetics_v3:4,count:4,cover:4,cover_path:4,crawl:4,crawl_interv:4,creat:4,create_complete_multipart_upload:4,create_image_not:4,create_not:4,create_video_not:4,creator:3,curl:0,cursor:4,data:4,date:4,delete_note_com:[1,4],desc:4,dict:4,dir_path:4,directori:4,dislike_com:[1,4],dislike_not:[1,4],display_titl:4,docker:0,don:4,emot:4,enumer:4,equal:4,explor:4,fact:4,fals:4,fashion_v3:4,fasion:4,feed_typ:4,feedtyp:1,fetch:4,file:4,file_id:4,file_path:4,file_typ:4,first:4,fit:4,fitness_v3:4,flask:3,follow:4,follow_us:[1,4],followed_author:4,food:4,food_v3:4,from:4,game:4,gaming_v3:4,gener:4,get:4,get_emoji:4,get_follow_notif:4,get_home_fe:[1,4],get_home_feed_categori:4,get_like_notif:4,get_mention_notif:4,get_note_all_com:4,get_note_by_id:[1,4],get_note_by_id_from_html:4,get_note_by_keyword:[1,4],get_note_com:[1,4],get_note_sub_com:[1,4],get_notes_statist:4,get_notes_summari:4,get_qrcod:[1,4],get_search_suggest:4,get_self_info2:4,get_self_info:[1,4],get_suggest_at:4,get_suggest_top:4,get_upload_files_permit:4,get_upload_id:4,get_user_all_not:4,get_user_by_keyword:4,get_user_collect_not:[1,4],get_user_info:[1,4],get_user_like_not:[1,4],get_user_not:[1,4],get_video_first_frame_image_id:4,gevent:0,gh:0,greater:4,has:4,has_mor:4,have:4,homefe:4,homefeed_recommend:4,hours:4,household_product_v3:4,http:[0,4],id:[1,4],ignor:4,imag:4,image_info:4,includ:4,info:4,input:4,instal:0,interact:4,interact_info:4,interv:4,is:4,is_creat:4,is_priv:4,is_rec:4,it:[0,4],item:4,jpeg:4,js:0,jsdelivr:0,just:4,keyword:4,kwarg:4,last:4,latest:0,like_com:[1,4],like_not:[1,4],list:4,login_cod:4,love_v3:4,method:4,metric:4,min:0,mobile_token:4,more:4,movi:4,movie_and_tv_v3:4,mp4:4,multi_flag:4,must:4,net:0,none:4,note:4,note_id:4,note_titl:4,note_typ:4,note_user_id:4,num:4,number:4,obj:4,object:4,onli:4,option:4,or:4,order:4,other:4,page:4,page_s:4,param:4,parent:4,part:4,phone:4,pip:0,playwright:0,png:4,post:4,post_tim:4,properti:4,proxi:[1,4],py:0,python:4,qr_id:4,qrcode:4,reajason:[0,4],recommend:[1,4],report:4,report_note_metr:4,report_typ:4,request:[0,4],requirecool:0,respons:4,root_comment_id:4,run:0,same:4,save:4,save_files_from_note_id:4,search:4,searchnotetyp:4,searchsorttyp:4,second:4,send_cod:4,session:4,should:4,sign:4,simpl:4,size:4,sleep:4,so:4,sort:4,sort_bi:4,stai:4,stay_second:4,stealth:0,store:4,str:4,sub:4,that:4,thi:4,time:4,timeout:[1,4],titl:4,to:4,token:4,topic:4,trasform:4,travel:4,travel_v3:4,tupl:4,twice:4,type:4,uncollect_not:[1,4],unfollow_us:[1,4],upload_fil:4,upload_file_with_slic:4,upload_id:4,uri:4,url:4,user:4,user_ag:[1,4],user_id:4,valu:4,video:4,video_id:4,video_info:4,video_path:4,viewer:4,viewer_user_id:4,wait_tim:4,want:4,web_sess:0,webid:0,what:4,when:4,which:4,will:4,www:[3,4],xhs:[0,1,3,4],xhs_client:1,xhsclient:[1,3],xhsdiscov:4,xiaohongshu:[3,4],you:4,your:4,zone:4},titles:["\u5feb\u901f\u5165\u95e8","\u4e3b\u9875\u722c\u53d6","\u7b14\u8bb0\u53d1\u5e03","\u4ecb\u7ecd","Documentation"],titleterms:{"class":4,document:4,feedtyp:4,flask:0,the:4,xhsclient:[0,4]}}) \ No newline at end of file diff --git a/source/xhs.html b/source/xhs.html index a623acf..ce281c0 100644 --- a/source/xhs.html +++ b/source/xhs.html @@ -5,7 +5,7 @@ - Documentation — xhs 0.2.7 文档 + Documentation — xhs 0.2.10 文档 @@ -90,6 +90,11 @@

      The XhsClientproperty cookie_dict
      +
      +
      +create_complete_multipart_upload(file_id: str, token: str, upload_id: str, parts: list)[源代码]
      +
      +
      create_image_note(title, desc, files: list, post_time: Optional[str] = None, ats: Optional[list] = None, topics: Optional[list] = None, is_private: bool = False)[源代码]
      @@ -174,6 +179,11 @@

      The XhsClientget_emojis()[源代码]

      +
      +
      +get_follow_notifications(num: int = 20, cursor: str = '')[源代码]
      +
      +
      get_home_feed(feed_type: xhs.core.FeedType)[源代码]
      @@ -184,6 +194,16 @@

      The XhsClientget_home_feed_category()[源代码]

      +
      +
      +get_like_notifications(num: int = 20, cursor: str = '')[源代码]
      +
      + +
      +
      +get_mention_notifications(num: int = 20, cursor: str = '')[源代码]
      +
      +
      get_note_all_comments(note_id: str, crawl_interval: int = 1)[源代码]
      @@ -282,6 +302,31 @@

      The XhsClient

      +
      +
      +get_notes_statistics(page: int = 1, page_size: int = 48, sort_by='time', note_type=0, time=30, is_recent=True)[源代码]
      +
      +
      参数
      +
        +
      • page – page num default is 1

      • +
      • page_size – page size, 12 or 24 or 36 or 48

      • +
      • sort_by – time default

      • +
      • note_type – 0 is all, 1 is images, 2 is video

      • +
      • time – fetch date

      • +
      • is_recent – default is false, when time is 7, this should be false

      • +
      +
      +
      返回
      +

      +
      +
      +
      + +
      +
      +get_notes_summary()[源代码]
      +
      +
      get_qrcode()[源代码]
      @@ -356,6 +401,11 @@

      The XhsClient

      +
      +
      +get_upload_id(file_id, token)[源代码]
      +
      +
      get_user_all_notes(user_id: str, crawl_interval: int = 1)[源代码]
      @@ -376,6 +426,11 @@

      The XhsClient

      +
      +
      +get_user_by_keyword(keyword: str, page: int = 1, page_size: int = 20)[源代码]
      +
      +
      get_user_collect_notes(user_id: str, num: int = 30, cursor: str = '')[源代码]
      @@ -527,6 +582,11 @@

      The XhsClient

      +
      +
      +upload_file_with_slice(file_id: str, token: str, file_path: str)[源代码]
      +
      +
      property user_agent