Python 采集 Facebook 评论插件、留言外挂程序

  • 实现时间:2021-05-30
  • 实现难度:★★★☆☆☆
  • 实现目标:采集 Facebook 评论插件、留言外挂程序的所有评论。
  • 完整代码:https://github.com/TRHX/Python3-Spider-Practice/tree/master/CommentPlugin/facebook-comments
  • 其他爬虫实战代码合集(持续更新):https://github.com/TRHX/Python3-Spider-Practice
  • 爬虫实战专栏(持续更新):https://itrhx.blog.csdn.net/article/category/9351278

文章目录

    • 【1x00】写在前面
    • 【2x00】逻辑分析
      • 【2x01】第一页
      • 【2x02】下一页
      • 【2x03】回复别人的评论
    • 【3x00】完整代码
    • 【4x00】数据截图


【1x00】写在前面

本文的采集代码适用于 Facebook 评论插件的评论采集。仅用于 Python 编程技术交流!

Facebook 评论插件官网:https://developers.facebook.com/products/social-plugins/comments

本文以 https://www.chinatimes.com/realtimenews/20210529003827-260407 为例。


【2x00】逻辑分析

【2x01】第一页

在页面的 Facebook 评论插件位置右键查看框架源代码,我们就可以看到第一页评论页面的源码,直接访问这个 URL 就可以看到评论信息。

在这里插入图片描述
这个页面的 URL 为:https://www.facebook.com/plugins/feedback.php?app_id=1379575469016080&channel=https%3A%2F%2Fstaticxx.facebook.com%2Fx%2Fconnect%2Fxd_arbiter%2F%3Fversion%3D46%23cb%3Df22d8c81d4ce144%26domain%3Dwww.chinatimes.com%26origin%3Dhttps%253A%252F%252Fwww.chinatimes.com%252Ff5f738a4fa595%26relation%3Dparent.parent&container_width=924&height=100&href=https%3A%2F%2Fwww.chinatimes.com%2Frealtimenews%2F20210529003827-260407&locale=zh_TW&numposts=5&order_by=reverse_time&sdk=joey&version=v3.2&width

我们将其格式化后,得到有以下参数:

https://www.facebook.com/plugins/feedback.php?
app_id: 1379575469016080
channel: https://staticxx.facebook.com/x/connect/xd_arbiter/?version=46#cb=f22d8c81d4ce144
domain: www.chinatimes.com
origin: https%3A%2F%2Fwww.chinatimes.com%2Ff5f738a4fa595
relation: parent.parent
container_width: 924
height: 100
href: https://www.chinatimes.com/realtimenews/20210529003827-260407
locale: zh_TW
numposts: 5
order_by: reverse_time
sdk: joey
version: v3.2
width

以上参数中,app_id 需要我们去获取,domain 为该网站的域名,href 为该页面的 URL,剩下的其他参数经测试,对结果无影响,可直接复制过去。

直接在原页面搜索 app_id 的值,可以发现有个 meta 标签里面有这个值,直接使用 Xpath 匹配即可,注意,经过测试,部分使用了这个插件的页面是没有 app_id 的,不需要这个值也能获取,所以要注意报错处理。

try:app_id = content.xpath('//meta[@property="fb:app_id"]/@content')[0]
except IndexError:pass

在这里插入图片描述

对于第一页的所有评论,我们搜索评论文字的 Unicode 编码,可以在 response 中找到对应内容,直接将包含评论信息的这一段提取出来即可。

在这里插入图片描述


【2x02】下一页

点击载入其他留言,可以看到新的请求,类似于:https://www.facebook.com/plugins/comments/async/4045370158886862/pager/reverse_time/,请求方式为 post。URL 中 async 后面的一串数字为 targetID,可以在请求返回的数据中获取。

在这里插入图片描述
在这里插入图片描述
Form data 如下:

