爬虫瑞数4案例:网上房地产

2024-01-08 07:12

本文主要是介绍爬虫瑞数4案例:网上房地产,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

声明:
该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关

一、瑞数简介

瑞数动态安全 Botgate(机器人防火墙)以“动态安全”技术为核心,通过动态封装、动态验证、动态混淆、动态令牌等技术对服务器网页底层代码持续动态变换,增加服务器行为的“不可预测性”,实现了从用户端到服务器端的全方位“主动防护”,为各类 Web、HTML5 提供强大的安全保护。

二、瑞数特点
  1. 会有多层debugger,可以点击Never pause here过掉debugger
  2. 会有多次请求
  • 瑞数4、瑞数5有两次相同的请求,瑞数4第一个请求状态码202,瑞数5第一个请求状态412,第一次请求响应的html,会有个script标签外链js加载 t s = w i n d o w [ ′ _ts = window[' ts=window[_ts’],外链js代码可以固定,也可以通过对外链js发送请求获取js代码
  • 瑞数5.5有两次相同的请求,第一次请求状态码412,响应的html有外链js,此外链js代码可以固定,也可以通过对外链js发送请求获取js代码
  • 瑞数6和瑞数5.5编译过程差不多
  1. 第一次响应的html,都会包含动态加载的meta标签包含content、两个script标签,
  • 瑞数4、瑞数5用第一个script加载包含_ts = window[‘$_ts’]的js文件,第二个script加载一段自执行的js,用于把之前加载的代码处理成可用的js代码,处理后的js字符串,通过call执行,并生成cookie
  • 瑞数5.5用第一个script加载包含_ts = window[‘$_ts’]代码,第二个script加载自执行js文件,用于把之前加载的代码处理成可用的js代码,处理后的js字符串,通过call执行,并生成cookie
  1. 都会有特有的cookie标识
  • 瑞数4:FSSBBIl1UgzbN7N80T,生成值的第一个字符就是代数
  • 瑞数5:IdlEqTWW2ERnT,生成值的第一个字符就是代数
  • 瑞数5.5:1EzPGwRUoQaWT,生成值的第一个字符就是代数
  1. 瑞数会检测当前执行的文件是哪一个,可以使用delete __filename、delete __dirname
三、瑞数4特点
  1. 两层debugger,可以点击Never pause here过掉debugger
  2. 同一个请求两次
  3. 第一次请求失败,状态码是202
  • 首先会生成一个js文件: t s = w i n d o w [ ′ _ts = window[' ts=window[_ts’],代码可以固定
  • 然后响应返回一个html页面,里面会有动态加载的meta标签包含content、一个script标签加载刚才js文件、一段script标签包含的js代码
  • 这段js代码是个自执行方法,会把之前的js代码,转换成可用的js代码,并通过call方法执行eval函数生成vm文件,在vm文件生成cookie,赋值给document.cookie
  • 响应的cookie名字是:FSSBBIl1UgzbN7N80S
  1. 第一次请求js代码生成的 cookie的名字是:FSSBBIl1UgzbN7N80T,生成值的第一个字符就是代数
  2. 第二次请求,会正确拿到数据
四、找出需要加密的参数
  1. js运行 atob(‘aHR0cDovL3d3dy5mYW5nZGkuY29tLmNuL2luZGV4Lmh0bWw=’) 拿到网址,F12打开调试工具(打开F12会遇到无限debugger,这是个eval执行的debugger,右击左侧代码行点击Never pause here过掉即可),找到 index.html 请求(状态200),鼠标右击请求找到Copy>Copy as cUrl(cmd)
    在这里插入图片描述
  2. 打开网站:https://spidertools.cn/#/curl2Request,把拷贝好的curl转成python代码,新建 fdc.py,把代码复制到该文件
    在这里插入图片描述
  3. 多运行几次jdc.py,会发现请求失败,状态码是202,仔细分析cookie会发现FSSBBIl1UgzbN7N80S、FSSBBIl1UgzbN7N80T,而FSSBBIl1UgzbN7N80T值得第一个字符是4,这是瑞数特点之一,字符4代表是瑞数4代
    在这里插入图片描述
  4. 新建fdc.js,用于放扣下的代码
五、瑞数4 cookie 分析
  1. 使用hook定位FSSBBIl1UgzbN7N80T,参数生成位置,这里我使用的是油猴
    在这里插入图片描述
  2. 编辑好油猴脚本,启动该脚本,切换到Application,清除浏览器的cookie,一定要清除cookie
    在这里插入图片描述在这里插入图片描述
  3. 清除cookie后,刷新页面后会进入油猴脚本里的debugger,一直点击跳过当前函数执行,就会找到FSSBBIl1UgzbN7N80T赋值的地方
    在这里插入图片描述在这里插入图片描述
  4. 分析FSSBBIl1UgzbN7N80T赋值的地方,会发现是在_KaTeX parse error: Expected group after '_' at position 9: Jo函数中,搜索_̲Jo会找到调用该函数的几个地方全部打上断点,点击跳过断点,会进入其中的一个断点。注意这是个虚拟文件,每次生成的都不一样,需结合当前代码分析
    在这里插入图片描述在这里插入图片描述
  5. 分析右侧的堆栈,找到不属于该虚拟文件的栈,分别点击查看会发现一个call方法,该方法就是生成虚拟文件的地方,这个文件是第一次请求的响应结果
    在这里插入图片描述
  6. 使用无痕窗口打开网站,F12打开调试工具,点击Never pause here过掉debugger,再点击sources,找到事件监听勾选script
    在这里插入图片描述
  7. 切换到Application,清除浏览器的cookie,一定要先清除cookie,清除cookie后,刷新页面,会看到一个js文件,这是第一次请求生成的,把这个文件代码全部拷贝到fdc.js
    在这里插入图片描述
  8. 点击跳过断点,会进入一个html文件,这个html文件就是刚才找到call方法的文件,分析文件会发现一个meta标签、一个script标签引入了刚才生成的js、还有一个script标签里面有很多代码,代码用于把之前的js转换成可用的js代码,把该js全部拷贝到fdc.js
    在这里插入图片描述
  9. 在该文件搜索.call,会找到一个.call方法执行,在该行打上断点
    在这里插入图片描述
  10. 点击跳过断点,鼠标悬浮到call方法参数上上会发现很多js字符串,这就是经过该自执行方法转换后的js,就是之前分析的虚拟文件执行的js
    在这里插入图片描述
  11. 这里要注意虚拟文件是动态生成的,每次获取到的都是不一样的,为了方便调试,把html文件替换成本地文件,这样每次生成的虚拟文件就是一样的,右击该html文件名称,点击Override content,如果替换成功后代码都在一行,可以在本地找到该文件,用编辑器打开,格式化一下,并在call的位置打上断点
    在这里插入图片描述在这里插入图片描述
  12. 把script中的自执行方法全部拷贝到fdc.js,运行fdc.js,会发现报window的错误,window是浏览器环境的,node环境不存在,接下来开始补环境
    在这里插入图片描述
六、补环境
  1. 首选在代码顶部补上window环境,并用代理自动把需要补的环境吐出来,新建jsProxy.js把下面代码拷贝过去
// 代理器封装
function getEnv(proxy_array) {for(var i=0; i<proxy_array.length; i++){handler = `{\nget: function(target, property, receiver) {\nconsole.log('方法:get','    对象:${proxy_array[i]}','    属性:',property,'    属性类型:',typeof property,'    属性值类型:',typeof target[property]);return target[property];},set: function(target, property, value, receiver){\nconsole.log('方法:set','    对象:${proxy_array[i]}','    属性:',property,'    属性类型:',typeof property,'    属性值类型:',typeof target[property]);return Reflect.set(...arguments);}}`;eval(`try{\n${proxy_array[i]};\n${proxy_array[i]} = new Proxy(${proxy_array[i]},${handler});}catch(e){\n${proxy_array[i]}={};\n${proxy_array[i]} = new Proxy(${proxy_array[i]},${handler});}   `)}
}// proxy_array = ['window', 'document', 'location', 'navigator', 'history','screen','target' ]
// getEnv(proxy_array)module.exports = getEnv

在这里插入图片描述

  1. 运行fdc.js,会发现在获取window.top时报错了,在控制台输出window.top得知 window.top = window,在代码顶部补上window.top
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

  2. 运行fdc.js,会发现在获取document.createElement时报错了,document.createElement是用来创建标签的,在代码顶部补上document.createElement,之所以return出一个json,是因为标签也是一个对象
    在这里插入图片描述在这里插入图片描述

  3. 运行fdc.js,会发现在获取document.createElement时又报错了,创建的标签是div,找到打印信息最后的位置,会看到报错代码
    在这里插入图片描述在这里插入图片描述

  4. 在浏览器call断点处,点击进入该方法内部会找到虚拟文件,在虚拟文件内搜索KaTeX parse error: Expected group after '_' at position 4: Wb[_̲By[93]],会找到该方法的位置,在该行打上断点,点击跳过断点,会进入刚才的断点,把代码信息在控制输出,会发现是获取div下的i标签,获取出的结果是 length:0,在代码顶部补上该代码
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  5. 运行fdc.js,会发现在获取window.attachEvent时报错了,找到打印信息最后的位置,会看到报错代码,在虚拟文件内搜索KaTeX parse error: Expected group after '_' at position 3: z[_̲By[95]],会找到该方法的位置,在该代码处有个判断,在if和else中都打上断点,点击跳过断点,if断点,把代码信息在控制输出,会发现是window.addEventListener,获取出的结果是 undefined,在代码顶部补上该代码
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  6. 运行fdc.js,会发现在获取document.getElementsByTagName时报错了,找到打印信息最后的位置,会看到报错代码,在虚拟文件内搜索KaTeX parse error: Expected group after '_' at position 4: 77[_̲By[93]],会找到多个该方法的位置,在所有的KaTeX parse error: Expected group after '_' at position 4: 77[_̲By[93]]打上断点,点击跳过断点,会进入某一个断点,打印出信息,会发现是两个meta对象和length,在代码顶部补上代码
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  7. 运行fdc.js,会发现在获取document.getElementsByTagName时又在报错了,报错信息是缺少removeChild属性,点击跳过当前函数执行,分析刚才断点的代码,会发现需要最后一个meta上的content属性、parentNode.removeChild,其中parentNode.removeChild是用来移除标签,所以不用有返回值,在代码顶部补上代码
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

  8. 重复运行fdc.js,按照上面的方法补全环境

  9. 补完环境,修改fdc.js,再运行,会发现已经拿到FSSBBIl1UgzbN7N80T
    在这里插入图片描述

七、python代码验证结果
  1. 修改fdc.js,因为meta中的content、还有js代码都是动态生成的,所以要用字符暂时占位,分别注释掉之前content的值和js,用meta_content、js_code代替
    在这里插入图片描述在这里插入图片描述
  2. 修改fdc.py
    在这里插入图片描述在这里插入图片描述
  3. 点击运行fdc.py,会发现第二个请求报400,那是因为瑞数会检测当前执行的文件是哪一个
    在这里插入图片描述
  4. 修改fdc.js,再运行fdc.py,会发现数据获取成功
    在这里插入图片描述在这里插入图片描述
八、最终代码
  1. fdc.js,代码太多只贴补环境的那块儿
delete __dirname
delete __filenamevar getEnv = require('./jsProxy')//补window环境
window = global
window.top = window
window.addEventListener = function (event) {console.log('window中的addEventListener接受的值:', event)
}//补document
div = {getElementsByTagName: function (res) {console.log('div中的getElementsByTagName接受的值:', res)if (res == 'i') {return {length: 0}}}
}meta = {0: {},1: {// content: '{qqiWR9xjADLqtZr.GKDUqs39vLCd6fuDojxTsXPqq|[MOVUqGS9kDwYAY2MHmG8qqenYagvFTYnqaVRkcNykUE2QpL1UOm3DmV.UaxMHf24DULSwPQ.o1WoFaQ0osgoFcNzHGWFl1x7iueMEnWPYsGUinpbxrEUmkAWiA36crg6r1VwErNIEG9BVaVFkaqEkf9kra7lrS9tYs3eEPaaxSeIEA9HkkfRiYYWHS7gkPZdkrEPtnQwYs3.eahnr50RXqCjtH09dcbnU7yq4AOBU4TRXVkvoMVtL1OLxi7NNT4YAHqEZm5GKFxqZfCPrWTwLGBbkWL54mK.oiLLSmOEEieM2f_8iwg4amB1DX0kaTVQrgEnzs8CJMW67uDuJ.35XOKaH.0ac80{AVhRPOD1oF7LTncUsEzy56uo8iJ7aOK.T3d7d7kbbH.qS7sbNHjwPZbUgFjASBsb.WM9dBo_PH_LpL1cfl4096k162hsQioxBGHtAihVlwBPeCtEe8.qfQg.wHVg9MepzcbGPT1sAl.orvE_e5EwA2MzQ9Wbt9r1r0r4q!x7z,aac,amr,asm,avi,bak,bat,bmp,bin,c,cab,css,csv,com,cpp,dat,dll,doc,dot,docx,exe,eot,fla,flc,fon,fot,font,gdb,gif,gz,gho,hlp,hpp,htc,ico,ini,inf,ins,iso,js,jar,jpg,jpeg,json,java,lib,log,mid,mp4,mpa,m4a,mp3,mpg,mkv,mod,mov,mim,mpp,msi,mpeg,obj,ocx,ogg,olb,ole,otf,py,pyc,pas,pgm,ppm,pps,ppt,pdf,pptx,png,pic,pli,psd,qif,qtx,ra,rm,ram,rmvb,reg,res,rtf,rar,so,sbl,sfx,swa,swf,svg,sys,tar,taz,tif,tiff,torrent,txt,ttf,vsd,vss,vsw,vxd,woff,woff2,wmv,wma,wav,wps,xbm,xpm,xls,xlsx,xsl,xml,z,zip,apk,plist,ipaqqqqqqqqqqqqqqkRxA1WYW8i2ZaYc0IH9V_UAlwSf3|gYBRPSpKnWLGmzpn1RFgTvfn.WMN2nKrBqVWPwqrME6aBAcYAxK7XifNgJ9qoIDrOhYVmscevR1Qa3rJyk2QrpCg4rYlO8OZfH6qvFCY8H209hArJH6q1VnpSrlaPkAxixrTXpaEYh2ZXAfJ4JoABM1TUmKV0p1w6lTaAFbYgEArBRbVr393oFOmsRvqi8DwDEYpOFkzaRuL9ECQFHfAFhcyeEqLuhcQr3al2qpe5oO7YraggcozOmq06MaQaWcW5HOqD3aEPhnL4hrVNECWVlGqJ3C0IMkzUomlrq 0wR7HvJ6IsUC410DntKRngA;QyqA82EGtIB6ePNEeYo9NG;iEm6gdSTTpYiqU10OlvsnG;yMG8gk5okQ97gP4eb.IadA;T8F36FaS9AtR4sXBkRr0iG;RTlM3IYjAzboXbIiNSIFRA;t7_svh3Kc3.VU9jOjAJgdq;.8D9Zx78FrKF.Zn4xbfmIG;IMhCM7gXESIqShs5TNMo9A;pvBPF7OtrK6trS5vZYizwa;9qxqLXuEeDQeAlNfAL_l.A;VNeyFcNDtQZhV2sfCxyHqA;kT4JL2WRSOhvUIEcOjSrva;LpFhLGWYI8eFx_X999MLEq;NqssQaVItFB0TevtNxJrkG;AI3RN3R7lP0BBnYsoCO5KG;xrYRhwM6FYW7zCsPL.iecq;0kOXzZzt1eXLrlPo.QQ4xG;ApKNqLIRoybF5rIxSnabBG;hfgZrtz_KscdFC6a3f1wKA;Ddfe167m26649h_g.S8UKVgXBt1074790432r0YQLJiVGhVajrMQpjFqUZuNqV80Tt89zds6ycR9fGsCNkl3650r0q}!DBEbb61kMgq_GKiDIZLg9oiwINe0CsjYI7qgLVKAwKS03oewpcl4FvNLIO7y1Tff8kgLIo2mtKfXR6JJw6Y_YTwPJKJxRTp2FUNdsvSGFU2gYvm7YUlP16wcwTJjWYNC36rssnfssmwnM0eVKbYnVvZFwTxcov2N1Dx0MKEKUCfl1YLAi0Y_KDyAxfA7VnfnQ9fZKcfIsvwaIDWDEvy5tmVaiUaqqqqqqqqqqqqqq',content:'meta_content',parentNode: {removeChild: function (tag) {console.log('meta中的removeChild接受的值:', tag)}}},length: 2
}script = {0: {getAttribute: function (attr) {if (attr == 'r') {return 'm'} else {console.log('script-0中的getAttribute接受的值:', attr)}},parentElement: {removeChild: function (tag) {console.log('script-0中的removeChild接受的值:', tag)}}},1: {getAttribute: function (attr) {if (attr == 'r') {return 'm'} else {console.log('script-1中的getAttribute接受的值:', attr)}},parentElement: {removeChild: function (tag) {console.log('script-1中的removeChild接受的值:', tag)}}},length: 2
}document = {createElement: function (tag) {if (tag == 'div') {return div} else {console.log('document中的createElement接受的值:', tag)return {}}},getElementsByTagName: function (tag) {if (tag == 'meta') {return meta} else if (tag == 'script') {return script} else {console.log('document中的etElementsByTagName接受的值:', tag)return {}}},addEventListener: function (event) {console.log('addEventListener中的addEventListener接受的值:', event)}
}//补location
location = {"href": "http://www.fangdi.com.cn/index.html","origin": "http://www.fangdi.com.cn","protocol": "http:","host": "www.fangdi.com.cn","hostname": "www.fangdi.com.cn","pathname": "/index.html",
}proxy_array = ['window', 'document', 'location', 'navigator', 'history', 'screen', 'target']
getEnv(proxy_array)setTimeout = function () {}
setInterval = function () {}
  1. fdc.py
import requests
from lxml import etree
import execjsheaders = {"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.7","Accept-Language": "zh-CN,zh;q=0.9","Cache-Control": "no-cache","Pragma": "no-cache","Proxy-Connection": "keep-alive","Referer": "http://www.fangdi.com.cn/index.html","Upgrade-Insecure-Requests": "1","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
}
cookies = {# "FSSBBIl1UgzbN7N80S": "GkMvOPOR2zBCVsQEB.kvrp8c09MaBt9Z4z5v2kzr4OF3jgytrI0CcP_CLbjb7aVH","www.fangdi.com_http_ic": "www.fangdi.com.cn_80_RS",# "FSSBBIl1UgzbN7N80T": "4XQnYs.FW_Xmfaz6PD8YA3Rx1mZj6pwxCz1eI7_4lZ5RLbw_KslOYk3h1a3wTBpJP5x5.vhgimumrTaVMAUJgrBWaQy5_GMTE74VTNzdCmViki0eYwajPW7AGFKvVbgOvfxgn8IzQedPz_fsXY46XQAcEaO_IcySZDrjaqAFG3PHcR8AOjRd9ujI3sHLpPVOPWjWqpKn2fvsKW2lOMCs2fuBHyTBXZz93X4wtriC8l8eYYbaA3oP5AxLasmnWfK15309X9vVSdbuwE64nXt8QWQ5XvaajzXt8wy_oMCH9OmfQGBmvwku0cgzu7xOioFuNqZOW6YFZUb1HOJxVgzi1CjlK"
}request_session = requests.session()
request_session.headers.update(headers)
request_session.cookies.update(cookies)
url = "http://www.fangdi.com.cn/index.html"def get_code():response = request_session.get(url)cookies['FSSBBIl1UgzbN7N80S'] = response.cookies['FSSBBIl1UgzbN7N80S']request_session.cookies.update(cookies)html = etree.HTML(response.text)meta_content = html.xpath('//meta[2]/@content')[0]js_code = html.xpath('//script[2]/text()')[0]return meta_content,js_codemeta_content,js_code = get_code()with open('fdc.js', 'r', encoding='utf-8') as js_file:js_text = js_file.read()js_text = js_text.replace('meta_content', meta_content)js_text = js_text.replace("'js_code'", js_code)js = execjs.compile(js_text)cookies['FSSBBIl1UgzbN7N80T'] = js.call('main')request_session.cookies.update(cookies)response = request_session.get(url)
response.encoding = 'utf-8'
print(response.text)
print(response)

这篇关于爬虫瑞数4案例:网上房地产的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/582670

相关文章

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

Java 正则表达式的使用实战案例

《Java正则表达式的使用实战案例》本文详细介绍了Java正则表达式的使用方法,涵盖语法细节、核心类方法、高级特性及实战案例,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录一、正则表达式语法详解1. 基础字符匹配2. 字符类([]定义)3. 量词(控制匹配次数)4. 边

Python Counter 函数使用案例

《PythonCounter函数使用案例》Counter是collections模块中的一个类,专门用于对可迭代对象中的元素进行计数,接下来通过本文给大家介绍PythonCounter函数使用案例... 目录一、Counter函数概述二、基本使用案例(一)列表元素计数(二)字符串字符计数(三)元组计数三、C

Spring Boot 整合 SSE(Server-Sent Events)实战案例(全网最全)

《SpringBoot整合SSE(Server-SentEvents)实战案例(全网最全)》本文通过实战案例讲解SpringBoot整合SSE技术,涵盖实现原理、代码配置、异常处理及前端交互,... 目录Spring Boot 整合 SSE(Server-Sent Events)1、简述SSE与其他技术的对

MySQL 临时表与复制表操作全流程案例

《MySQL临时表与复制表操作全流程案例》本文介绍MySQL临时表与复制表的区别与使用,涵盖生命周期、存储机制、操作限制、创建方法及常见问题,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小... 目录一、mysql 临时表(一)核心特性拓展(二)操作全流程案例1. 复杂查询中的临时表应用2. 临时

MySQL 数据库表与查询操作实战案例

《MySQL数据库表与查询操作实战案例》本文将通过实际案例,详细介绍MySQL中数据库表的设计、数据插入以及常用的查询操作,帮助初学者快速上手,感兴趣的朋友跟随小编一起看看吧... 目录mysql 数据库表操作与查询实战案例项目一:产品相关数据库设计与创建一、数据库及表结构设计二、数据库与表的创建项目二:员

C#中的Drawing 类案例详解

《C#中的Drawing类案例详解》文章解析WPF与WinForms的Drawing类差异,涵盖命名空间、继承链、常用类及应用场景,通过案例展示如何创建带阴影圆角矩形按钮,强调WPF的轻量、可动画特... 目录一、Drawing 是什么?二、典型用法三、案例:画一个“带阴影的圆角矩形按钮”四、WinForm

setsid 命令工作原理和使用案例介绍

《setsid命令工作原理和使用案例介绍》setsid命令在Linux中创建独立会话,使进程脱离终端运行,适用于守护进程和后台任务,通过重定向输出和确保权限,可有效管理长时间运行的进程,本文给大家介... 目录setsid 命令介绍和使用案例基本介绍基本语法主要特点命令参数使用案例1. 在后台运行命令2.

RabbitMQ消费端单线程与多线程案例讲解

《RabbitMQ消费端单线程与多线程案例讲解》文章解析RabbitMQ消费端单线程与多线程处理机制,说明concurrency控制消费者数量,max-concurrency控制最大线程数,prefe... 目录 一、基础概念详细解释:举个例子:✅ 单消费者 + 单线程消费❌ 单消费者 + 多线程消费❌ 多

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更