本文主要是介绍菜鸡学 js 逆向感悟(针对小白,也请各位大佬指点一下),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 菜鸡入门 js 逆向一点小经验
- js 逆向过程
- 代码实现
菜鸡入门 js 逆向一点小经验
本火箭最近因为要做个项目(不是我自己做,是让大佬带),大佬让我先多看一些论文。
于是,小火箭我就去了学校购买的 某方数据知识服务平台 搜索论文,因为每次都点下载太麻烦,即使有批量下载我也觉得好麻烦。
(我这是怎么了,都懒成这个样子了,😔,又与大佬们拉开差距了)
于是我就又想写个爬虫,输入关键词 ,然后自动下载指定目录,到时候只要输入关键词,再给出 保存路径 ,就无忧咯o( ̄▽ ̄)ブ
说冲就冲
第一步,还是轻车熟路地打开 F12,点击网络
注:
- 如果需要先登录校园网的话,一定要先登录哦
以关键词 无人驾驶大数据 为例,输入关键词后,点击回车…
好像有哪里不太对,我的主题是 js 逆向,emmm,换碟!
很容易可以找到其中一个 下载按钮 所对应的元素,呐,就在这里
(如果不会的话,你可真得好好补补课了 U•ェ•*U, 如下图所示)
右键 点击 下载按钮(想要查看的任何元素都可以这样),然后点击 检查元素,就 o98k 啦~
可以看到,这个按钮所对应的链接是通过 js(emmm,用什么词好呢?加载?emmm,就是让一个 js 文件对按钮加一个事件,然后当我们点击了这个按钮,可以跳转到想要的页面
要按往常,我还真的一点头绪也没有,因为那时候的我 不会 js ,但现在,经过简(艰)单(苦)自学后,我大致了解了 js 逆向的过程。
js 逆向过程
- 先 找到 这个事件所对应的 js 语句
- 分析
- 去除不必要的变量
- 然后 模拟 得到应该得到的值
- 最后 执行 一下就万事大吉了
(屏幕前的你似乎还是有点懵,那正常,因为我也还是有点懵,つ﹏⊂)
啥也不说了,直接实践,世间唯一真理,实践出真知!
奥里给,造就完了!!!
(其实以前我也大概知道了 js 逆向的过程,但我很愚蠢的一直找不到别人所说的 全局搜索 ,つ﹏⊂,不过昨天我终于找到了,(ಥ _ ಥ),我用的火狐,而全局搜索就在如下图所示的地方)
你们可以尝试一下,点一下就会发现新大陆!!!!!
这个全局搜索是真的好用,我感觉我下边都不用讲了(つ﹏⊂)
说实话,这个逆向比较简单一点,因为这个事件执行的 js 代码和传递的参数都在标签中有,如下图所示
看起来是不是有点熟悉,因为这就是在下载按钮那个标签里有
🤦(说实话,我也不知道他为什么要放的这么明显,虽然我们也可以通过点击 event 按钮 也能查看到。
但这样放在标签属性中的话
- 直接 xpath 就得到了
- 再 re 一下就得到了传递的参数值了
- 为什么我这么说呢,因为我就用的这种方法哈哈,U•ェ•*U
)
我们可以看到它使用的是函数 downLoadPermissions ,通过全局搜索,我们能够找到这个函数所在位置
下面就换碟福尔摩斯 (开始分析) :
在这个函数的下面还有个函数名差不多的函数,他们的作用差不多,可以看出来
这两个函数传递的参数名为 page_cnt,language,resourceType,source,id,title,isoa,isfirst
函数的功能是
- 首先用变量 operationPermiss 链接到相应的标签
- 判断这个变量的值是否为 false ,如果是,就调用函数 download
- 否则,就调用函数 getloginurl ,显而易见,这个是要跳转到登陆链接
我们肯定是要选择 download 呀!
再次使用全局搜索,搜索函数 download ,很(不太)容易就找到了这个函数所在的位置
看看左边密密麻麻的搜索结果,我可是费了好大的劲才找到真正的函数定义
/(ㄒoㄒ)/~~
看这个函数的功能,应该是
- 先判断 isfirst 的值,如果未定义(应该是这个意思吧),就置为空
- 然后不看 title,直接看最后一行
- 我不太清楚 windows.open 这个函数的功能,但我看到了括号里是在拼接链接地址,(和我平常拼接网址好像啊哈哈),所以我就找到了这个 下载按钮 所对应的网址
- 注:
- 因为传递的函数值不一样,所以下载地址都不一样(我猜你们肯定知道😁)
那现在我们就可以愉快的拼接文件下载的网址咯!!!
- 因为传递的函数值不一样,所以下载地址都不一样(我猜你们肯定知道😁)
代码实现
我的代码如下
def get_download_list(self, index_content):'''本函数用来得到文章下载的 url:return download_url_list:'''# 首先得到包含 下载按钮 的论文所对应的 div 标签c_list = index_content.xpath('//div[@class="ResultList "]//span[text()="下载"]/../../a/@onclick')# 遍历列表for i, c in enumerate(c_list):try:# 首先得到函数调用的语句,因为有的会还含有其他语句,影响提取参数值c = re.findall('downLoadPermissions\((.*?)\)', c)[0]# 这个错误是我没有想到的,因为有的调用的函数是 downLoad,使用上边的正则表达式会报错,超出列表范围except IndexError:c = re.findall('downLoad\((.*?)\)', c)[0]# 用逗号 , 分隔各个参数值list1 = c.split(',')info_list = []# 得到的是参数值,带着引号,所以提取中间的值,我没有尝试 eval 函数,直接用的 re,你可以尝试一下,然后告诉我可行性,嘻嘻,我就是白嫖怪!for info in list1:try:info = re.findall("'(.*)'", info)[0]# 这个报错我也是没有想到的,因为有的文章来源不仅仅是 'WF',如果有其他来源的话,这个参数值就是如 '[WF,]'# 这时候会导致使用逗号分隔会得到两个空字符串,本来得到的列表有 7 个参数值,但列表中有 8 个元素,所以需要去除一个,否则会影响传递值# 在尝试以后,我发现 source 字段直接设置为 'WF' 同样可以得到结果,所以传递值时 source 字段直接使用的 'WF'except IndexError:info = ''info_list.append(info)if len(info_list) == 8:del info_list[3]data = {'page_cnt': info_list[0],'language': info_list[1],'resourceType': info_list[2],'source': 'WF','resourceId': info_list[4],'resourceTitle': info_list[5],'isoa': info_list[6],'type': info_list[2],'first': ''}# 拼接网址index_url = major_url2 + up.urlencode(data)self.download_url_list.append(index_url)
我将提取信息的过程写成了一个类,最终代码如下
# -*- coding=utf-8 -*-import requests
import urllib.parse as up
import lxml.etree as le
import reheaders = {【这里就加上你们自己的 headers 即可】}major_url = 'http://g.wanfangdata.com.cn'
major_url2 = 'http://g.wanfangdata.com.cn/search/downLoad.do?'class wanfang_spider_tools():def __init__(self, kw):self.kw = kwself.index_content = []self.title_list = []self.download_url_list = []self.title_list = []self.result_dict = {}def search_kw_result(self, page):'''得到关键词的搜索结果:return index_content <xml>:'''data = {'beetlansyId': 'aysnsearch','searchType': 'all','pageSize': '20','page': str(page),'searchWord': self.kw,'order': 'correlation','showType': 'detail','isCheck': 'check','isHit': '','isHitUnit': '','firstAuthor': 'false','corePerio': 'false','alreadyBuyResource': 'true','rangeParame': '','navSearchType': 'all'}index_url = major_url + '/search/searchList.do?' + up.urlencode(data)self.index_content.append(le.HTML(requests.get(url=index_url, headers=headers).text))def get_content_list(self, index_content):'''查看搜索结果总页数:return:'''num_list = [int(num) for num in index_content.xpath('//div[@id="laypage_0"]/a[text()!="下一页"]/text()')]try:max_num = max(num_list)for page in range(2, max_num):self.search_kw_result(page)except:passdef get_title_list(self, index_content):'''本函数用来得到论文题目和类型:return title_list <list>:'''xpath_list = index_content.xpath('//div[@class="ResultList "]//span[text()="下载"]/../../../../../../..//div[@class="title"]')for title_x in xpath_list:char = ''title_l = title_x.xpath('./a[@target="_blank"]//text()')if title_l == []:continuecontent_type = title_x.xpath('./../../div[@class="ResultCheck"]/input/@exporttype')[0]for title_c in title_l:char += title_cchar = re.sub('[\r]*[\t]*[\n]*', '', char)if char != '':self.result_dict[char] = {}self.result_dict[char]['type'] = content_typedef get_download_list(self, index_content):'''本函数用来得到文章下载的 url:return download_url_list:'''c_list = index_content.xpath('//div[@class="ResultList "]//span[text()="下载"]/../../a/@onclick')for i, c in enumerate(c_list):try:c = re.findall('downLoadPermissions\((.*?)\)', c)[0]except IndexError:c = re.findall('downLoad\((.*?)\)', c)[0]list1 = c.split(',')info_list = []for info in list1:try:info = re.findall("'(.*)'", info)[0]except IndexError:info = ''info_list.append(info)if len(info_list) == 8:del info_list[3]data = {'page_cnt': info_list[0],'language': info_list[1],'resourceType': info_list[2],'source': 'WF','resourceId': info_list[4],'resourceTitle': info_list[5],'isoa': info_list[6],'type': info_list[2],'first': ''}index_url = major_url2 + up.urlencode(data)self.download_url_list.append(index_url)def return_info(self):'''整合信息:return info_dict <dict>:'''self.search_kw_result(1)self.get_content_list(self.index_content[0])for index_content in self.index_content:self.get_title_list(index_content)self.get_download_list(index_content)for i, title in enumerate(self.result_dict.keys()):self.result_dict[title]['url'] = self.download_url_list[i]return self.result_dict
有了下载的网址,后续的下载就靠你们自己了
我是使用的 webdriver 打开浏览器后自动下载,你们可以选择其他的方法,方法不唯一
其实再看看,好像我这又不太像 js 逆向,准确来说,我现在还没有对 js 逆向有个深刻的理解,烦请各位大佬指点
以上就是我要分享的内容,因为学识尚浅,会有不足,还请各位大佬指正。
有什么问题也可在评论区留言。
这篇关于菜鸡学 js 逆向感悟(针对小白,也请各位大佬指点一下)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!