app_id: 1379575469016080
after_cursor: AQHReYdcksX9wFZEKA3MgNmN8PCRr7N3tFfZZuIKpCKnIuv-SxCycw4uZ1LqhtMr7RVkGyqACNdpkd9uJJ1jk6ne9g
limit: 10
__user: 0
__a: 1
__dyn: 7xe6EgU4e1QyUbFp62-m1FwAxu13wKxK7Emy8W3q322aewTwl8eU4K3a3W1DwUx60Vo1upE4W0LEK1pwo8swaq1xwEwhU1382gKi8wnU1e42C0BE1co3rw9O0RE5a1qw8W0b1w
__csr: 
__req: 1
__hs: 18777.PHASED:plugin_feedback_pkg.2.0.0.0
dpr: 1
__ccg: EXCELLENT
__rev: 1003879025
__s: ::lw3b8e
__hsi: 6968076253228168178
__comet_req: 0
locale: zh_TW
lsd: AVp5kXcGShk
jazoest: 2975
__sp: 1

app_id 和前面一样,after_cursor 的值通过搜索可以在上一页评论数据里面找到,换句话说,这一页的数据里面包含一个 after_cursor 的值,这个值是下一页请求 Form data 里面的参数。经测试其他参数的值不影响最终结果。

在这里插入图片描述


【2x03】回复别人的评论

回复别人的评论分为两种,第一种是直接可以看到的,第二种是需要点击“更多回复”才能看到的。第一种可以直接获取,第二种需要再次发送新的请求才能获取,新的请求的 URL 类似于:https://www.facebook.com/plugins/comments/async/comment/4045370158886862_4046939882063223/pager/ ,请求方式和下一页的请求方式一样,其中 URL comment 后面的一串数字仍然是 targetID, Form data 里的 after_cursor 参数可以在楼主的评论数据里面获取。


【3x00】完整代码

完整代码 Github 地址(点亮 star 有 buff 加成):
https://github.com/TRHX/Python3-Spider-Practice/tree/master/CommentPlugin/facebook-comments

