文章日期:2024.12.16
使用工具:Python
本章知识:亚马逊公开数据采集,轻松绕过验证,无需分布式,无需IP池,无需自动化模拟,极其简单
文章难度:低等(没难度)
文章全程已做去敏处理!!! 【需要做的可联系我】
AES解密处理(直接解密即可)(crypto-js.js 标准算法):在线AES加解密工具
仅供学习!仅供学习!仅供学习!
首先,以下几点是我在2022年的时候进行的研究测试。 请勿喷!!
1、亚马逊是有ip封锁机制的,同一个ip访问过多会出现人机验证码。
2、当出现了ip封锁机制时,如果不进行验证,过一会就人机验证就会失效(偶尔性),这时只需要刷新页面既可重新访问页面资源
3、当我请求资源时,将超时时间设置很短,亚马逊会有一定几率自动跳过人机验证,直接返回有资源的数据。
4、(实验)当我在一台电脑,一个ip,开启了50个线程同时采集亚马逊一个数据的时候,他会有20%返回正确资源。但当我开启100个线程访问100个不同的资源时,却能返回80%-100%,这意味着什么,同时并发100个数据,可以有80条-100条可以返回正确数据,那也就是 2秒-5秒 可以返回 80条-100条
下面给大家看一下我采集后的,我采用了【redis+mysql】作为临时数据调用和数据存储
配置是100线程,相当于100个数据同时请求,请求错误的几率很低,通常都是会错10几个,都是属于正常的,请求错误的会放到redis重新请求,如果你看不出来每秒请求的数据量是多少,可以接着往下看
没错请求后的数据会直接保存到mysql,你们可以看mysql数据里的日期那一列,记得看秒,每秒多少数据,我的日期记录是根据数据处理进行记录的,数据从html提取完成的那一刻生成的存储日期,并不是保存mysql的时候生成的新日期
核心代码讲解:
行了,我也不绕弯子,核心代码直接给你们
【核心代码】 此代码已使用2年多,目前任然有效,分享给大家。为了防止大家不懂,我在代码最底部放了演示代码,可以放心实操。代码已去敏
"""
File Name: 亚马逊高效采集核心模块
Author: 小木_.
Date Created: 2022-04-18
Last Modified: 2024-12-16
Version: 3.8
Description: 大批量的采集专用,反头指纹/绕过人机验证/强行采集/强行ip检验(噎死)
"""
import requests
import hashlib
import random
import time
import base64
from concurrent.futures import ThreadPoolExecutor
# base64 解密
def base64_decode(str):
# print(base64.b64decode('MTIz'.encode()))
return base64.b64decode(str).decode('utf-8')
# 这个是链接被base64加密了,此步骤只用于去敏,无其他作用
URL = base64_decode('d3d3LmFtYXpvbi5jb20=')
# 亚马逊专用请求器(可用于请求亚马逊任何数据)
class AMAZON_REQUESTER:
def __init__(self, URL: list):
# URL 只能传列表形式的,链接有多少,并发就有多少,返回的数据请用for循环遍历,返回数据以字典形式返回 列:{'code': 1, 'data': data, 'url': url}
self.URL = URL
# 并发量
self.Concurrent_workload = len(URL)
self.data = self.Collection_Request()
def md5_encrypt(self,string):
'''
'md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512',
'blake2b', 'blake2s',
'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
'shake_128', 'shake_256'
'''
md5 = hashlib.md5()
md5.update(string.encode('utf-8'))
return md5.hexdigest()
# 请求数据-主 直接返回源码
def Collection_Request(self):
def _r(url):
# 此 headers 信息要全,因为亚马逊要读取你的头部,要进行分析,尽可能的不一样
headers = {
"authority": URL,
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
"accept-language": "zh-CN,zh;q=0.9",
"cache-control": "no-cache",
"pragma": "no-cache",
"sec-ch-ua": f"\"Not A(Brand\";v=\"{random.randint(0, 40)}\", \"Brave\";v=\"{random.randint(0, 40)}\", \"Chromium\";v=\"{random.randint(0, 40)}\"", # 随机
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-ch-ua-platform-version":f"\"{random.randint(0, 40)}.0.0\"", # 随机
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "none",
f"{self.md5_encrypt(str(time.time()))[:5]}": f"{self.md5_encrypt(str(random.randint(1, 10000)))}", # 防头部指纹 自行添加
"sec-fetch-user": "?1",
"sec-gpc": "1",
"upgrade-insecure-requests": "1",
"user-agent": f"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/{random.randint(300, 550)}.{random.randint(0, 40)} (KHTML, like Gecko) Chrome/121.0.0.0 Safari/{random.randint(300, 550)}.{random.randint(0, 40)}"
}
# 此cookie用于配置语言 无其他作用 这个cookie直接在网站里复制即可
cookies = {
"session-id": "141-9031760-8975349",
"session-id-time": "2082787201l",
"i18n-prefs": "USD",
"lc-main": "zh_CN",
"ubid-main": "134-0283973-0399727",
"session-token": "7SLAeUSiRPgkWG535jiReL52H1RqiEIo9InLcmg3RLjBCAbVEb9fH8RoJ2N9ozzpja5OkRGz+edoQKlu5QtFXKyZQJ1pxzJOn8cRByul0DWIifymcLAMMlHEjZRVIoQd35Dz6XerVWD57LTphmUE/HpWpb2kzFmzhIXUVaULv3AQ3FZHxqIVWbBC6t0joZ4uAgjkq/1ZWOgz1rSbKegDgcmpF9Pm7cDebnqfB+GJCRtWpZfxWR+ltrRvhJZHN1Wk5RqRJPxwtDeHzkUD7ZeptbYHVhfN+NoapEVLd1WdR3TvnKfnf2xWQNbg4e+Jsqi6dnARl1mD4HEF4DbcUaE7SSsW8KuMe2A/",
"csm-hit": "tb:PQN1JJ125JMAWP1N81RS+s-PQN1JJ125JMAWP1N81RS|1734339863183&t:1734339863183&adb:adblk_no"
}
try:
# 请求
response = requests.get(url, headers=headers, cookies=cookies, timeout=4)
# 检测有没有人机,如果代码存在【sp:end-feature:csm:body-close】说明当前页面请求失败,遇到人机验证了,则将链接放回redis重新请求
if 'sp:end-feature:csm:body-close' in str(response.text):
# 将数据进行处理,使用正则提取
data = response.text.replace('\n', '').replace('\t', '').replace('\f', '').replace('\r', '')
return {'code': 1, 'data': data, 'url': url}
return {'code': 0, 'url': url}
except Exception as e:
# 请求出错
return {'code': 0, 'url': url}
# 创建线程
with ThreadPoolExecutor(max_workers=self.Concurrent_workload) as pool:
return pool.map(_r, self.URL)
# 导入当前模块 外都直接导入此模块
__all__ = ['AMAZON_REQUESTER']
'''
###### 演示 ######
# 链接列表,最多高100个链接,最少50个是最效率的,主要是根据电脑性能自行分配
url_list = [f'https://{URL}/dp/B07SJBR8YW',f'https://{URL}/dp/B0CQ553W85',f'https://{URL}/dp/B0C2MG4CMT']
# 将链接列表传递进去并实例化,实例化的时候会自动请求并采集
AMAZON_data_list = AMAZON_REQUESTER(URL=url_list)
# 获取数据,这个时候数据需要通过for循环提取,
for data_dict in AMAZON_data_list.data:
# 数据也是字典状态,需要提取
# 请求成功 {'code': 1, 'data': ...html数据.., 'url': '当前请求的链接'}
# 请求失败 {'code': 0, 'url': '当前请求的链接'} 失败的可以将url重新放回队列,重新请求,用redis更好
print(data_dict)
'''