写好脚本则更能够帮你抓取数据到文件、数据库,部分实现自动化,甚至远超一些同类专业产品。
常规功能
可以用来指定抓取所有的WEB通讯,也可以只抓取指定进程的通讯。
File-Capture Traffic ; Any Process 或拖动选定进程窗口
2.可以用来查看一个URL打开后,浏览器与后端的交互
3.可以查看任意一个HTTP交互,看请求和响应的原始报文,帮助你了解HTTP协议
4.可以设置丰富的过滤条件,确保聚焦
5.可以以各种形态查看数据,并提供了工具来做转换【这个比较丰富,但隐藏较深】
6.可以编写脚本,实现各个阶段的处理
可以基于类似Windows下的WScript,甚至使用一些ActiveX组件实现并发机制、通讯与数据存储。
OnBeforeRequest 在请求发生前调用,请求经过Fiddler发送给服务器之前会先调用这个函数,因此,如果想要修改请求,可以写在这个函数里
OnPeekAtResponseHeaders 在头到达后调用
OnBeforeResponse 在内容到达后,还没有处理前调用,从服务器读完响应后,且在将响应发送给客户端之前执行的。通过修改这个函数,可以修改服务器的响应头或者响应体
把网页上的JSON文件下载到本地
把以下内容放入OnBeforeResponse里面,
if (m_Hide304s && oSession.responseCode == 304) {
oSession["ui-hide"] = "true";
}
if (oSession.uriContains("https://www.tiktok.com/api/recommend/item_list/")){
var strBodytk=oSession.GetResponseBodyAsString();
//var spstk = oSession.PathAndQuery.slice(-58,);
//FiddlerObject.alert(spstk)
var timestamptk=new Date().getTime();
var filenametk = "D:\\tiktokzl" + "\/" + timestamptk + ".json";
//var filename = "D:\抖音评论资料" + "/" + sps + timestamp + ".json";
var curDatetk = new Date();
var swtk : System.IO.StreamWriter;
if (System.IO.File.Exists(filenametk)){
swtk = System.IO.File.AppendText(filenametk);
swtk.Write(strBodytk);
}
else{
swtk = System.IO.File.CreateText(filenametk);
swtk.Write(strBodytk);
}
swtk.Close();
swtk.Dispose();
}
抓到 请求的数据 保存本地txt 文件里面
- 将下代码 粘到OnBeforeRequest 的函数里头
if
(oSession.fullUrl.Contains("填写需要抓取的域名")) { var
fso; var
file; fso = new
ActiveXObject("Scripting.FileSystemObject"); //文件保存路径可自定义 file = fso.OpenTextFile("填写保存TXT文件地址",8 ,true, true); file.writeLine("Request url: "
+ oSession.url); file.writeLine("Request header:"
+ "\n"
+ oSession.oRequest.headers); file.writeLine("Request body: "
+ oSession.GetRequestBodyAsString()); file.writeLine("\n"); file.close();}
自动化抓取图片并提出重复的
static function FileExsitInDirectory(fso:Object, filename:String , dirpath:String )
{
var curPath = dirpath + “/” + filename ;
var objset , objFolders , FolderName, ret;
if (fso.FileExists(curPath))
{
return curPath;
}
else
{
var objset = fso.getFolder(dirpath);
var objFolders = objset.SubFolders;
var fenum = new Enumerator(objset.SubFolders);
for (var i = 0 ; !fenum.atEnd(); fenum.moveNext(),i++)
{
var FolderName = dirpath + "/" + fenum.item().Name + "/";
var ret = FileExsitInDirectory(fso, filename, FolderName);
if( ret != "NULL" )
{
return ret
}
}
return "NULL";
}
}
static function OnBeforeResponse(oSession: Session)
{
if (m_Hide304s && oSession.responseCode == 304)
{
oSession[“ui-hide”] = “true”;
}
//如果来自指定网站,且是jpg,则写文件 image/jpeg
if(
(oSession.RequestHeaders.AllValues("Host").Contains(".mm115.net") ||
oSession.RequestHeaders.AllValues("Host").Contains(".jzsjwk.com"))
&&
oSession.ResponseHeaders.AllValues("Content-Type").Contains("image/jpeg") )
{
var whindex = oSession.url.IndexOf ('?');
if (whindex <= 0)
whindex = oSession.url.Length;
var file_url = oSession.url.Substring (0,whindex);
whindex = oSession.url.IndexOf ('.jpg');
if ((whindex > 0) && (oSession.GetResponseBodyAsString().Length > 40000))
{
whindex = whindex+4;
file_url = file_url.Substring (0,whindex).Replace ('/','_').Replace('%','B').Replace('?','7').Replace('&','-').Replace('img22.jzsjwk.com','img1.mm115.net');
var file_path = "d:/PRVIT/jpg/"+file_url;
try
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
var retval = FileExsitInDirectory(fso,file_url,"d:/PRVIT/jpg/");
FiddlerObject.log (retval);
if ("NULL" == retval)
{
var stream = new ActiveXObject('Adodb.Stream');
stream.Mode = 3;
stream.Open();
stream.Type = 1;
//stream.Charset = 'unicode';
//stream.WriteText(s);
stream.Position = 0;
stream.Type = 1;
//stream.Position = 2;
//var bs = stream.Read();
//stream.Position = 0;
stream.Write(oSession.responseBodyBytes);
//stream.SetEOS();
stream.SaveToFile(file_path,1);
stream.Close();
oSession["ui-backcolor"] = "yellow";
}
else
{
oSession["ui-strikeout"] = "true";
oSession["ui-backcolor"] = "green";
}
}
catch(err)
{
FiddlerObject.log (err.message);
oSession["ui-backcolor"] = "red";
}
}
else
{
oSession["ui-color"] = "red";
}
}
}
抓取内容,并存放到数据库
var sql = “”;
try
{
var con =new ActiveXObject(“ADODB.Connection”);
//con.Provider="Microsoft.ACE.OLEDB.18.0";
var rs=new ActiveXObject("ADODB.Recordset");
/**
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Y:/TEST/fiddler_web_service_analysis.accdb;Persist Security Info=False;
**/
//var access_db_path = "d:/fiddler_web_service_analysis.accdb" ;
//con.ConnectionString="Data Source="+access_db_path;
//ODBC DSN name ,config by windows odbc
con.open("DSN=db_hsb_vs_ahs;") ;
//FiddlerObject.alert(1);
sql = "insert into t_call_record (call_timestamp,request_send_timestamp,response_recv_timestamp,sitename,url,request,response,spend_second,content_type,content_length) values(" +
strVar1(oSession.Timers.FiddlerBeginRequest) + "," +
strVar1(oSession.Timers.ClientDoneRequest) + "," +
strVar1(oSession.Timers.ServerDoneResponse) + "," +
strVar1(oSession.RequestHeaders.AllValues("Host")) + "," +
strVar1(oSession.url.Substring (0,whindex)) + "," +
strVar1(oSession.RequestHeaders.ToString ()+oSession.GetRequestBodyAsString()) + "," +
strVar1(oSession.ResponseHeaders.ToString ()+oSession.GetResponseBodyAsString()) + "," +
etimes*1000 + "," +
strVar1(oSession.ResponseHeaders.AllValues("Content-Type")) +"," +
oSession.ResponseHeaders.AllValues("Content-Length")+0
+");";
//FiddlerObject.alert(sql);
rs.open(sql,con);
oSession["ui-color"] = "red";
//rs.close();
// rs=NULL;
con.close();
// con = NULL;
}
catch(exp)
{
var txt="Error description: " + exp.message + "\n\n" + sql;
FiddlerObject.log(txt);
oSession["ui-strikeout"] = "true";
}
- 在此处【重定向urlplace】host和url的判断
if(oSession.HostnameIs("host") && oSession.url.IndexOf("url_path") > -1){
oSession.hostname = "api.mobile.xxx.com"
}
- 在此处【设置请求的header】,测试网络爬虫时候会用,
// TSET FOR Spider: 根据网站来限定请求
if (oSession.HostnameIs("test.com")) {
// 模拟修改请求的用户端ip,这种情况对独立的网络有效,对于公司级的网络,还是有一些问题,需要借助vpn
oSession.oRequest["X-Forwarded-For"]="16.12.23.16";
// 修改请求的header
oSession.oRequest["User-Agent"] = "spider Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0";
}
2019.04.26 手机模拟添加cookie(区别于种cookie 在onBeforeResponse里)
- 删除所有的cookie
oSession.oRequest.headers.Remove("Cookie");
- 新建cookie
oSession.oRequest.headers.Add("Cookie", "username=testname;testpassword=P@ssword1");
注意: Fiddler script不能直接删除或者编辑单独的一个cookie, 你需要用replace方法或者正则表达式的方法去操作cookie的string
if (oSession.HostnameIs("******") && oSession.oRequest.headers.Exists("Cookie") ) {
var sCookie = oSession.oRequest["Cookie"];
//用replace方法或者正则表达式的方法去操作cookie的string
//sCookie = sCookie.Replace("cookieName=", "ignoreme=");
sCookie = sCookie + ";tt_spver=1";
oSession.oRequest["Cookie"] = sCookie;
}
在此处修改response的bady内容【使用正则匹配方式】
if(oSession.HostnameIs("host") && oSession.url.IndexOf("url_path") > -1){
// 获取response中的body字符串
var strBody=oSession.GetResponseBodyAsString();
// 用正则表达式或者replace方法去修改string
var regx = '"stream_mode":\d*?'
strBody=strBody.replace(regx,'"stream_mode":0');
// 弹个对话框检查下修改后的body
FiddlerObject.alert(strBody);
// 将修改后的body,重新写回Request中
oSession.utilSetResponseBody(strBody);
}
在此处修改json中的数据【修改接口字段的值】
if(oSession.HostnameIs("host") && oSession.url.IndexOf("url_path") > -1){
// 获取Response Body中JSON字符串
var responseStringOriginal = oSession.GetResponseBodyAsString();
// 转换为可编辑的JSONObject变量
var responseJSON = Fiddler.WebFormats.JSON.JsonDecode(responseStringOriginal);
// 修改JSONObject变量,修改字段数据
responseJSON.JSONObject["new_core"] = "True";
responseJSON.JSONObject["stream_mode"] = 5;
// 重新设置Response Body
var responseStringDestinal = Fiddler.WebFormats.JSON.JsonEncode(responseJSON.JSONObject);
oSession.utilSetResponseBody(responseStringDestinal);
}
在此处修改json中的数据【增加接口字段=值】
if(oSession.HostnameIs("host") && oSession.url.IndexOf("url_path") > -1){
// 获取Response Body中JSON字符串
var responseStringOriginal = oSession.GetResponseBodyAsString();
// 转换为可编辑的JSONObject变量
var responseJSON = Fiddler.WebFormats.JSON.JsonDecode(responseStringOriginal);
// 修改JSONObject变量,修改字段数据
responseJSON.JSONObject["type_arr"] = ["bullet"];
// 重新设置Response Body
var responseStringDestinal = Fiddler.WebFormats.JSON.JsonEncode(responseJSON.JSONObject);
oSession.utilSetResponseBody(responseStringDestinal);
}
使指定URL支持CORS跨域请求有时候,你调用一个 json 接口,发现跨域了,你需要去找接口的开发人支持跨域,显然傻傻等待后端开发完毕再联调是低效率的, 这个时候就就要在后台改完之前就自己实现跨域的模拟,此时 fiddler 显然是再好不过的利器。支要持 CORS 跨域, 就是要为请求的返回头增加 Access-Control-Allow-Origin 属性,因此需要修改 OnBeforeResponse函数,在该函数的末尾添加你的 CORS 逻辑
static function OnBeforeResponse(oSession: Session) {
...
if(oSession.uriContains("要处理的url")){
oSession.oResponse["Access-Control-Allow-Origin"] = "允许的域名";
oSession.oResponse["Access-Control-Allow-Credentials"] = true;
}
}
oSession常用的相关属性和方法
// 修改session中的显示样式
oSession["ui-color"] = "orange";
// 移除http头部中的MQB-X5-Referer字段
oSession.oRequest.headers.Remove("MQB-X5-Referer");
// 修改http头部中的Cache-Control字段
oSession.oRequest["Cache-Control"] = "no-cache";
// 修改host
oSession.host = "example.domain";
// 修改Origin字段
oSession.oRequest["Origin"] = "http://domain";
// 删除所有的cookie
oSession.oRequest.headers.Remove("Cookie");
// 新建cookie
oSession.oRequest.headers.Add("Cookie", "username=cookiename;");
// 修改Referer字段
oSession.oRequest["Referer"] = "https://yoururl";
// 获取Request中的body字符串
var strBody=oSession.GetRequestBodyAsString();
// 用正则表达式或者replace方法去修改string
strBody=strBody.replace("aaaa","bbbbbb");
// 将修改后的body,重新写回Request中
oSession.utilSetRequestBody(strBody);
// 判断连接中是否包含字符串str
oSession.uriContains(str)
// 给连接请求添加一个字段TEST
oSession.oRequest["TEST"]="TEST NEW Request";
可参考
https://github.com/gitjayzhen/FiddlerUseScript