JS逆向实战8——某网实战(基于golang-colly)
其实本章算不上逆向教程 只是介绍golang的colly框架而已
列表页分析
根据关键字搜索
通过抓包分析可知
下一页所请求的参数如下
上图标红的代表所需参数
所以其实我们真正需要的也就是SearchSql
但是你多观察即可知 这个SearchSql在第一页访问的时候就传给了
所以也就是
爬取第一页获取第二页的请求参数——爬取第二页获取第三页的请求参数
详情页分析
详情页链接在列表页给你的链接是错误的
真是的链接如下图所示
由此图可知我们需要很多参数才能完成爬取
但是列表页给我们的链接也不是毫无用处
我们用正则提取中间所需要的参数即可完成爬取
代码
由于代码是用Go写的 用colly 还不是特别熟练
package main
import (
"fmt"
"github.com/gocolly/colly"
"regexp"
"time"
)
func main() {
PostUrl := "https://kns.cnki.net/kns8/Brief/GetGridTableHtml"
c, contentCollector := initCollector()
c.OnRequest(func(r *colly.Request) {
fmt.Println(r)
fmt.Println(r.Method)
r.Headers.Set("Accept", "text/html, */*; q=0.01")
r.Headers.Set("Accept-Language", "zh-CN,zh;q=0.9")
r.Headers.Set("Connection", "keep-alive")
r.Headers.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
r.Headers.Set("Origin", "https://kns.cnki.net")
r.Headers.Set("Referer", "https://kns.cnki.net/kns8/defaultresult/index")
r.Headers.Set("Sec-Fetch-Dest", "empty")
r.Headers.Set("Sec-Fetch-Mode", "cors")
r.Headers.Set("Sec-Fetch-Site", "same-origin")
r.Headers.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36")
r.Headers.Set("X-Requested-With", "XMLHttpRequest")
})
// 解析列表页
c.OnHTML(".result-table-list tbody", func(element *colly.HTMLElement) {
element.ForEach("tr", func(i int, element *colly.HTMLElement) {
// 获取链接地址
titleUrl, _ := element.DOM.Find("a").Attr("href")
// 获取时间
titleDate := element.DOM.Find("td.date").Text()
// 拿到标题名
s := element.DOM.Find("a").Text()
// 切片取值
if len(s) < 0 {
_ = fmt.Errorf("匹配失败,长度为:%v\n", len(s))
}
titleName := s[:len(s)-4]
// 正则取 decode的值
//deCodeRe := `DbCode=(.*?)&`
// 正则 fileName 的值
fileNameRe := `FileName=(.*?)&`
// 正则 取DbName 的值
dbNameRe := `DbName=(.*?)&`
isMatched, _ := regexp.MatchString(fileNameRe, titleUrl)
if !isMatched {
_ = fmt.Errorf("匹配失败,%v\n", isMatched)
}
fileName := regexp.MustCompile(fileNameRe).FindStringSubmatch(titleUrl)[1]
dbName := regexp.MustCompile(dbNameRe).FindStringSubmatch(titleUrl)[1]
trueUrl := fmt.Sprintf(`https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=CCND&dbname=%s&filename=%s&uniplatform=NZKPT`, dbName, fileName)
fmt.Println(titleName)
fmt.Println(titleDate)
fmt.Println(trueUrl)
_ = contentCollector.Visit(trueUrl)
})
sqlVal, _ := element.DOM.Find("#sqlVal").Attr("value")
_ = c.Post(PostUrl, map[string]string{
"IsSearch": "false",
"QueryJson": `{"Platform":"","DBCode":"CFLS","KuaKuCode":"CJFQ,CDMD,CIPD,CCND,CISD,SNAD,BDZK,CCJD,CCVD,CJFN","QNode":{"QGroup":[{"Key":"Subject","Title":"","Logic":1,"Items":[{"Title":"主题","Name":"SU","Value":"矿","Operate":"%=","BlurType":""}],"ChildItems":[]}]}}`,
"SearchSql": sqlVal,
"PageName": "defaultresult",
"HandlerId": "16",
"DBCode": "CFLS",
"KuaKuCodes": "CJFQ,CDMD,CIPD,CCND,CISD,SNAD,BDZK,CCJD,CCVD,CJFN",
"CurPage": "2",
"RecordsCntPerPage": "20",
"CurDisplayMode": "listmode",
"CurrSortField": "",
"CurrSortFieldType": "desc",
"IsSortSearch": "false",
"IsSentenceSearch": "false",
"Subject": "",
})
})
// 解析详情页
contentCollector.OnHTML(".brief", func(element *colly.HTMLElement) {
contentHtml := element.Text
fmt.Printf(contentHtml)
})
_ = c.Post(PostUrl, map[string]string{
"IsSearch": "true",
"QueryJson": `{"Platform":"","DBCode":"CFLS","KuaKuCode":"CJFQ,CDMD,CIPD,CCND,CISD,SNAD,BDZK,CCJD,CCVD,CJFN","QNode":{"QGroup":[{"Key":"Subject","Title":"","Logic":1,"Items":[{"Title":"主题","Name":"SU","Value":"矿","Operate":"%=","BlurType":""}],"ChildItems":[]}]}}`,
"PageName": "defaultresult",
"DBCode": "CFLS",
"KuaKuCodes": "CJFQ,CDMD,CIPD,CCND,CISD,SNAD,BDZK,CCJD,CCVD,CJFN",
"CurPage": "1",
"RecordsCntPerPage": "20",
"CurDisplayMode": "listmode",
"CurrSortField": "",
"CurrSortFieldType": "desc",
"IsSentenceSearch": "false",
"Subject": "",
})
}
func initCollector() (*colly.Collector, *colly.Collector) {
// 1. 创建收集器
c := colly.NewCollector(
colly.UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36"),
colly.AllowURLRevisit(),
)
// 设置抓取频率限制
_ = c.Limit(&colly.LimitRule{
DomainGlob: "*",
RandomDelay: 5 * time.Second, // 随机延迟
})
// 设置clone内容 解析
contentCollector := c.Clone()
return c, contentCollector
}
JS逆向实战8——某网实战(基于golang-colly)的更多相关文章
- 手把手教你写电商爬虫-第三课 实战尚妆网AJAX请求处理和内容提取
版权声明:本文为博主原创文章,未经博主允许不得转载. 系列教程: 手把手教你写电商爬虫-第一课 找个软柿子捏捏 手把手教你写电商爬虫-第二课 实战尚妆网分页商品采集爬虫 看完两篇,相信大家已经从开始的 ...
- 《Python Web开发实战》|百度网盘免费下载|Python Web开发
<Python Web开发实战>|百度网盘免费下载|Python Web开发 提取码:rnz4 内容简介 这本书涵盖了Web开发的方方面面,可以分为如下部分: 1. 使用最新的Flask ...
- Dubbo官网实战使用技巧
原文链接:Dubbo官网实战使用技巧 1.启动时检查: 我们检查依赖的服务是否启动,可利用下面三个属性,优先级从左到右逐渐降低. 如果服务不是强依赖,或者说服务之间可能存在死循环依赖,我们应该将 ch ...
- js中各种跨域问题实战小结(二)
这里接上篇:js中各种跨域问题实战小结(一) 后面继续学习的过程中,对上面第一篇有稍作休整.下面继续第二部分: -->5.利用iframe和location.hash -->6.windo ...
- js中各种跨域问题实战小结(一)
什么是跨域?为什么要实现跨域呢? 这是因为JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.也就是说只能访问同一个域中的资源.我觉得这就有必要了解下javascript中的同源策略 ...
- Sass实战 sass官网
Sass实战 sass官网 1.相关视频教程:http://pan.baidu.com/s/1eSl8bUa 1.1我的项目源码:http://pan.baidu.com/s/1dFmqbyp 1.2 ...
- 主题:实战WebService II: SOAP篇(基于php)
概述(SOAP和XML-PRC比较) 在Web服务发展的初期,XML格式化消息的第一个主要用途是,应用于XML-RPC协议,其中RPC代表远程过程调用.在XML远程过程调用 (XML-RPC)中,客户 ...
- 项目实战——企业级Zabbix监控实战(一)
项目实战--企业级Zabbix监控实战 实验一:Zabbix监控的搭建 1.实验准备 centos系统服务器3台. 一台作为监控服务器, 两台台作为被监控节点, 配置好yum源. 防火墙关闭. 各节点 ...
- 我去!爬虫遇到JS逆向AES加密反爬,哭了
今天准备爬取网页时,遇到『JS逆向AES加密』反爬.比如这样的: 在发送请求获取数据时,需要用到参数params和encSecKey,但是这两个参数经过JS逆向AES加密而来. 既然遇到了这个情况,那 ...
随机推荐
- which 和 that 在定语从句中作介词宾语的用法
关系代词在定语从句中作介词的宾语,且介词在关系代词之前时,关系代词应该用 which:介词在定语从句句末,关系代词可以用 that 或 which. (一)He teaches in a school ...
- what the difference betweent pin page and lock page ?
以前在项目中,大家为了避免自己使用的page被换出,使用的方式是mlock,从mlock的实现的看,它限制了page被swap, 然后在一个swap off的系统中,这样其实和mlock调用与否没有关 ...
- python与pycharm的安装与“试用”
python与pycharm的安装与"试用" 一.python解释器安装与启动 python解释器的安装 1.打开文件安装包运行页面 #python3.8 2.选择Customiz ...
- K8S中部署apisix(非ingress)
不使用pvc的方式在K8S中部署apisix-gateway 简介 因为公司项目准备重构,现在做技术储备,之前公司项目使用的ocelot做网关,ocelot是.net平台下的一个网关,也是很不错,但是 ...
- [CSP day1T3]树上的数
题面 题解 这道题由于是求字典序最小的,所以要贪心地枚举数字,然后找可以走到的编号最小的点,处理这条路径. 这条路径有一些特性. 以下是特别精炼的结论: 所以一旦选好了路径,这些边的先后顺序就被定死了 ...
- Rust 从入门到精通06-语句和表达式
1.语句和表达式 语句和表达式是 Rust 语言实现逻辑控制的基本单元. 在 Rust 程序里面,语句(Statement)是执行一些操作但不返回的指令,表达式(Expressions)计算并产生一个 ...
- 第四十篇:Vue的生命周期(一)
好家伙,军训结束了,回归 Vue实例的生命周期 1.什么是生命周期? 从Vue实例创建,运行到销毁期间总是伴随着各种各样的事件,这些事件,统称为生命周期. 2.什么是生命周期钩子? 生命周期函数的别称 ...
- Linux或Docker里安装minio / Docker中安装h5ai
此文为单节点搭建操作 Linux中搭建minio 对象存储服务器 下载minio安装包 wget https://dl.minio.io/server/minio/release/linux-amd6 ...
- KingbaseES 参数 - ignore_char_null_check
KingbaseES 基于PostgreSQL进行了大量的Oracle兼容性开发,为了能同时兼容Oracle 和 PG 的特性,增加参数进行控制.以下介绍 KingbaseES 下特有的参数 igno ...
- JavaWeb核心篇(3)——JSP,MVC,三层架构
JavaWeb核心篇(3)--JSP,MVC,三层架构 在本篇文章中我们会学习到JSP,MVC,三层架构 虽然JSP已经快被时代所淘汰,但是在一些老旧的工作场所还是有在使用,所以了解一下也不为过 至于 ...