# ====================================
# --*-- coding: utf-8 --*--
# @Time    : 2021-05-30
# @Author  : TRHX • 鲍勃
# @Blog    : www.itrhx.com
# @CSDN    : itrhx.blog.csdn.net
# @FileName: facebook.py
# @Software: PyCharm
# ====================================import requests
import json
import time
from lxml import etree# ==============================  测试链接  ============================== #
# https://www.chinatimes.com/realtimenews/20210529003827-260407
# https://tw.appledaily.com/life/20210530/IETG7L3VMBA57OD45OC5KFTCPQ/
# https://www.nownews.com/news/5281470
# https://www.thejakartapost.com/life/2019/06/03/how-to-lose-belly-fat-in-seven-days.html
# https://mcnews.cc/p/25224
# https://news.ltn.com.tw/news/world/breakingnews/3550262
# https://www.npf.org.tw/1/15857
# https://news.pts.org.tw/article/528425
# https://news.tvbs.com.tw/life/1518745
# ==============================  测试链接  ============================== #PAGE_URL = 'https://www.chinatimes.com/realtimenews/20210529003827-260407'
PROXIES = {'http': 'http://127.0.0.1:10809', 'https': 'http://127.0.0.1:10809'}
# PROXIES = None # 如果不需要代理则设置为 Noneclass FacebookComment:def __init__(self):self.json_name = 'facebook_comments.json'self.domain = PAGE_URL.split('/')[2]self.iframe_referer = 'https://{}/'.format(self.domain)self.user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'self.channel_base_url = 'https%3A%2F%2Fstaticxx.facebook.com%2Fx%2Fconnect%2Fxd_arbiter%2F%3Fversion%3D46%23cb%3Df17861604189654%26domain%3D{}%26origin%3Dhttps%253A%252F%252F{}%252Ff9bd3e89788d7%26relation%3Dparent.parent'self.referer_base_url = 'https://www.facebook.com/plugins/feedback.php?app_id={}&channel={}&container_width=924&height=100&href={}&locale=zh_TW&numposts=5&order_by=reverse_time&sdk=joey&version=v3.2&width'self.comment_base_url = 'https://www.facebook.com/plugins/comments/async/{}/pager/reverse_time/'self.reply_base_url = 'https://www.facebook.com/plugins/comments/async/comment/{}/pager/'self.target_id = ''self.referer = ''self.app_id = ''@staticmethoddef find_value(html: str, key: str, num_chars: int, separator: str) -> str:pos_begin = html.find(key) + len(key) + num_charspos_end = html.find(separator, pos_begin)return html[pos_begin: pos_end]@staticmethoddef save_comment(filename: str, information: json) -> None:with open(filename, 'a+', encoding='utf-8') as f:f.write(information + '\n')def get_app_id(self) -> None:headers = {'user-agent': self.user_agent}response = requests.get(url=PAGE_URL, headers=headers, proxies=PROXIES)html = response.textcontent = etree.HTML(html)try:app_id = content.xpath('//meta[@property="fb:app_id"]/@content')[0]self.app_id = app_idexcept IndexError:passdef get_first_parameter(self) -> str:channel_url = self.channel_base_url.format(self.domain, self.domain)referer_url = self.referer_base_url.format(self.app_id, channel_url, PAGE_URL)headers = {'authority': 'www.facebook.com','upgrade-insecure-requests': '1','user-agent': self.user_agent,'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9','sec-fetch-site': 'cross-site','sec-fetch-mode': 'navigate','sec-fetch-dest': 'iframe','referer': self.iframe_referer,'accept-language': 'zh-CN,zh;q=0.9'}response = requests.get(url=referer_url, headers=headers, proxies=PROXIES)data = response.textafter_cursor = self.find_value(data, "afterCursor", 3, separator='"')target_id = self.find_value(data, "targetID", 3, separator='"')# rev = find_value(data, "consistency", 9, separator='}')# 提取并保存最开始的评论tree = etree.HTML(data)script = tree.xpath('//body/script[last()]/text()')[0]html_begin = script.find('"comments":') + len('"comments":')html_end = script.find('"meta"')result = script[html_begin:html_end].strip()result_dict = json.loads(result[:-1])comment_type = 'first'self.processing_comment(result_dict, comment_type)self.target_id = target_idself.referer = referer_urlreturn after_cursordef get_comment(self, after_cursor: str, comment_url: str) -> None:""":param after_cursor: 字符串,下一页的 cursor:param comment_url: 字符串,评论页面的 URL:return: None"""num = 1while after_cursor:post_data = {'app_id': self.app_id,'after_cursor': after_cursor,'limit': 10,'iframe_referer': self.iframe_referer,'__user': 0,'__a': 1,'__dyn': '7xe6EgU4e3W3mbG2KmhwRwqo98nwgUbErxW5EyewSwMwyzEdU5i3K1bwOw-wpUe8hwem0nCq1ewbWbwmo62782CwOwKwEwhU1382gKi8wl8G0jx0Fw9q0B82swdK0D83mwkE5G0zE16o','__csr': '','__req': num,'__beoa': 0,'__pc': 'PHASED:plugin_feedback_pkg','dpr': 1,'__ccg': 'GOOD',# '__rev': rev,# '__s': ':mfgzaz:f4if6y',# '__hsi': '6899699958141806572','__comet_req': 0,'locale': 'zh_TW',# 'jazoest': '22012','__sp': 1}headers = {'user-agent': self.user_agent,'content-type': 'application/x-www-form-urlencoded','accept': '*/*','origin': 'https://www.facebook.com','sec-fetch-site': 'same-origin','sec-fetch-mode': 'cors','sec-fetch-dest': 'empty','referer': self.referer,'accept-language': 'zh-CN,zh;q=0.9'}response = requests.post(url=comment_url, headers=headers, proxies=PROXIES, data=post_data)data = response.textif 'xml version' in data:html_data = data.split('\n', 1)[1]else:html_data = dataif 'for (;;);' in html_data:json_text = html_data.split("for (;;);")[1]json_dict = json.loads(json_text)# print(json_dict)comment_type = 'second'self.processing_comment(json_dict, comment_type)try:after_cursor = json_dict['payload']['afterCursor']except KeyError:after_cursor = False# try:#     rev = json_dict['hsrp']['hblp']['consistency']['rev']# except KeyError:#     rev = ''else:after_cursor = Falsenum += 1def processing_comment(self, comment_dict: dict, comment_type: str) -> None:""":param comment_dict: 字典,所有评论信息,不同页面传来的数据可能结构不一样:param comment_type: 字符串,用来标记第一页和非第一页的评论:return: None"""try:comment_dict = comment_dict['payload']except KeyError:comment_dict = comment_dict# 如果为 first,表示是第一页评论,则全部储存,否则要去掉重复的第一个if comment_type == 'first':comment_ids = comment_dict['commentIDs']else:comment_ids = comment_dict['commentIDs'][1:]# 第一次储存,储存所有一级评论self.extract_comment(comment_dict, comment_ids)def extract_comment(self, comment_dict: dict, comment_ids: list) -> None:""":param comment_dict: 字典,所有的评论信息:param comment_ids: 列表,所有评论的 ID:return: None"""for i in range(len(comment_ids)):# ==================  info  ================== #crawl_timestamp = int(time.time())crawl_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())# =================  comment  ================ #comment = comment_dict['idMap'][comment_ids[i]]comment_id = comment_ids[i]target_id = comment['targetID']created_timestamp = comment['timestamp']['time']created_time_text = comment['timestamp']['text']created_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(float(created_timestamp)))comment_type = comment['type']ranges = comment['ranges']like_count = comment['likeCount']has_liked = comment['hasLiked']can_like = comment['canLike']can_edit = comment['canEdit']hidden = comment['hidden']high_lighted_words = comment['highlightedWords']spam_count = comment['spamCount']can_embed = comment['canEmbed']try:reply_count = comment['public_replies']['totalCount']except KeyError:reply_count = 0report_uri = 'https://www.facebook.com' + comment['reportURI']content = comment['body']['text']# =================  author  ================= #author_id = comment['authorID']author = comment_dict['idMap'][author_id]author_name = author['name']thumb_src = author['thumbSrc']uri = author['uri']is_verified = author['isVerified']author_type = author['type']comment_result_dict = {'info': {'pageURL': PAGE_URL,                      # 原始页面链接'crawlTimestamp': crawl_timestamp,        # 爬取时间戳'crawlTime': crawl_time                   # 爬取时间},'comment': {'type': comment_type,                     # 类型'commentID': comment_id,                  # 评论 ID'targetID': target_id,                    # 目标 ID,若为回复 A 的评论,则其值为 A 的评论 ID'createdTimestamp': created_timestamp,    # 评论时间戳'createdTime': created_time,              # 评论时间'createdTimeText': created_time_text,     # 评论时间(年月日)'likeCount': like_count,                  # 该条评论获得的点赞数'replyCount': reply_count,                # 该条评论下的回复数'spamCount': spam_count,                  # 该条评论被标记为垃圾信息的次数'hasLiked': has_liked,                    # 该条评论是否被你点赞过'canLike': can_like,                      # 该条评论是否可以被点赞'canEdit': can_edit,                      # 该条评论是否可以被编辑'hidden': hidden,                         # 该条评论是否被隐藏'canEmbed': can_embed,                    # 该条评论是否可以被嵌入到其他网页'ranges': ranges,                         # 不知道啥含义'highLightedWords': high_lighted_words,   # 该条评论被高亮的单词'reportURI': report_uri,                  # 举报该条评论的链接'content': content,                       # 该条评论的内容},'author': {'type': author_type,                      # 类型'authorID': author_id,                    # 该条评论作者的 ID'authorName': author_name,                # 该条评论作者的用户名'isVerified': is_verified,                # 该条评论作者是否已认证过'uri': uri,                               # 该条评论作者的 facebook 主页'thumbSrc': thumb_src                     # 该条评论作者的头像链接}}print(comment_result_dict)self.save_comment(self.json_name, json.dumps(comment_result_dict, ensure_ascii=False))# 第二次储存,储存所有二级评论(回复别人的评论,且不用点击“更多回复”就能看见的评论)# 判断依据,是否存在 commentIDstry:reply_ids = comment['public_replies']['commentIDs']self.extract_comment(comment_dict, reply_ids)except KeyError:pass# 第三次储存,储存所有三级评论(回复别人的评论,但是需要点击“更多回复”才能看见的评论)# 判断依据,是否存在 afterCursortry:reply_after_cursor = comment['public_replies']['afterCursor']reply_id = comment_ids[i]reply_url = self.reply_base_url.format(reply_id)self.get_comment(reply_after_cursor, reply_url)except KeyError:passdef run(self) -> None:self.get_app_id()after_cursor = self.get_first_parameter()if len(after_cursor) < 20:print('\n{} 评论采集完毕!'.format(PAGE_URL))else:comment_url = self.comment_base_url.format(self.target_id)self.get_comment(after_cursor, comment_url)print('\n{} 评论采集完毕!'.format(PAGE_URL))if __name__ == '__main__':FC = FacebookComment()FC.run()

