【🏠作者主页】:吴秋霖
【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python与爬虫领域研究与开发工作!
【🌟作者推荐】:对爬虫领域以及JS逆向分析感兴趣的朋友可以关注《爬虫JS逆向实战》《深耕爬虫领域》
未来作者会持续更新所用到、学到、看到的技术知识!包括但不限于:各类验证码突防、爬虫APP与JS逆向分析、RPA自动化、分布式爬虫、Python领域等相关文章
作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者无关!如有侵权,请联系作者本人进行删除!
1. 写在前面
电商系列有多难,做过的小伙伴应该都非常的清楚!其中解决算法只是入场券,核心难点当然是风控系统!作者虽没有实际的业务场景,但是在研究分析与测试的过程中能够感受到强度!尤其是在对IP、账号、行为的硬控堪称为精准
分析目标:
aHR0cHM6Ly93d3cudGVtdS5jb20vYmdjX2NvbW1lbnRzLmh0bWw/Z29vZHNfaWQ9NjAxMDk5NTEyMzAyNTk5Jm1hbGxfaWQ9NTAyNjE0Njg3NiZfeF9zZXNzbl9pZD0zdGF0cTA5d202JnJlZmVyX3BhZ2VfbmFtZT1nb29kcyZyZWZlcl9wYWdlX2lkPTEwMDMyXzE3MTc4MjMxMDk4NzFfeGNwc254Zng2bSZyZWZlcl9wYWdlX3NuPTEwMDMy
2. 接口分析
首先在打开网站的第一步,需要准备一个优质的IP环境,已保障网络是可以正常访问的。不然的话就会出现下面这样的情况,如下所示:
直接看头部参数,还是这个Anti-Content,目前作者分析大部分还有有区别的,但是一个站点基本是通用的。区别就在于是否含轨迹参与了加密,如下所示:
这个验证码虽然说出的不是很频繁,但是在持续抓取的道路上一定是一道坎!如下所示:
这里的也是一个坑,由于作者前期是采用的登录方式去调试的。导致算法没有扣全(但是能用)就去尝试抓取测试,导致账号被风控后所有页面的内容被限制浏览!如下所示:
3. 数据爬取
temu的网站其实从分析到扣JS算法,跟作者之前分析过的达人端流程相差无几达人端是700多位含轨迹。接下来直接搜索关键词参数,断点跟进,如下所示:
这里有一个关键的环境点需要补,就是referer。完整的环境头可以直接拿去使用,如下所示:
(function(global, cookie, href, ua) {
const random = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);
const eventMap = new Map();
class DeviceMotionEvent {}
class DeviceOrientationEvent {}
const documentMock = {
cookie: cookie,
onmousewheel: "",
get referrer() {
return "";
},
addEventListener: (e, t) => eventMap.set(e, t),
getElementById: () => {},
get ontouchstart() {
return null;
},
get documentElement() {
return { scrollTop: 12 };
}
};
const historyMock = {
back: () => {},
toString: () => "function back() { [native code] }"
};
const localStorageMock = {
getItem: () => null,
setItem: () => {}
};
const locationMock = {
get href() {
return href;
},
get port() {
return "";
}
};
const navigatorMock = {
hasOwnProperty: () => false,
get languages() {
return ["zh-CN", "zh"];
},
get plugins() {
return { length: 4 };
},
get userAgent() {
return ua;
}
};
const screenMock = {
get availHeight() {
return 1040;
},
get availWidth() {
return 1920;
}
};
global._event_map = eventMap;
global.DeviceMotionEvent = DeviceMotionEvent;
global.DeviceOrientationEvent = DeviceOrientationEvent;
global.chrome = {};
global.document = documentMock;
global.history = historyMock;
global.localStorage = localStorageMock;
global.location = locationMock;
global.navigator = navigatorMock;
global.outerHeight = 1040;
global.outerWidth = 1920;
global.screen = screenMock;
global.history.back.toString = historyMock.toString;
global.document.getElementById.toString = () => "native code";
})(typeof window !== "undefined" ? window : global, "{cookie}", "{href}", "{ua}");
这里JS内参数Cookie、UA、Referer采用的动态替换的方式调用传递,这样的方式更加的便捷,在Python程序中代码如何去实现?如下所示:
import execjs
# 调用JS算法示例
def generate_anti_content(cookie_str, referer, user_agent):
try:
with open("anti_content_temu.js", "rb") as f:
js_code = f.read()
node = execjs.get()
js_code = js_code.decode("gbk", 'ignore').replace("{cookie}", cookie_str).replace("{href}", referer).replace("{ua}", user_agent)
if cookie_str not in js_code or user_agent not in js_code:
raise Exception("未替换成功")
ctx = node.compile(js_code)
return ctx.call('get_anti_content')
except Exception as e:
logger.error(f"生成Anti-Content失败: {e}")
raise
目前的话我们在抓取的时候是可以不需要去登录账号的,这就很友好了。我们在控制台将Cookie信息拿出来即可,因为Cookie信息也是需要参与加密的,如下所示:
算法如果有问题的话在请求的时候会得到下面的错误反馈,如下所示:
{'success': False, 'error_code': 40002, 'error_msg': 'System busy! '}
还有一种情况则是账号或者参数出现风控或异常,则会出现下面的错误反馈,如下所示:
{'error_code': 406008, 'error_msg': ''}
最后,测试一下扣出来的最终算法,可以看到加上轨迹验证与核心参数之后的长度在500+,基本上就是正确的了!商品评论详情抓取测试效果如下所示:
JS算法的话在每一次请求都调用生成最新的。切记生成一次多次去使用!最后,作者也是测试了一下商品的评价分类,如下所示:
经过了十多分钟控制策略的测试,发现还是非常稳定的。未出现验证,因为咱们使用的Cookie本身就是非登录的,主要就是测试验证码弹出的风控或者强制要求登录等问题!作者也是顺带着验证了一下商品信息与搜索均是没有问题的,证明所有的接口Anti-Content的算法是通用的~~