前几天一位朋友分享了一个福利网站,让我帮忙批量下载文件。本着互帮互助的精神,正好练习一下两年前学完就忘的爬虫知识
严重声明 本文的意图只有一个就是通过分析网站学习更多的逆向技术,如果有人利用本文知识和技术进行非法操作进行牟利,带来的任何法律责任都将由操作者本人承担,和本文作者无任何关系,最终还是希望大家能够秉着学习的心态阅读此文。
Python相关下载就不做多描述了
直接进入首页,打开开发者工具
很容易定位到每一个福利和翻页的位置
进入单个福利下载位置,点击下载,得到请求
其实就是第一个请求进行校验后,第二个就是GET请求下载,所以着重是第一个请求
先直接Postman跑一下,确定参数和有无header
可以看到就三个参数
第一个请求直接查看Initiator面板中的请求调用栈。
找到关键调用位置
对应到页面上就是
参数就在页面js中声明了
下面就用python来搞一下
from urllib.error import HTTPError
import requests
from bs4 import BeautifulSoup
import re
import json
import decode
def getTest(url):
kv = {'user-agent': 'Mozilla/5.0'}
res = requests.get(url, kv)
page = BeautifulSoup(res.text, 'html.parser')
#查找页面每一个资源地址
items = page.find_all(class_='waitpic')
for item in items:
#资源地址
print(item.parent['href'])
#截取地址的id
pid=re.findall(r"\d+?\d*",item.parent['href'])[0]
res1 = requests.get(item.parent['href'], kv)
#资源详情页面
one = BeautifulSoup(res1.text, 'html.parser')
#下载按钮
Mypassdown=one.find('a', class_='Mypassdown')
if Mypassdown is None:
continue
data_down = Mypassdown.get('data-down')
body = {'pid': pid, 'down': data_down,'action':'Post_down_ajax'}
check=requests.post('https://www.第一个请求地址.xyz/wp-admin/admin-ajax.php',body)
result=json.loads(check.text)
if result is not None:
print(result)
#下一页
next=page.find(class_='next page-numbers')
if next is None:
pass
else:
url = (next['href'])
getTest(url)
if __name__ == '__main__':
url="https://www.福利.xyz/"
getTest(url)
以上就实现了每一页资源的自动请求,请求完成后翻页。
执行后就是统一的校验通过,并得到data数据
再来看校验的js代码中,post请求结束后执行了MYdownresult(result);,所以直接看MYdownresult的逻辑
可以看到就是拿到data数据解析后使用Cx_urlopen函数进行下载。所以直接分析$.CxJM.atob函数
既然得到了以上js,其实可以直接使用在线运行工具看效果
可以看到运行后直接解析出了我们想要的地址
下面就直接分析解密逻辑得到python代码就可以了
import re
def i(a,c,d) :
jisuan="".join(a)
g = 0
index = 0
i = len(jisuan)
j = ""
k = 0
l =0
m=0
while ( i > index):
l = ord(jisuan[index])
if(256 > l ):
l=(d[l])
else:
l=-1
g = (g << 6) + l
k += 6
while (k >= 8 ):
k -= 8
m = g >> k
j += c[m]
g ^= m << k
index+=1
return j
def decode(data):
data=data.replace("*!agf", "=")
data=data.replace("&a^f", "b")
b = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
c = ""
d = [-1] * 256
e = [-1] * 256
f = 0
h = ""
for num in range(0,256):
f=num
h = chr(f)
c+=str(h)
e[f] = f
try:
d[f] = b.index(str(h))
except:
d[f] =-1
data="".join(re.findall('[a-zA-Z0-9]+', data, re.S))
return (i(data,c,d))
直接在main中引用并执行decode.decode(result[‘data’])
完整代码如下:
from urllib.error import HTTPError
import requests
from bs4 import BeautifulSoup
import re
import json
import decode
def getTest(url):
kv = {'user-agent': 'Mozilla/5.0'}
res = requests.get(url, kv)
page = BeautifulSoup(res.text, 'html.parser')
#查找页面每一个资源地址
items = page.find_all(class_='waitpic')
for item in items:
#资源地址
#print(item.parent['href'])
#截取地址的id
pid=re.findall(r"\d+?\d*",item.parent['href'])[0]
res1 = requests.get(item.parent['href'], kv)
#资源详情页面
one = BeautifulSoup(res1.text, 'html.parser')
print(one.title.text)
#下载按钮
Mypassdown=one.find('a', class_='Mypassdown')
if Mypassdown is None:
continue
data_down = Mypassdown.get('data-down')
body = {'pid': pid, 'down': data_down,'action':'Post_down_ajax'}
check=requests.post('https://www.第一个请求地址.xyz/wp-admin/admin-ajax.php',body)
result=json.loads(check.text)
if result is not None:
#print(result)
if result['status'] == 1:
print(decode.decode(result['data']))
#下一页
next=page.find(class_='next page-numbers')
if next is None:
pass
else:
url = (next['href'])
getTest(url)
if __name__ == '__main__':
url="https://www.福利.xyz/"
getTest(url)
运行效果如下,过多的标题不敢截
至此解决资源下载路径问题,下载的话,直接拿到浏览器下载或者网上找python下载代码即可
总结
之前也就学过一点点python和js的皮毛,通过代码的粗略程度也能知道。也就知道哪个库是解析的,哪个库是请求的,都是一边搜索一边写。一开始并没想分析网页的点击请求,因为下载地址都是zip/2021/01/10/9592.zip这种格式,很明显是拼接的年月日,而且资源详情页有预览图的地址就有这个年月,我可以直接遍历1-31拼接后得到url,通过request后的status是否是200来判断这个url是否有效。但如此一来又没有解谜的趣味性,而且从讲解来看,总不能说答案是遍历出来的吧,只好从听众的角度一步步解密到结果。
希望能对他人有所帮助