【4x00】数据截图

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/437652.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

写第一个spark程序(wordcount)

首先启动集群与spark 其次把spark目录下的README.md上传到hdfs 进入spark下的bin目录&#xff0c;运行spark-shell ./spark-shell运行 val textFile sc.textFile("hdfs://chun1:9000/spark/README.md")val wordCounts textFile.flatMap(line>line.split("…

【中国版Office 365 应用程序注册】

中国版Office 365是由世纪互联进行运营的一个云服务&#xff0c;单纯从技术角度来看的话&#xff0c;它基本保持了与国际版的同步。但是由于两个版本本质上是完全独立的&#xff0c;其中最关键的就是账号系统是分开的&#xff0c;所以从使用角度来看&#xff0c;不管是直接用户…

Python 中如何解决 asyncio 文件描述符最大数量限制问题

文章目录问题复现问题分析事件循环 EventLoopI/O 多路复用select 的缺点解决方法1.更换事件循环选择器2.限制并发量3.修改最大文件描述符限制WindowsLinux总结WindowsLinux问题复现 Windows 平台下&#xff0c;Python 版本 3.5&#xff0c;使用异步框架 asyncio&#xff0c;有…

【转】掀起Azure AD的盖头来——深入理解Microsoft Graph应用程序和服务权限声明

