datasources.xiaohongshu_comments.search_rednote_comments
Import scraped RedNote comments
It's prohibitively difficult to scrape data from RedNote within 4CAT itself due to its aggressive rate limiting. Instead, import data collected elsewhere.
1""" 2Import scraped RedNote comments 3 4It's prohibitively difficult to scrape data from RedNote within 4CAT itself due 5to its aggressive rate limiting. Instead, import data collected elsewhere. 6""" 7from datetime import datetime 8 9from backend.lib.search import Search 10from common.lib.item_mapping import MappedItem, MissingMappedField 11 12 13class SearchRedNoteComments(Search): 14 """ 15 Import scraped RedNote/Xiaohongshu/XSH comment data 16 """ 17 type = "xiaohongshu-comments-search" # job ID 18 category = "Search" # category 19 title = "Import scraped RedNote comment data" # title displayed in UI 20 description = "Import RedNote comment data collected with an external tool such as Zeeschuimer." # description displayed in UI 21 extension = "ndjson" # extension of result file, used internally and in UI 22 is_from_zeeschuimer = True 23 24 # not available as a processor for existing datasets 25 accepts = [None] 26 references = [ 27 "[Zeeschuimer browser extension](https://github.com/digitalmethodsinitiative/zeeschuimer)", 28 "[Worksheet: Capturing TikTok data with Zeeschuimer and 4CAT](https://tinyurl.com/nmrw-zeeschuimer-tiktok)" 29 ] 30 31 def get_items(self, query): 32 """ 33 Run custom search 34 35 Not available for RedNote 36 """ 37 raise NotImplementedError("RedNote/Xiaohongshu comment datasets can only be created by importing data from elsewhere") 38 39 40 @staticmethod 41 def map_item(item): 42 """ 43 Map XSH comment object to 4CAT item 44 45 Depending on whether the object was captured from JSON or HTML, treat it 46 differently. A lot of data is missing from HTML objects. 47 48 :param item: 49 :return: 50 """ 51 52 timestamp = datetime.fromtimestamp(int(item["create_time"]) / 1000).strftime("%Y-%m-%d %H:%M:%S") 53 54 return MappedItem({ 55 "id": item["id"], 56 "thread_id": item["note_id"], 57 "url": f"https://www.xiaohongshu.com/explore/{item['note_id']}", 58 "body": item.get("content", ""), 59 "timestamp": timestamp, 60 "author": item["user_info"]["nickname"], 61 "author_avatar_url": item["user_info"]["image"], 62 "ip_location": item["ip_location"] if item.get("ip_location") else MissingMappedField(""), 63 "likes": item["like_count"], 64 "replies": item["sub_comment_count"], 65 "unix_timestamp": int(item["create_time"] / 1000) 66 })
14class SearchRedNoteComments(Search): 15 """ 16 Import scraped RedNote/Xiaohongshu/XSH comment data 17 """ 18 type = "xiaohongshu-comments-search" # job ID 19 category = "Search" # category 20 title = "Import scraped RedNote comment data" # title displayed in UI 21 description = "Import RedNote comment data collected with an external tool such as Zeeschuimer." # description displayed in UI 22 extension = "ndjson" # extension of result file, used internally and in UI 23 is_from_zeeschuimer = True 24 25 # not available as a processor for existing datasets 26 accepts = [None] 27 references = [ 28 "[Zeeschuimer browser extension](https://github.com/digitalmethodsinitiative/zeeschuimer)", 29 "[Worksheet: Capturing TikTok data with Zeeschuimer and 4CAT](https://tinyurl.com/nmrw-zeeschuimer-tiktok)" 30 ] 31 32 def get_items(self, query): 33 """ 34 Run custom search 35 36 Not available for RedNote 37 """ 38 raise NotImplementedError("RedNote/Xiaohongshu comment datasets can only be created by importing data from elsewhere") 39 40 41 @staticmethod 42 def map_item(item): 43 """ 44 Map XSH comment object to 4CAT item 45 46 Depending on whether the object was captured from JSON or HTML, treat it 47 differently. A lot of data is missing from HTML objects. 48 49 :param item: 50 :return: 51 """ 52 53 timestamp = datetime.fromtimestamp(int(item["create_time"]) / 1000).strftime("%Y-%m-%d %H:%M:%S") 54 55 return MappedItem({ 56 "id": item["id"], 57 "thread_id": item["note_id"], 58 "url": f"https://www.xiaohongshu.com/explore/{item['note_id']}", 59 "body": item.get("content", ""), 60 "timestamp": timestamp, 61 "author": item["user_info"]["nickname"], 62 "author_avatar_url": item["user_info"]["image"], 63 "ip_location": item["ip_location"] if item.get("ip_location") else MissingMappedField(""), 64 "likes": item["like_count"], 65 "replies": item["sub_comment_count"], 66 "unix_timestamp": int(item["create_time"] / 1000) 67 })
Import scraped RedNote/Xiaohongshu/XSH comment data
references =
['[Zeeschuimer browser extension](https://github.com/digitalmethodsinitiative/zeeschuimer)', '[Worksheet: Capturing TikTok data with Zeeschuimer and 4CAT](https://tinyurl.com/nmrw-zeeschuimer-tiktok)']
def
get_items(self, query):
32 def get_items(self, query): 33 """ 34 Run custom search 35 36 Not available for RedNote 37 """ 38 raise NotImplementedError("RedNote/Xiaohongshu comment datasets can only be created by importing data from elsewhere")
Run custom search
Not available for RedNote
@staticmethod
def
map_item(item):
41 @staticmethod 42 def map_item(item): 43 """ 44 Map XSH comment object to 4CAT item 45 46 Depending on whether the object was captured from JSON or HTML, treat it 47 differently. A lot of data is missing from HTML objects. 48 49 :param item: 50 :return: 51 """ 52 53 timestamp = datetime.fromtimestamp(int(item["create_time"]) / 1000).strftime("%Y-%m-%d %H:%M:%S") 54 55 return MappedItem({ 56 "id": item["id"], 57 "thread_id": item["note_id"], 58 "url": f"https://www.xiaohongshu.com/explore/{item['note_id']}", 59 "body": item.get("content", ""), 60 "timestamp": timestamp, 61 "author": item["user_info"]["nickname"], 62 "author_avatar_url": item["user_info"]["image"], 63 "ip_location": item["ip_location"] if item.get("ip_location") else MissingMappedField(""), 64 "likes": item["like_count"], 65 "replies": item["sub_comment_count"], 66 "unix_timestamp": int(item["create_time"] / 1000) 67 })
Map XSH comment object to 4CAT item
Depending on whether the object was captured from JSON or HTML, treat it differently. A lot of data is missing from HTML objects.
Parameters
- item:
Returns
Inherited Members
- backend.lib.worker.BasicWorker
- BasicWorker
- INTERRUPT_NONE
- INTERRUPT_RETRY
- INTERRUPT_CANCEL
- queue
- log
- manager
- interrupted
- modules
- init_time
- name
- run
- clean_up
- request_interrupt
- is_4cat_class
- backend.lib.search.Search
- max_workers
- prefix
- return_cols
- import_error_count
- import_warning_count
- process
- search
- import_from_file
- items_to_csv
- items_to_ndjson
- items_to_archive
- backend.lib.processor.BasicProcessor
- db
- job
- dataset
- owner
- source_dataset
- source_file
- config
- is_running_in_preset
- filepath
- work
- after_process
- remove_files
- abort
- iterate_proxied_requests
- push_proxied_request
- flush_proxied_requests
- iterate_archive_contents
- unpack_archive_contents
- extract_archived_file_by_name
- write_csv_items_and_finish
- write_archive_and_finish
- create_standalone
- save_annotations
- map_item_method_available
- get_mapped_item
- is_filter
- get_options
- get_status
- is_top_dataset
- is_from_collector
- get_extension
- is_rankable
- exclude_followup_processors
- is_4cat_processor