diff --git a/constant/__init__.py b/constant/__init__.py
new file mode 100644
index 0000000..40a96af
--- /dev/null
+++ b/constant/__init__.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/constant/baidu_tieba.py b/constant/baidu_tieba.py
new file mode 100644
index 0000000..cfd15e1
--- /dev/null
+++ b/constant/baidu_tieba.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+TIEBA_URL = 'https://tieba.baidu.com'
\ No newline at end of file
diff --git a/db.py b/db.py
index 335d8ae..13777a6 100644
--- a/db.py
+++ b/db.py
@@ -85,7 +85,7 @@ async def init_table_schema():
utils.logger.info("[init_table_schema] begin init mysql table schema ...")
await init_mediacrawler_db()
async_db_obj: AsyncMysqlDB = media_crawler_db_var.get()
- async with aiofiles.open("schema/tables.sql", mode="r") as f:
+ async with aiofiles.open("schema/tables.sql", mode="r", encoding="utf-8") as f:
schema_sql = await f.read()
await async_db_obj.execute(schema_sql)
utils.logger.info("[init_table_schema] mediacrawler table schema init successful")
diff --git a/media_platform/tieba/client.py b/media_platform/tieba/client.py
index f9e0375..edbbf19 100644
--- a/media_platform/tieba/client.py
+++ b/media_platform/tieba/client.py
@@ -10,6 +10,7 @@ from tenacity import (RetryError, retry, stop_after_attempt,
wait_fixed)
from base.base_crawler import AbstractApiClient
+from model.m_baidu_tieba import TiebaNote
from proxy.proxy_ip_pool import ProxyIpPool
from tools import utils
@@ -98,6 +99,7 @@ class BaiduTieBaClient(AbstractApiClient):
return res
utils.logger.error(f"[BaiduTieBaClient.get] 达到了最大重试次数,请尝试更换新的IP代理: {e}")
+ raise e
async def post(self, uri: str, data: dict, **kwargs) -> Dict:
"""
@@ -152,7 +154,7 @@ class BaiduTieBaClient(AbstractApiClient):
sort: SearchSortType = SearchSortType.TIME_DESC,
note_type: SearchNoteType = SearchNoteType.FIXED_THREAD,
random_sleep: bool = True
- ) -> List[Dict]:
+ ) -> List[TiebaNote]:
"""
根据关键词搜索贴吧帖子
Args:
@@ -180,7 +182,7 @@ class BaiduTieBaClient(AbstractApiClient):
random.randint(1, 5)
return self._page_extractor.extract_search_note_list(page_content)
- async def get_note_by_id(self, note_id: str) -> Dict:
+ async def get_note_by_id(self, note_id: str) -> TiebaNote:
"""
根据帖子ID获取帖子详情
Args:
@@ -192,8 +194,6 @@ class BaiduTieBaClient(AbstractApiClient):
uri = f"/p/{note_id}"
page_content = await self.get(uri, return_ori_content=True)
return self._page_extractor.extract_note_detail(page_content)
- # todo impl it
- return {}
async def get_note_all_comments(self, note_id: str, crawl_interval: float = 1.0,
callback: Optional[Callable] = None) -> List[Dict]:
@@ -229,7 +229,7 @@ class BaiduTieBaClient(AbstractApiClient):
return result
async def get_comments_all_sub_comments(self, comments: List[Dict], crawl_interval: float = 1.0,
- callback: Optional[Callable] = None) -> List[Dict]:
+ callback: Optional[Callable] = None) -> List[Dict]:
"""
获取指定评论下的所有子评论
Args:
diff --git a/media_platform/tieba/core.py b/media_platform/tieba/core.py
index 91795a4..a03f0ad 100644
--- a/media_platform/tieba/core.py
+++ b/media_platform/tieba/core.py
@@ -9,7 +9,8 @@ from playwright.async_api import (BrowserContext, BrowserType, Page,
import config
from base.base_crawler import AbstractCrawler
-from proxy.proxy_ip_pool import IpInfoModel, create_ip_pool, ProxyIpPool
+from model.m_baidu_tieba import TiebaNote
+from proxy.proxy_ip_pool import IpInfoModel, create_ip_pool
from store import tieba as tieba_store
from tools import utils
from tools.crawler_util import format_proxy_info
@@ -66,8 +67,7 @@ class TieBaCrawler(AbstractCrawler):
Returns:
"""
-
- utils.logger.info("[BaiduTieBaCrawler.search] Begin search baidutieba keywords")
+ utils.logger.info("[BaiduTieBaCrawler.search] Begin search baidu tieba keywords")
tieba_limit_count = 10 # tieba limit page fixed value
if config.CRAWLER_MAX_NOTES_COUNT < tieba_limit_count:
config.CRAWLER_MAX_NOTES_COUNT = tieba_limit_count
@@ -82,52 +82,36 @@ class TieBaCrawler(AbstractCrawler):
continue
try:
utils.logger.info(f"[BaiduTieBaCrawler.search] search tieba keyword: {keyword}, page: {page}")
- note_id_list: List[str] = []
- notes_list_res = await self.tieba_client.get_notes_by_keyword(
+ notes_list: List[TiebaNote] = await self.tieba_client.get_notes_by_keyword(
keyword=keyword,
page=page,
page_size=tieba_limit_count,
sort=SearchSortType.TIME_DESC,
note_type=SearchNoteType.FIXED_THREAD
)
- utils.logger.info(f"[BaiduTieBaCrawler.search] Search notes res:{notes_list_res}")
- if not notes_list_res:
+ if not notes_list:
+ utils.logger.info(f"[BaiduTieBaCrawler.search] Search note list is empty")
break
-
- for note_detail in notes_list_res:
- if note_detail:
- await tieba_store.update_tieba_note(note_detail)
- note_id_list.append(note_detail.get("note_id"))
+ utils.logger.info(f"[BaiduTieBaCrawler.search] Note List: {notes_list}")
+ await self.get_specified_notes(note_id_list=[note_detail.note_id for note_detail in notes_list])
page += 1
- utils.logger.info(f"[BaiduTieBaCrawler.search] Note details: {notes_list_res}")
- await self.batch_get_note_comments(note_id_list)
except Exception as ex:
- utils.logger.error(f"[BaiduTieBaCrawler.search] Search note list error, err: {ex}")
+ utils.logger.error(
+ f"[BaiduTieBaCrawler.search] Search keywords error, current page: {page}, current keyword: {keyword}, err: {ex}")
break
- async def fetch_creator_notes_detail(self, note_list: List[Dict]):
+ async def get_specified_notes(self, note_id_list: List[str] = config.TIEBA_SPECIFIED_ID_LIST):
"""
- Concurrently obtain the specified post list and save the data
+ Get the information and comments of the specified post
+ Args:
+ note_id_list:
+
+ Returns:
+
"""
semaphore = asyncio.Semaphore(config.MAX_CONCURRENCY_NUM)
task_list = [
- self.get_note_detail(
- note_id=post_item.get("note_id"),
- semaphore=semaphore
- )
- for post_item in note_list
- ]
-
- note_details = await asyncio.gather(*task_list)
- for note_detail in note_details:
- if note_detail:
- await tieba_store.update_tieba_note(note_detail)
-
- async def get_specified_notes(self):
- """Get the information and comments of the specified post"""
- semaphore = asyncio.Semaphore(config.MAX_CONCURRENCY_NUM)
- task_list = [
- self.get_note_detail(note_id=note_id, semaphore=semaphore) for note_id in config.TIEBA_SPECIFIED_ID_LIST
+ self.get_note_detail_async_task(note_id=note_id, semaphore=semaphore) for note_id in note_id_list
]
note_details = await asyncio.gather(*task_list)
for note_detail in note_details:
@@ -135,11 +119,20 @@ class TieBaCrawler(AbstractCrawler):
await tieba_store.update_tieba_note(note_detail)
await self.batch_get_note_comments(config.TIEBA_SPECIFIED_ID_LIST)
- async def get_note_detail(self, note_id: str, semaphore: asyncio.Semaphore) -> Optional[Dict]:
- """Get note detail"""
+ async def get_note_detail_async_task(self, note_id: str, semaphore: asyncio.Semaphore) -> Optional[TiebaNote]:
+ """
+ Get note detail
+ Args:
+ note_id: baidu tieba note id
+ semaphore: asyncio semaphore
+
+ Returns:
+
+ """
async with semaphore:
try:
- note_detail: Dict = await self.tieba_client.get_note_by_id(note_id)
+ utils.logger.info(f"[BaiduTieBaCrawler.get_note_detail] Begin get note detail, note_id: {note_id}")
+ note_detail: TiebaNote = await self.tieba_client.get_note_by_id(note_id)
if not note_detail:
utils.logger.error(
f"[BaiduTieBaCrawler.get_note_detail] Get note detail error, note_id: {note_id}")
@@ -153,23 +146,38 @@ class TieBaCrawler(AbstractCrawler):
f"[BaiduTieBaCrawler.get_note_detail] have not fund note detail note_id:{note_id}, err: {ex}")
return None
- async def batch_get_note_comments(self, note_list: List[str]):
- """Batch get note comments"""
+ async def batch_get_note_comments(self, note_id_list: List[str]):
+ """
+ Batch get note comments
+ Args:
+ note_id_list:
+
+ Returns:
+
+ """
if not config.ENABLE_GET_COMMENTS:
utils.logger.info(f"[BaiduTieBaCrawler.batch_get_note_comments] Crawling comment mode is not enabled")
return
utils.logger.info(
- f"[BaiduTieBaCrawler.batch_get_note_comments] Begin batch get note comments, note list: {note_list}")
+ f"[BaiduTieBaCrawler.batch_get_note_comments] Begin batch get note comments, note list: {note_id_list}")
semaphore = asyncio.Semaphore(config.MAX_CONCURRENCY_NUM)
task_list: List[Task] = []
- for note_id in note_list:
- task = asyncio.create_task(self.get_comments(note_id, semaphore), name=note_id)
+ for note_id in note_id_list:
+ task = asyncio.create_task(self.get_comments_async_task(note_id, semaphore), name=note_id)
task_list.append(task)
await asyncio.gather(*task_list)
- async def get_comments(self, note_id: str, semaphore: asyncio.Semaphore):
- """Get note comments with keyword filtering and quantity limitation"""
+ async def get_comments_async_task(self, note_id: str, semaphore: asyncio.Semaphore):
+ """
+ Get comments async task
+ Args:
+ note_id:
+ semaphore:
+
+ Returns:
+
+ """
async with semaphore:
utils.logger.info(f"[BaiduTieBaCrawler.get_comments] Begin get note id comments {note_id}")
await self.tieba_client.get_note_all_comments(
@@ -178,23 +186,6 @@ class TieBaCrawler(AbstractCrawler):
callback=tieba_store.batch_update_tieba_note_comments
)
- async def create_tieba_client(self, ip_pool: ProxyIpPool) -> BaiduTieBaClient:
- """
- Create tieba client
- Args:
- ip_pool:
-
- Returns:
-
- """
- """Create tieba client"""
- utils.logger.info("[BaiduTieBaCrawler.create_tieba_client] Begin create baidutieba API client ...")
- cookie_str, cookie_dict = utils.convert_cookies(await self.browser_context.cookies())
- tieba_client_obj = BaiduTieBaClient(
- ip_pool=ip_pool,
- )
- return tieba_client_obj
-
async def launch_browser(
self,
chromium: BrowserType,
@@ -202,7 +193,17 @@ class TieBaCrawler(AbstractCrawler):
user_agent: Optional[str],
headless: bool = True
) -> BrowserContext:
- """Launch browser and create browser context"""
+ """
+ Launch browser and create browser
+ Args:
+ chromium:
+ playwright_proxy:
+ user_agent:
+ headless:
+
+ Returns:
+
+ """
utils.logger.info("[BaiduTieBaCrawler.launch_browser] Begin create browser context ...")
if config.SAVE_LOGIN_STATE:
# feat issue #14
@@ -227,6 +228,10 @@ class TieBaCrawler(AbstractCrawler):
return browser_context
async def close(self):
- """Close browser context"""
+ """
+ Close browser context
+ Returns:
+
+ """
await self.browser_context.close()
utils.logger.info("[BaiduTieBaCrawler.close] Browser context closed ...")
diff --git a/media_platform/tieba/help.py b/media_platform/tieba/help.py
index 2c1144d..efba258 100644
--- a/media_platform/tieba/help.py
+++ b/media_platform/tieba/help.py
@@ -1,18 +1,21 @@
# -*- coding: utf-8 -*-
-
-from typing import List, Dict
+import re
+from typing import List, Dict, Tuple
from parsel import Selector
+from model.m_baidu_tieba import TiebaNote
+from constant import baidu_tieba as const
+
class TieBaExtractor:
def __init__(self):
pass
@staticmethod
- def extract_search_note_list(page_content: str) -> List[Dict]:
+ def extract_search_note_list(page_content: str) -> List[TiebaNote]:
"""
- 提取贴吧帖子列表
+ 提取贴吧帖子列表,这里提取的关键词搜索结果页的数据,还缺少帖子的回复数和回复页等数据
Args:
page_content: 页面内容的HTML字符串
@@ -21,33 +24,24 @@ class TieBaExtractor:
"""
xpath_selector = "//div[@class='s_post']"
post_list = Selector(text=page_content).xpath(xpath_selector)
- result = []
+ result: List[TiebaNote] = []
for post in post_list:
- post_id = post.xpath(".//span[@class='p_title']/a/@data-tid").get(default='').strip()
- title = post.xpath(".//span[@class='p_title']/a/text()").get(default='').strip()
- link = post.xpath(".//span[@class='p_title']/a/@href").get(default='')
- description = post.xpath(".//div[@class='p_content']/text()").get(default='').strip()
- forum = post.xpath(".//a[@class='p_forum']/font/text()").get(default='').strip()
- forum_link = post.xpath(".//a[@class='p_forum']/@href").get(default='')
- author = post.xpath(".//a[starts-with(@href, '/home/main')]/font/text()").get(default='').strip()
- author_link = post.xpath(".//a[starts-with(@href, '/home/main')]/@href").get(default='')
- date = post.xpath(".//font[@class='p_green p_date']/text()").get(default='').strip()
- result.append({
- "note_id": post_id,
- "title": title,
- "desc": description,
- "note_url": link,
- "time": date,
- "tieba_name": forum,
- "tieba_link": forum_link,
- "nickname": author,
- "nickname_link": author_link,
- })
-
+ tieba_note = TiebaNote(
+ note_id=post.xpath(".//span[@class='p_title']/a/@data-tid").get(default='').strip(),
+ title=post.xpath(".//span[@class='p_title']/a/text()").get(default='').strip(),
+ desc=post.xpath(".//div[@class='p_content']/text()").get(default='').strip(),
+ note_url=const.TIEBA_URL + post.xpath(".//span[@class='p_title']/a/@href").get(default=''),
+ user_nickname=post.xpath(".//a[starts-with(@href, '/home/main')]/font/text()").get(default='').strip(),
+ user_link=const.TIEBA_URL + post.xpath(".//a[starts-with(@href, '/home/main')]/@href").get(default=''),
+ tieba_name=post.xpath(".//a[@class='p_forum']/font/text()").get(default='').strip(),
+ tieba_link=const.TIEBA_URL + post.xpath(".//a[@class='p_forum']/@href").get(default=''),
+ publish_time=post.xpath(".//font[@class='p_green p_date']/text()").get(default='').strip(),
+ )
+ result.append(tieba_note)
return result
- @staticmethod
- def extract_note_detail(page_content: str) -> Dict:
+
+ def extract_note_detail(self, page_content: str) -> TiebaNote:
"""
提取贴吧帖子详情
Args:
@@ -57,13 +51,33 @@ class TieBaExtractor:
"""
content_selector = Selector(text=page_content)
- # 查看楼主的链接: only_view_author_link: / p / 9117905169?see_lz = 1
- only_view_author_link = content_selector.xpath("//*[@id='lzonly_cntn']/@href").get(default='').strip() #
+ first_floor_selector = content_selector.xpath("//div[@class='p_postlist'][1]")
+ only_view_author_link = content_selector.xpath("//*[@id='lzonly_cntn']/@href").get(default='').strip()
note_id = only_view_author_link.split("?")[0].split("/")[-1]
- title = content_selector.xpath("//*[@id='j_core_title_wrap']/h3").get(default='').strip()
- desc = content_selector.xpath("//meta[@name='description']").get(default='').strip()
- note_url = f"/p/{note_id}"
- pass
+ # 帖子回复数、回复页数
+ thread_num_infos = content_selector.xpath(
+ "//div[@id='thread_theme_5']//li[@class='l_reply_num']//span[@class='red']"
+ )
+ # IP地理位置、发表时间
+ other_info_content = content_selector.xpath(".//div[@class='post-tail-wrap']").get(default="").strip()
+ ip_location, publish_time = self.extract_ip_and_pub_time(other_info_content)
+ note = TiebaNote(
+ note_id=note_id,
+ title=content_selector.xpath("//title/text()").get(default='').strip(),
+ desc=content_selector.xpath("//meta[@name='description']/@content").get(default='').strip(),
+ note_url=const.TIEBA_URL + f"/p/{note_id}",
+ user_link=const.TIEBA_URL + first_floor_selector.xpath(".//a[@class='p_author_face ']/@href").get(default='').strip(),
+ user_nickname=first_floor_selector.xpath(".//a[@class='p_author_name j_user_card']/text()").get(default='').strip(),
+ user_avatar=first_floor_selector.xpath(".//a[@class='p_author_face ']/img/@src").get(default='').strip(),
+ tieba_name=content_selector.xpath("//a[@class='card_title_fname']/text()").get(default='').strip(),
+ tieba_link=const.TIEBA_URL + content_selector.xpath("//a[@class='card_title_fname']/@href").get(default=''),
+ ip_location=ip_location,
+ publish_time=publish_time,
+ total_replay_num=thread_num_infos[0].xpath("./text()").get(default='').strip(),
+ total_replay_page=thread_num_infos[1].xpath("./text()").get(default='').strip(),
+ )
+ note.title = note.title.replace(f"【{note.tieba_name}】_百度贴吧", "")
+ return note
@staticmethod
def extract_tieba_note_comments(page_content: str) -> List[Dict]:
@@ -93,12 +107,40 @@ class TieBaExtractor:
"time": date,
})
+ @staticmethod
+ def extract_ip_and_pub_time(html_content: str) -> Tuple[str, str]:
+ """
+ 提取IP位置和发布时间
+ Args:
+ html_content:
+ Returns:
-if __name__ == '__main__':
+ """
+ pattern_ip = re.compile(r'IP属地:(\S+)')
+ pattern_pub_time = re.compile(r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2})')
+ ip_match = pattern_ip.search(html_content)
+ time_match = pattern_pub_time.search(html_content)
+ ip = ip_match.group(1) if ip_match else ""
+ pub_time = time_match.group(1) if time_match else ""
+ return ip, pub_time
+
+def test_extract_search_note_list():
with open("test_data/search_keyword_notes.html", "r", encoding="utf-8") as f:
content = f.read()
extractor = TieBaExtractor()
- _result = extractor.extract_search_note_list(content)
- print(_result)
- print(f"Total: {len(_result)}")
+ result = extractor.extract_search_note_list(content)
+ print(result)
+
+
+def test_extract_note_detail():
+ with open("test_data/note_detail.html", "r", encoding="utf-8") as f:
+ content = f.read()
+ extractor = TieBaExtractor()
+ result = extractor.extract_note_detail(content)
+ print(result.model_dump())
+
+
+if __name__ == '__main__':
+ test_extract_search_note_list()
+ test_extract_note_detail()
diff --git a/media_platform/tieba/test_data/note_detail.html b/media_platform/tieba/test_data/note_detail.html
new file mode 100644
index 0000000..e4ecae6
--- /dev/null
+++ b/media_platform/tieba/test_data/note_detail.html
@@ -0,0 +1,839 @@
+
对于一个父亲来说,这个女儿14岁就死了【以太比特吧】_百度贴吧
+
+
+
+
+
+
+
+
+ 签到排名:今日本吧第0个签到,
本吧因你更精彩,明天继续来努力!
连续签到:天 累计签到:天
0超级会员单次开通12个月以上,赠送连续签到卡3张
以太比特吧 关注:309,573贴子:5,368,434
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 章景轩
+
+
+ -
+
+
+
+ -
+
+
+
+
点击展开,查看完整图片
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 杜草莓
+
+
+ -
+
+
+
+ -
+
+
+
本来觉得就凭14岁的这点叛逆父亲不再理她觉得这个这个父亲是有点问题的,后来看到母亲也不理了,我就知道这女的肯定隐藏了很多自己干得垃圾事没说,她活该
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 我只是个薯条
+
+
+ -
+
+
+
+ -
+
+
+
这女的晚上不回家她爹去找她,被黄毛打进医院,也没来医院看过,最后和黄毛结婚也不来往。想起三套房想爆她爹金币,结果找不到求助平台。幸好她爹跑得快。
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 森歌の友
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 沉寂V殇
+
+
+ -
+
+
+
+ -
+
+
+
太假了,混社会不良太妹,还考高中,选专业。当没有大专么
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 独爱小尹
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 圣人姬惠
+
+
+ -
+
+
+
+ -
+
+
+
父亲问题很大,应该在14岁那年再生一个或者领养一个
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ ID不重要
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 猎萝者
+
+
+
+ -
+
+
+
站在作者的角度来看,肯定都是挑了对自己及其有利的东西来说了,然而
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 小霸王复读机
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 幸福的橘子
+
+
+
+ -
+
+
+
叛逆期你懂的这6个字包含了不知道多少事
父母没对他发火而是耐心劝导也不知道包含了多少,我不好说,而且14岁逃学混社会
初三高一的学生这么弄基本也是烂了
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 萌新龍傲天
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 多米吧
+
+
+ -
+
+
+
+ -
+
+
+
女的独生,八成是结婚嫁了混混日子不如意,想着爆父母金币3套房,后来连母亲都躲着她足以说明一切
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 隔流光-沉暖
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 最后的轻语7
+
+
+ -
+
+
+
+ -
+
+
+
对自己闭口不谈,
不好评价
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 我就是鱼
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 零九-
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 笑平天尊周青
+
+
+
+ -
+
+
+
她的母亲从前那么希望这个家和好,对女儿也很好,结果突然也躲着她
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ love夜夜声声
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 透破苍穹
+
+
+
+ -
+
+
+
网传的被隐瞒的另一部分故事,不保真
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 搬砖猫表哥
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 小蟹echo
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ Von_Telum
+
+
+
+ -
+
+
+
默认信xxn说的话已经很反映现在的环境了
這是最後一個教訓了
父親給的最後一個教訓,停止了你的反叛期,永久有效
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 成为烤鱼的寿司
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 驗桧
+
+
+
+ -
+
+
+
哇,是没头没尾的讲故事,甚至比聊天记录还干净,这下不得不信了
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 蓝染暗恋千神
+
+
+ -
+
+
+
+ -
+
+
+
叛逆期,是我懂的那个吗?
就是咒他爸要死还找烂仔来对付他爸,给人当街一顿打自己跑路了那个吗?
要我说,父母都体现出最大的斯文和忍让了,换作素质低点的可能牙齿都给人干碎了。
+ -
+
+
+
+
+
+ -
+
+
+ -
+
+ 百里逐星
+
+
+ -
+
+
+
+ -
+
+
+
自己犯贱能怪谁呢
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 魔拜
魔蛋
\ No newline at end of file
diff --git a/media_platform/tieba/test_data/note_detail_and_comments.html b/media_platform/tieba/test_data/note_detail_and_comments.html
deleted file mode 100644
index 132068a..0000000
--- a/media_platform/tieba/test_data/note_detail_and_comments.html
+++ /dev/null
@@ -1,7558 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 日 |
- 一 |
- 二 |
- 三 |
- 四 |
- 五 |
- 六 |
-
-
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
- |
- |
- |
- |
- |
- |
- |
-
-
-
-
-
-
-
-
签到排名:今日本吧第0个签到,
-
-
本吧因你更精彩,明天继续来努力!
-
-
-
本吧排名:15
-
-
本吧签到人数:3857
-
-
-
-
-
-
- 本月漏签0次!
-
-
-
0
-
成为超级会员,赠送8张补签卡
-
如何使用?
-
-
-
-
- 点击日历上漏签日期,即可进行补签。
-
-
-
-
-
-
-
-
-
-
-
连续签到:天 累计签到:天
-
-
-
0
-
- 超级会员单次开通12个月以上,赠送连续签到卡3张
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 章景轩
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
点击展开,查看完整图片
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 杜草莓
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
- 本来觉得就凭14岁的这点叛逆父亲不再理她觉得这个这个父亲是有点问题的,后来看到母亲也不理了,我就知道这女的肯定隐藏了很多自己干得垃圾事没说,她活该
-
-
-
-
-
-
-
-
-
-
-
- -
-
铭寒:
号废了重练一个而已,只是她妈后来才明白这一点
-
-
-
- -
-
-
- -
-
你的隔壁王哥:
十四岁能把人逼到没有一点犹豫的跳楼,有多大的学习压力想过没?这种家庭内为了子女成才会不记一切代价,甚至是以折磨的方式,而之后的一切变故都是由于这次跳楼父亲不闻不问的态度,换作是你心灰意泠后只会做的比他更过分,亲情破裂会让最后一丝克制也一同丧失。
-
-
-
- -
-
-
-
快拉黑尔父:
回复 你的隔壁王哥 :闷油瓶的话还能理解一下,小太妹为了得到什么说跳就跳我是一点也不怀疑也不同情的。你现在同情小心以后糟老罪咯。真要对她不好也不至于长大了好多事想明白了反而一直想修复关系。
-
-
-
- -
-
你的隔壁王哥:
回复 快拉黑尔父 :十四岁第一次逃学,还在担心父母会不会打他,说明在此之前完全就是个乖乖女。初三才逃第一次学,如果是太妹初二就已经插着翅膀到处飞了,而且跳楼母亲没有任何心里准备,就说明在以往的形象里是不可能做出这事,说明从一开始就只是正常女学生。
-
-
-
-
- -
-
-
- -
-
你的隔壁王哥:
回复 快拉黑尔父 :如果说是太妹,那么跳楼之前必然会有各种前车之鉴,换句话说为了得到某样需求常用跳楼作为威胁。这种头也不回没有任何犹豫的跳楼,显然不是为了得到什么,就是单纯的寻死,你觉得太妹会这么纯粹的寻死吗?太妹的心理承受能力可高多了,只有未经世事的小白心里破防了才会这么干脆。
-
-
-
- -
-
-
-
快拉黑尔父:
回复 你的隔壁王哥 :完全的一面之词,结果可以看到的是什么?14岁钱的好父亲当她死了。对她一直很好的母亲也断了联系。想修复关系的反而是她。告诉你一个众所周知的事,人发言,一定,一定会下意识的美化自己。这是下意识。然后你再看看这个故事。
-
-
-
- -
-
-
-
快拉黑尔父:
回复 你的隔壁王哥 :而你所说的这个想索求什么,全包含在了一句叛逆期懂得都懂这一句话里面隐藏了。这就是她下意识的掩盖的事了。
-
-
-
- -
-
你的隔壁王哥:
回复 快拉黑尔父 :你要分析心理啊,纯粹的寻死只会在心里破防的时候才会存在,你如果接触过混社会的太妹,你就会发现他们会以寻求刺激为炫耀的资本,在这种群体内心理承受能力高的离谱。要想让一个学生心里破防,只能让她的天塌了,脆弱的心里才会在极短时间内崩溃,只有长期压抑才会产生这种心理。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 我只是个薯条
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
- 这女的晚上不回家她爹去找她,被黄毛打进医院,也没来医院看过,最后和黄毛结婚也不来往。想起三套房想爆她爹金币,结果找不到求助平台。幸好她爹跑得快。
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
已经在鹿上了:
亲戚女儿 跟一个理发的跑了 躲债 也有十来年了
-
-
-
- -
-
随遇:
怪不得,我就感觉这小作文里面少了很多东西,自己的问题一笔带过
-
-
-
- -
-
我爱吃吃吃22:
这是真的吗??我靠单看这个小作文是真的以为父亲也有问题,不能因为女儿叛逆就这样。父亲被黄毛打进医院不去看望还和黄毛结婚,这个逆天了,只能说果然是垃圾一个
-
-
-
- -
-
-
- -
-
-
-
- -
-
二刀流易大师:
回复 我爱吃吃吃22 :纯纯他妈自己主观写出来的东西,一面之词你就信她啊,也就欺负自己爹不会上知乎,就这文她都尽量把自己问题撇干净了,说自己多惨多惨,但明眼人还是能看出问题来就知道这人什么货色了,
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
纳兰雷诺:
回复 我爱吃吃吃22 :看这小作文你还能看出父亲有问题???每年一次的坐飞机或自驾旅游,每周一次的全家出门逛街,这物质和陪伴,有多少父母能做到的??
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 森歌の友
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 我知道,可怜之人,必有()
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
三生烟火:
可怜之人必有可恨之处,可恨之人必有可悲之苦。原句。
-
-
-
- -
-
-
- -
-
围观土豪月:
完全看不出哪里可怜了,全是自找的,这还是她自己的小作文,现实更可怕
-
-
-
-
- -
-
-
- -
-
猫织毛衣:
这话跟一个巴掌拍不响一样逆天,把这话奉为圭臬的人多少也沾点
-
-
-
- -
-
-
- -
-
蓝猫H:
她14岁跟黄毛出去过夜,父亲找上门被黄毛打到住院一个月,她还怪父亲不该打黄毛。和黄毛结婚以后联合婆家算计父母的房产,所以父母把房卖了
-
-
-
- -
-
无堏:
恨也指遗憾的意思
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 沉寂V殇
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 太假了,混社会不良太妹,还考高中,选专业。当没有大专么
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
小兔叽QAQ:
14岁一般就是初三阶段,荒一年考个最LJ的高中应该还是可以的,而且只提高考和大二,大概率是个给钱就能上的大专
-
-
-
- -
-
-
-
- -
-
lvgvf:
回复 小兔叽QAQ :我高中数学老师初中也是个太妹,初三被关起来一年,考了重点然后去了华师大,痞里痞气的。
-
-
-
- -
-
多言数穷,:
回复 lvgvf :有天赋聪明的人浪子回头也能救,但白白浪费了上限。至于普通人或者笨一点的,勤勤恳恳也就个普本,再作就是自寻死路了
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 独爱小尹
-
-
-
- -
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 圣人姬惠
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 父亲问题很大,应该在14岁那年再生一个或者领养一个
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
一袭布衣:
那年头计划生育,开除公职不是开玩笑的。
-
-
-
- -
-
-
- -
-
嗷呜嗷呜:
回复 一袭布衣 :可能还有另外一种原因,男的很爱老婆,生孩子对于女方是件受罪的事,有些男的不愿意见自己老婆再受这种罪
-
-
-
- -
-
沙子是液体:
当一个游戏你玩腻了,可能不是练新号而是弃游
-
-
-
- -
-
-
-
- -
-
白糖咖啡:
大概率是公职人员只能要一个小孩,解开这个限制之后可能有点力不重心了
-
-
-
- -
-
星辰蚕:
回复 777君aiai :女儿14岁时闹翻,二胎开放的时候,母亲年龄真不小了,至少快40了。
-
-
-
- -
-
浪里个浪:
他爹事教授,那个年代只能生一个
-
-
-
- -
-
奇玛:
回复 嗷呜嗷呜 :受罪是一说,丫十四五了她娘也得快四十或者已经四十了,再要孩子得算高龄产妇,很危险的
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- ID不重要
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 她爸怎么忍住不创小号的
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
张绵绵呱呱:
那年代只能有一个,不然开除公职
-
-
-
- -
-
-
- -
-
魅影精靈:
回复 星海小萌新 :对他来说代价太高了而已但有些人不在乎。那个年代一样很多多胎的
-
-
-
- -
-
魂殿-欲焱斗罗萧霖:
回复 魅影精靈 :她爹是211的教授啊,那个年代计划生育严的要死,能全家坐飞机出去玩,还能一周一逛街,这种家庭条件有几个做得到
-
-
-
- -
-
妹之空:
单看这个小作文,我总觉得哪里怪怪的,先不说每年都有几次旅游,说明家庭条件不差,只是偶尔一次的叛逆,我觉得人之常情,改了就行,但是才一次就被逼的跳楼不符合常理,肯定还有其他的没说出来,后面母亲也断了联系,卖了房子,很奇怪啊,要么就是小仙女知道家里有房想爆金币,结果父母直接消失了
-
-
-
-
- -
-
咚咚咚:
回复 妹之空 :xxn肯定不说自己的问题啊,满脑子都是父亲对自己多狠心丝毫不想自己是不是正常人
-
-
-
- -
-
黄金的回旋能量:
回复 魂殿-欲焱斗罗萧霖 :不是吧?看情况这女的跟我应该是一个时代 我今年30 我记得我小时候那会是第一胎生女的就可以再生一个 生男的就不能生了
-
-
-
- -
-
-
- -
-
-
- -
-
张绵绵呱呱:
回复 贴吧用户_798MN1M :那你这么说早就闹起来了,这不男女歧视吗,说话动脑子啊,我父母也是公职,那会生了我,不可能要第二个,要了分的房子都没收
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 猎萝者
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 站在作者的角度来看,肯定都是挑了对自己及其有利的东西来说了,然而
-
-
-
-
-
-
-
-
-
-
-
- -
-
浅水一抔:
字里行间都是对父亲的埋怨,14岁还未成年,衣食住行一边啃着父母一边说自己是单亲家庭,这么些年也不想着去修复关系,早干嘛去了,估计现在父亲年纪大了想着修复关系好多爆金币吧
-
-
-
- -
-
-
- -
-
miku哲学:
xxn小作文必掐头去尾,而且还是b乎那就更不用看了
-
-
-
- -
-
miku哲学:
xxn小作文必掐头去尾,而且还是b乎那就更不用看了
-
-
-
- -
-
叶家99少:
回复 浅水一抔 :别的地方看过这个故事,就是想暴金币。后面连妈妈都看出来了,所以连妈妈都不太理她了…
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 小霸王复读机
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 这个好像是之前新闻里的
-
-
-
-
-
-
-
-
-
-
-
- -
-
rockykenp:
应该不是,印象中我很久很久就看到过这个,当时应该是知乎第一人称的
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 幸福的橘子
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 叛逆期你懂的这6个字包含了不知道多少事
父母没对他发火而是耐心劝导也不知道包含了多少,我不好说,而且14岁逃学混社会
初三高一的学生这么弄基本也是烂了
-
-
-
-
-
-
-
-
-
-
-
- -
-
重生之女武神:
跳楼都算了,他还让黄毛把他爹打进医院,结婚后联合婆家想爆他爹金币。
-
-
-
- -
-
沙子是液体:
现在叙事主体是子女,都是受原生家庭伤害。实际为人父母才知道小孩随时能让你爆炸,小孩要是叛逆期一天能家暴你无数次
-
-
-
- -
-
大道至简3338:
叛逆期的意思应该是小孩长大了,变得有主见了。但现在很多人都觉得叛逆期就是变坏的意思,把一个人的坏归结在叛逆期上。
-
-
-
- -
-
幸福的橘子:
回复 大道至简3338 :叛逆期自己发瘟家长也不当人,个人一般会大力攻击家长的不是,他轻描淡写一句话相当于没说家长干了什么
-
-
-
- -
-
疯狂钻石:
只能说中间省略了太多,不说伤天害理,cs事情肯定做过,父亲才绝望的
-
-
-
-
- -
-
不愿_走轮回:
夜不归宿还叛逆期你懂得,大概率多人运动去了
-
-
-
- -
-
永乐总统:
给他211的老高知活爹气成这个样,我都怀疑她是杀人潜逃了
-
-
-
- -
-
小楼一夜听小雨:
回复 幸福的橘子 :是各方面都烂了,好好的一副牌,打成这样,要不然凭她的家庭,要是好好上学,现在起码是a8的水平
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 萌新龍傲天
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
小学森:
有的人记吃不记打,有的则相反 其实想想,谁都是第一次做父母,也都是第一次做儿女,我真觉得家庭关系挺难处的。有时候我能感受到父母的爱,但是说不了几句话,我就会有一股莫名的戾气,很容易发火,但其实我是个脾气很好的人
-
-
-
- -
-
小学森:
回复 萌新龍傲天 :最近看了一些文章,就有提到这种情绪,大概是因为小时候父母的情感投射导致的原因,每一次父母的好,都是在加深我的愧疚(比如说,赚钱都是为了你,怎么怎么滴,宣扬牺牲和奉献以及苦难),所以我拒绝父母对我的好,所以我逆反,似乎这样可以减轻我的负面情绪
-
-
-
- -
-
小学森:
记得有次电视上在放一个情绪很浓烈的视频,可能是近代史之类的,我爸问我有什么感想,其实我心里波澜壮阔,但面无表情,并且淡淡回了一句,一般,没什么感受。。然后我爸是我是个冷血动物,我笑了,说,没错,我确实是个冷血动物
-
-
-
- -
-
-
- -
-
小学森:
所以,如果我在这个故事里面,我大概率也会这样,甚至别说还能“抬头不见低头见了”,可能我早快活去了
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 多米吧
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 女的独生,八成是结婚嫁了混混日子不如意,想着爆父母金币3套房,后来连母亲都躲着她足以说明一切
-
-
-
-
-
-
-
-
-
-
-
- -
-
魂殿-欲焱斗罗萧霖:
从她爹一开始就放弃,到母亲在她结婚以后放弃就能看出来,自己干了不少垃圾事,估计结婚的对象也是个垃圾人
-
-
-
- -
-
-
- -
-
魂殿-欲焱斗罗萧霖:
回复 弥天大铞 :她夜不归宿她爹去找她,她让黄毛怂恿小混混给她爹打进住院,期间没来看过一眼,后面结婚也是跟这个黄毛,甚至还盯上家里三套房产。看看之前,一家人一年能坐飞机出去玩,一周一逛街,物质与精神都富足,家庭幸福美满的,被她搞成这样,hhh
-
-
-
- -
-
太稀奇了这个:
回复 魂殿-欲焱斗罗萧霖 :我想知道这种人在13岁之前接受了怎样的教育?因为我觉得人生来都是一张白纸,肯定是后天环境因素造成的吧
-
-
-
- -
-
-
-
- -
-
魂殿-欲焱斗罗萧霖:
回复 太稀奇了这个 :小时候教育一回事,到了叛逆期这种事情谁都不好说,万一小时候不咋出门,叛逆期出去一接触觉得外头新鲜就一直待外头了呢
-
-
-
- -
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 隔流光-沉暖
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 活该,早点死别耽误别人
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 最后的轻语7
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 对自己闭口不谈,
不好评价
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 再叛逆也不至于寻死
硬要死那就满足你当你死了
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 我就是鱼
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
- xxn的话一个标点符号都不能信
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 零九-
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 故事太过于离谱,是没讲完还是编的
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
肥水梦:
过于离谱反而真实,现实往往比剧本更魔幻
-
-
-
- -
-
麦兜小尐崽:
离谱?你是生活太好了?还是没见过比这个更加离谱的?现实往往比电影电视更魔幻。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 笑平天尊周青
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 她的母亲从前那么希望这个家和好,对女儿也很好,结果突然也躲着她
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- love夜夜声声
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 一眼就是避重就轻,能说的都是最轻的了
-
-
-
-
-
-
-
-
IP属地:广东来自iPhone客户端31楼2024-08-05 23:45
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 透破苍穹
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 网传的被隐瞒的另一部分故事,不保真
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
弋煙汀眞:
回复 蝙蝠侠不戴眼罩 :是不是编都无所谓,因为都没提供时间地点人名都没法求证,无非要么全信要么全不信,全信和全不信的结果也都一样
-
-
-
- -
-
🤗:
回复 蝙蝠侠不戴眼罩 :编不编无所谓,xxn自己写的也90%是编的
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 搬砖猫表哥
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 一般人做不到的绝情,可疑
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 小蟹echo
-
-
-
- -
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- Von_Telum
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 默认信xxn说的话已经很反映现在的环境了
-
-
-
-
-
-
-
-
IP属地:上海来自iPhone客户端36楼2024-08-06 00:30
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 這是最後一個教訓了
父親給的最後一個教訓,停止了你的反叛期,永久有效
-
-
-
-
-
-
-
-
IP属地:中国香港来自Android客户端37楼2024-08-06 00:39
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 成为烤鱼的寿司
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 驗桧
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 哇,是没头没尾的讲故事,甚至比聊天记录还干净,这下不得不信了
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
-
叶家99少:
好像以前看过,应该是真的,就是小仙女说的不能信,坏的流脓不听话,父亲死心了,她想暴金币,后面****心了
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 蓝染暗恋千神
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
IP属地:湖北来自iPhone客户端40楼2024-08-06 00:46
-
-
-
-
-
-
-
-
- -
-
安知池鱼:
我就知道 这女的不是个好东西。
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 叛逆期,是我懂的那个吗?
就是咒他爸要死还找烂仔来对付他爸,给人当街一顿打自己跑路了那个吗?
要我说,父母都体现出最大的斯文和忍让了,换作素质低点的可能牙齿都给人干碎了。
-
-
-
-
-
-
-
-
-
-
-
- -
-
三流作家明月:
这跌真的菩萨转世了,这要是我直接打断狗腿,养一辈子废人也比创造逆天生物给社会添麻烦强的多,有的孩子就得使劲管,不管不知道姓啥
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
-
- 百里逐星
-
-
- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
- 自己犯贱能怪谁呢
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - 发贴红色标题
- - 显示红名
- - 签到六倍经验
-
-
-
-
-
赠送补签卡1张,获得[经验书购买权]
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/model/__init__.py b/model/__init__.py
new file mode 100644
index 0000000..40a96af
--- /dev/null
+++ b/model/__init__.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/model/m_baidu_tieba.py b/model/m_baidu_tieba.py
new file mode 100644
index 0000000..6f420dc
--- /dev/null
+++ b/model/m_baidu_tieba.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from typing import Optional
+from pydantic import BaseModel, Field
+
+
+class TiebaNote(BaseModel):
+ note_id: str = Field(..., description="帖子ID")
+ title: str = Field(..., description="帖子标题")
+ desc: str = Field(default="", description="帖子描述")
+ note_url: str = Field(..., description="帖子链接")
+ publish_time: str = Field(default="", description="发布时间")
+ user_link: str = Field(default="", description="用户主页链接")
+ user_nickname: str = Field(default="", description="用户昵称")
+ user_avatar: str = Field(default="", description="用户头像地址")
+ tieba_name: str = Field(..., description="贴吧名称")
+ tieba_link: str = Field(..., description="贴吧链接")
+ total_replay_num: int = Field(default=0, description="回复总数")
+ total_replay_page: int = Field(default=0, description="回复总页数")
+ ip_location: Optional[str] = Field(default="", description="IP地理位置")
diff --git a/model/m_douyin.py b/model/m_douyin.py
new file mode 100644
index 0000000..40a96af
--- /dev/null
+++ b/model/m_douyin.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/model/m_kuaishou.py b/model/m_kuaishou.py
new file mode 100644
index 0000000..40a96af
--- /dev/null
+++ b/model/m_kuaishou.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/model/m_weibo.py b/model/m_weibo.py
new file mode 100644
index 0000000..40a96af
--- /dev/null
+++ b/model/m_weibo.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/model/m_xiaohongshu.py b/model/m_xiaohongshu.py
new file mode 100644
index 0000000..40a96af
--- /dev/null
+++ b/model/m_xiaohongshu.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/requirements.txt b/requirements.txt
index 151374f..eb405db 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -13,4 +13,4 @@ python-dotenv==1.0.1
jieba==0.42.1
wordcloud==1.9.3
matplotlib==3.9.0
-requests==2.32.3
\ No newline at end of file
+requests==2.32.3
diff --git a/schema/tables.sql b/schema/tables.sql
index 88828b7..2aadb38 100644
--- a/schema/tables.sql
+++ b/schema/tables.sql
@@ -349,29 +349,26 @@ ALTER TABLE `bilibili_video_comment`
ALTER TABLE `weibo_note_comment`
ADD COLUMN `parent_comment_id` VARCHAR(64) DEFAULT NULL COMMENT '父评论ID';
-SET
-FOREIGN_KEY_CHECKS = 1;
-
DROP TABLE IF EXISTS `tieba_note`;
-CREATE TABLE `tieba_note`
+CREATE TABLE tieba_note
(
- `id` int NOT NULL AUTO_INCREMENT COMMENT '自增ID',
- `note_id` varchar(64) NOT NULL COMMENT '帖子ID',
- `title` varchar(255) DEFAULT NULL COMMENT '笔记标题',
- `desc` longtext COMMENT '笔记描述',
- `time` varchar NOT NULL COMMENT '笔记发布时间',
- `note_url` varchar(255) DEFAULT NULL COMMENT '笔记详情页的URL',
- `nickname` varchar(64) DEFAULT NULL COMMENT '用户昵称',
- `nickname_link` varchar(255) DEFAULT NULL COMMENT '用户主页地址',
- `tieba_name` varchar(255) DEFAULT NULL COMMENT '贴吧名称',
- `tieba_link` varchar(255) DEFAULT NULL COMMENT '贴吧链接地址',
- `avatar` varchar(255) DEFAULT NULL COMMENT '用户头像地址',
- `ip_location` varchar(255) DEFAULT NULL COMMENT '评论时的IP地址',
- `add_ts` bigint NOT NULL COMMENT '记录添加时间戳',
- `last_modify_ts` bigint NOT NULL COMMENT '记录最后修改时间戳',
- `comment_count` varchar(16) DEFAULT NULL COMMENT '笔记评论数',
- PRIMARY KEY (`id`),
- KEY `idx_tieba_note_id` (`note_id`),
- KEY `idx_tieba_note_time` (`time`)
-) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='贴吧帖子表';
+ id BIGINT AUTO_INCREMENT PRIMARY KEY,
+ note_id VARCHAR(644) NOT NULL COMMENT '帖子ID',
+ title VARCHAR(255) NOT NULL COMMENT '帖子标题',
+ `desc` TEXT COMMENT '帖子描述',
+ note_url VARCHAR(255) NOT NULL COMMENT '帖子链接',
+ publish_time VARCHAR(255) NOT NULL COMMENT '发布时间',
+ user_link VARCHAR(255) NOT NULL COMMENT '用户主页链接',
+ user_nickname VARCHAR(255) NOT NULL COMMENT '用户昵称',
+ user_avatar VARCHAR(255) NOT NULL COMMENT '用户头像地址',
+ tieba_name VARCHAR(255) NOT NULL COMMENT '贴吧名称',
+ tieba_link VARCHAR(255) NOT NULL COMMENT '贴吧链接',
+ total_replay_num INT DEFAULT 0 COMMENT '帖子回复总数',
+ total_replay_page INT DEFAULT 0 COMMENT '帖子回复总页数',
+ ip_location VARCHAR(255) DEFAULT '' COMMENT 'IP地理位置',
+ add_ts BIGINT NOT NULL COMMENT '添加时间戳',
+ last_modify_ts BIGINT NOT NULL COMMENT '最后修改时间戳',
+ KEY `idx_tieba_note_note_id` (`note_id`),
+ KEY `idx_tieba_note_publish_time` (`publish_time`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='贴吧帖子表';
\ No newline at end of file
diff --git a/store/tieba/__init__.py b/store/tieba/__init__.py
index 9e47fa4..efaa6cc 100644
--- a/store/tieba/__init__.py
+++ b/store/tieba/__init__.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from typing import List
+from model.m_baidu_tieba import TiebaNote
from . import tieba_store_impl
from .tieba_store_impl import *
@@ -21,24 +22,20 @@ class TieBaStoreFactory:
return store_class()
-async def update_tieba_note(note_item: Dict):
- tieba_url = "https://tieba.baidu.com"
- note_id = note_item.get("note_id")
- local_db_item = {
- "note_id": note_id,
- "title": note_item.get("title") or note_item.get("desc", "")[:255],
- "desc": note_item.get("desc", ""),
- "note_url": tieba_url + note_item.get("note_url"),
- "time": note_item.get("time"),
- "tieba_name": note_item.get("tieba_name"),
- "tieba_link": tieba_url + note_item.get("tieba_link", ""),
- "nickname": note_item.get("nickname"),
- "nickname_link": tieba_url + note_item.get("nickname_link", ""),
- "ip_location": note_item.get("ip_location", ""),
- "last_modify_ts": utils.get_current_timestamp(),
- }
- utils.logger.info(f"[store.tieba.update_tieba_note] tieba note: {local_db_item}")
- await TieBaStoreFactory.create_store().store_content(local_db_item)
+async def update_tieba_note(note_item: TiebaNote):
+ """
+ Add or Update tieba note
+ Args:
+ note_item:
+
+ Returns:
+
+ """
+ save_note_item = note_item.model_dump()
+ save_note_item.update({"last_modify_ts": utils.get_current_timestamp()})
+ utils.logger.info(f"[store.tieba.update_tieba_note] tieba note: {save_note_item}")
+
+ await TieBaStoreFactory.create_store().store_content(save_note_item)
async def batch_update_tieba_note_comments(note_id: str, comments: List[Dict]):