引子 这是一篇计划外的文章。我们都知道要进行Microsoft Graph的开发的话&#xff0c;需要进行应用程序注册。这个在此前我已经有专门的文章写过了。但这里存在一个小的问题&#xff1a;国内版的Office 365在申请好之后&#xff0c;并没有像国际版那样&#xff0c;有一个对应的…

Python3 学习系列 丨 博客目录索引

整个博客有关 Python 学习目录索引&#xff0c;方便快捷定位查询基础学习篇 Python3 基础学习笔记 C01【变量和简单数据类型】Python3 基础学习笔记 C02【列表】Python3 基础学习笔记 C03【操作列表】Python3 基础学习笔记 C04【if 语句】Python3 基础学习笔记 C05【字典】Pyt…

【转】日邮物流:实现智慧物流,这个云上对了!

和阳光、空气、水、网络一样&#xff0c;「物流」早已成为当代企业、个人赖以生存的必要条件。2020第一季度全球物流受疫情影响面临挑战&#xff0c;业内普遍预计全球物流及供应链将重新优化布局。借此时机&#xff0c;物流业纷纷将目光投向“数字化智慧物流”方向&#xff0c;…

Python 实现十大经典排序算法

目录排序算法分类一、冒泡排序&#xff08;Bubble Sort&#xff09;1、原理2、步骤3、动画演示4、代码实现5、具体示例二、选择排序&#xff08;Selection Sort&#xff09;1、原理2、步骤3、动画演示4、代码实现5、具体示例三、插入排序&#xff08;Insertion Sort&#xff09…

【转】Microsoft Graph 桌面应用程序

桌面应用程序&#xff0c;在我这篇文章的语境中&#xff0c;我是特指在Windows桌面上面直接运行的.NET应用程序&#xff0c;包括Console Application&#xff0c;WPF Application&#xff0c;Windows Forms Application, UWP Application&#xff0c;并且限于篇幅&#xff0c;我…

【转】Microsoft Graph Web应用程序极致开发体验

前言 这篇文章最早写于2017年5月2日&#xff0c;当时的想法是从最简单的方式来写如何在一个ASP.NET MVC应用程序中集成Microsoft Graph&#xff0c;但实际上还真不是那么简单&#xff0c;至少我是不满意的&#xff0c;加上这一两周都比较忙&#xff0c;所以这一篇就一直搁置。…

