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 @@
-
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('"', '"')
+ 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("&", "&"))
+ 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 方法)
+ - get_notes_summary() (xhs.XhsClient 方法)
+
+ - get_qrcode() (xhs.XhsClient 方法)
+
- get_search_suggestion() (xhs.XhsClient 方法)
- get_self_info() (xhs.XhsClient 方法)
@@ -172,8 +184,12 @@
G
- get_suggest_topic() (xhs.XhsClient 方法)
- get_upload_files_permit() (xhs.XhsClient 方法)
+
+ - get_upload_id() (xhs.XhsClient 方法)
- get_user_all_notes() (xhs.XhsClient 方法)
+
+ - get_user_by_keyword() (xhs.XhsClient 方法)
- get_user_collect_notes() (xhs.XhsClient 方法)
@@ -272,6 +288,8 @@ U
- 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 1419f7c..b2bdf16 100644
Binary files a/objects.inv and b/objects.inv differ
diff --git a/search.html b/search.html
index 9f0da42..0631c4f 100644
--- a/search.html
+++ b/search.html
@@ -5,7 +5,7 @@
- 搜索 — 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 XhsClient
property cookie_dict¶
+
+
-
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 XhsClient
get_emojis()[源代码]¶
+
+
-
get_home_feed(feed_type: xhs.core.FeedType)[源代码]¶
@@ -184,6 +194,16 @@ The XhsClient
get_home_feed_category()[源代码]¶
+
+
+
+
-
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_user_collect_notes(user_id: str, num: int = 30, cursor: str = '')[源代码]¶
@@ -527,6 +582,11 @@ The XhsClient
+
+
-
property user_agent¶