Spark(idea)操作mysql进行查询和插入 (代码+理解)

首先在maven中加入配置 <!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.27</version></dependency>然后在idea配置数据库 1&#xff09; 查询 //1.查询数…

【转】在无人值守程序(服务)中调用Microsoft Graph

什么是无人值守程序&#xff08;服务&#xff09; 我在此前用了几篇文章分别介绍了在桌面应用程序&#xff08;控制台&#xff09;&#xff0c;Web应用程序&#xff08;ASP.NET MVC&#xff09;&#xff0c;以及PowerSehll脚本中如何访问Microsoft Graph&#xff0c;今天这一篇…

【转】使用PowerApps快速构建基于主题的轻业务应用 —— 入门篇

前言 在上一篇文章 基于Office 365的随需应变业务应用平台 中我提到&#xff0c;随着随需应变的业务需要&#xff0c;以及技术的发展&#xff0c;业务应用的开发的模式也有了深刻的变化。基于微软的平台&#xff0c;有服务于主干业务应用的Dynamic 365 业务应用平台&#xff0…

Spark内核源码学习(暂未学完)

1&#xff09; 回顾 1.1 Spark通用运行流程概述 在submit任务条件是需要指定executo个数&#xff0c;executor-CUP个数&#xff0c;可以提高并行度。 什么是并行&#xff0c;什么是并发&#xff1f; 并发&#xff1a;假如有多个任务task&#xff0c;并行是在一个cup中&#x…

【转】使用PowerApps快速构建基于主题的轻业务应用 —— 进阶篇

在上一篇 使用PowerApps快速构建基于主题的轻业务应用 —— 入门篇 中&#xff0c;我用了三个实际的例子演示了如何快速开始使用PowerApps构建轻业务应用&#xff0c;你可能已经发现&#xff0c;我都是使用默认生成的设置&#xff0c;没有做任何修改。当然&#xff0c;那样做出…

Spark一些组件的定义

Driver program: 运行应用程序的main函数并创建SparkContext的进程 除了RDD的最终执行所写的业务逻辑&#xff0c;剩下的都在Driver里生成&#xff0c;Driver端执行action算子才会到开始执行所创建的DAG-RDD图。 Cluster manager&#xff1a; 用于获取集群资源外部服务 Mas…

【转】D365 FO第三方集成(二)---访问认证(获取访问令牌)

D365 FO 在github上发布了第三方访问D365 FO的示例代码&#xff0c;里面包含了各种调用示例&#xff0c;代码很清晰。https://github.com/microsoft/Dynamics-AX-Integration 这篇blog简单分析一下代码中获取访问令牌的部分代码。 与获取访问令牌相关的代码有两个类ClientConfi…

【转】D365 FO第三方集成(三)---服务实现

D365 FO的Custom Service的实现比AX2012简单了很多。 AX2012服务方法要用属性SysEntryPointAttribute标记&#xff0c;添加到Services以后&#xff0c;还要发布服务并在系统管理入站端口添加操作&#xff0c;服务运行在CIL下&#xff0c;所以每次改动服务方法的代码都要增量生成…

PHP连接sql seaver数据库

我的PHP版本7.0 通过sqlsrv系列函数&#xff0c;需要下载安装Microsoft Drivers for PHP for SQL Server驱动&#xff1a; 地址&#xff1a;https://msdn.microsoft.com/library/dn865013.aspx。 根据自己需求下载安装&#xff0c;安装地址php下ext目录下&#xff0c;我的是4.0…

NoSql理解+传统关系型数据库ACID+Nosql的CAP+BASE的理解

1&#xff09;什么是Nosql NoSQL(NoSQL Not Only SQL )&#xff0c;意即“不仅仅是SQL”&#xff0c; 泛指非关系型的数据库。随着互联网web2.0网站的兴起&#xff0c;传统的关系数据库在应付web2.0网站&#xff0c;特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显…

ztree 点击重载 layui table

ztree 点击重载 layui table <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <HTML> <HEAD><TITLE> ztree_demo </TITLE><meta http…