C# 关于爬取网站数据遇到csrf-token的分析与解决

需求

某航空公司物流单信息查询,是一个post请求。通过后台模拟POST HTTP请求发现无法获取页面数据,通过查看航空公司网站后,发现网站使用避免CSRF攻击机制,直接发挥40X错误。

关于CSRF

读者自行百度

网站HTTP请求分析

Headers

Form Data

在head里包含了cookie 与 x-csrf-token  formdata 里包含了_csrf (与head里的值是一样的).

这里通过查看该网站的JS源代码发现_csrf 来自于网页的head标签里

猜测cookie与 x-csrf-token是有一定的有效期,并且他们共同作用来防御CSRF攻击。

解决方案

1,首先请求一下该航空公司的网站,获取cookie与_csrf

2,然后C# 模拟http分别在head和formdata里加入如上参数,发起请求

代码

public class CSRFToken
 {
 string cookie;//用于请求的站点的cookie
 List<string> csrfs;//用于请求站点的token的key 以及 value

 public CSRFToken(string url)
 {
  //校验传输安全
  if (!string.IsNullOrWhiteSpace(url))
  {
  try
  {
   //设置请求的头信息.获取url的host
   var _http = new HttpHelper(url);
   string cookie;
   string html = _http.CreateGetHttpResponseForPC(out cookie);
   this.cookie = cookie;

   string headRegex = @"<meta name=""_csrf.*"" content="".*""/>";

   MatchCollection matches = Regex.Matches(html, headRegex);
   Regex re = new Regex("(?<=content=\").*?(?=\")", RegexOptions.None);
   csrfs = new List<string>();
   foreach (Match math in matches)
   {

   MatchCollection mc = re.Matches(math.Value);
   foreach (Match ma in mc)
   {
    csrfs.Add(ma.Value);
   }
   }

  }
  catch (Exception e)
  {

  }
  }
 }

 public String getCookie()
 {
  return cookie;
 }
 public void setCookie(String cookie)
 {
  this.cookie = cookie;
 }
 public List<string> getCsrf_token()
 {
  return csrfs;
 }
 }

httpHelper

public string CreatePostHttpResponse(IDictionary<string, string> headers, IDictionary<string, string> parameters)
  {
   HttpWebRequest request = null;
   //HTTPSQ请求
   UTF8Encoding encoding = new System.Text.UTF8Encoding();
   ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
   request = WebRequest.Create(_baseIPAddress) as HttpWebRequest;
   request.ProtocolVersion = HttpVersion.Version10;
   ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
   request.Method = "POST";
   request.ContentType = "application/x-www-form-urlencoded";
   // request.ContentType = "application/json";
   request.UserAgent = DefaultUserAgent;
   //request.Headers.Add("X-CSRF-TOKEN", "bc0cc533-60cc-484a-952d-0b4c1a95672c");
   //request.Referer = "https://www.asianacargo.com/tracking/viewTraceAirWaybill.do";

   //request.Headers.Add("Origin", "https://www.asianacargo.com");
   //request.Headers.Add("Cookie", "JSESSIONID=HP21d2Dq5FoSlG4Fyw4slWwHb0-Sl1CG6jGtj7HE41e5f4aN_R1p!-435435446!117330181");
   //request.Host = "www.asianacargo.com";

   if (!(headers == null || headers.Count == 0))
   {

    foreach (string key in headers.Keys)
    {
     request.Headers.Add(key, headers[key]);
    }

   }

   //如果需要POST数据
   if (!(parameters == null || parameters.Count == 0))
   {
    StringBuilder buffer = new StringBuilder();
    int i = 0;
    foreach (string key in parameters.Keys)
    {
     if (i > 0)
     {
      buffer.AppendFormat("&{0}={1}", key, parameters[key]);
     }
     else
     {
      buffer.AppendFormat("{0}={1}", key, parameters[key]);
     }
     i++;
    }
    byte[] data = encoding.GetBytes(buffer.ToString());
    using (Stream stream = request.GetRequestStream())
    {
     stream.Write(data, 0, data.Length);
    }
   }

   HttpWebResponse response;

   try
   {
    //获得响应流
    response = (HttpWebResponse)request.GetResponse();
    Stream s = response.GetResponseStream();

    StreamReader readStream = new StreamReader(s, Encoding.UTF8);
    string SourceCode = readStream.ReadToEnd();
    response.Close();
    readStream.Close();
    return SourceCode;
   }
   catch (WebException ex)
   {
    response = ex.Response as HttpWebResponse; return null;
   }

  }

 public string CreateGetHttpResponse(out string cookie)
  {
   HttpWebRequest request = null;
   //HTTPSQ请求
   UTF8Encoding encoding = new System.Text.UTF8Encoding();
   ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
   request = WebRequest.Create(_baseIPAddress) as HttpWebRequest;
   request.ProtocolVersion = HttpVersion.Version10;
   ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
   request.Method = "GET";
   request.ContentType = "application/x-www-form-urlencoded";
   request.UserAgent = DefaultUserAgent;

   HttpWebResponse response;

   try
   {
    //获得响应流
    response = (HttpWebResponse)request.GetResponse();

    cookie = response.Headers["Set-Cookie"];
    Stream s = response.GetResponseStream();

    StreamReader readStream = new StreamReader(s, Encoding.UTF8);
    string SourceCode = readStream.ReadToEnd();
    response.Close();
    readStream.Close();
    return SourceCode;
   }
   catch (WebException ex)
   {
    response = ex.Response as HttpWebResponse;
    cookie = "";
    return null;
   }

  }

爬取程序

爬取结果

浏览器结果

注意事项与结论

1,不同的网站,获取cstf的方式不一样,无论怎么做,只要信息传到前台我们都可以有相应的方法来获取。

2,请求时候的http验证可能不一样,测试的某航空公司物流信息的时候,http请求的安全协议是tis12。

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11; 还有其他参数比如UserAgent后台可能也会验证

3,基于如上航空公司,发现它的cookie和cstf_token一定时间内不会改变,那么当实际爬取的时候可以考虑缓存cookie以及cstf_token,只有当请求失败的时候,才重新获取

(0)

相关推荐

  • 用C#做网络爬虫的步骤教学

    如今代码圈很多做网络爬虫的例子,今天小编给大家分享的是如何用C#做网络爬虫.注意这次的分享只是分享思路,并不是一整个例子,因为如果要讲解一整个例子的话,牵扯的东西太多. 1.新建一个控制台程序,这个相信大家都懂的 2.建好以后,打开主程序文件,导入发送http请求的库,这里用的是System.NET 3.编写发送http请求的方法,如下所示:首先实例化WebClient,然后设置头信息,其次转化参数为字节数据,最后调用UploadData方法进行发送. 4.接下来调用我们写的发送http请求的方

  • C#制作多线程处理强化版网络爬虫

    上次做了一个帮公司妹子做了爬虫,不是很精致,这次公司项目里要用到,于是有做了一番修改,功能添加了网址图片采集,下载,线程处理界面网址图片下载等. 说说思路:首相获取初始网址的所有内容 在初始网址采集图片 去初始网址采集链接 把采集到的链接放入队列 继续采集图片,然后继续采集链接,无限循环 还是上图片大家看一下, 处理网页内容抓取跟网页网址爬取都做了改进,下面还是大家来看看代码,有不足之处,还请之处! 网页内容抓取HtmlCodeRequest, 网页网址爬取GetHttpLinks,用正则去筛选

  • C# 爬虫简单教程

    1.使用第三方类库 HtmlAgilityPack 官方网址:https://html-agility-pack.net/?z=codeplex. // From File 从文件获取html信息 var doc = new HtmlDocument(); doc.Load(filePath); // From String 从字符串获取html信息 var doc = new HtmlDocument(); doc.LoadHtml(html); // From Web 从网址获取html信息

  • C#多线程爬虫抓取免费代理IP的示例代码

    这里用到一个HTML解析辅助类:HtmlAgilityPack,如果没有网上找一个增加到库里,这个插件有很多版本,如果你开发环境是使用VS2005就2.0的类库,VS2010就使用4.0,以此类推..........然后直接创建一个控制台应用,将我下面的代码COPY替换就可以运行,下面就来讲讲我两年前做爬虫经历,当时是给一家公司做,也是用的C#,不过当时遇到一个头痛的问题就是抓的图片有病毒,然后系统挂了几次.所以抓网站图片要注意安全,虽然我这里没涉及到图片,但是还是提醒下看文章的朋友. clas

  • 利用C#实现最基本的小说爬虫示例代码

    前言 作为一个新手,最近在学习C#,自己折腾弄了个简单的小说爬虫,实现了把小说内容爬下来写入txt,还只能爬指定网站. 第一次搞爬虫,涉及到了网络协议,正则表达式,弄得手忙脚乱跑起来效率还差劲,慢慢改吧.下面话不多说了,来一起看看详细的介绍吧. 爬的目标:http://www.166xs.com/xiaoshuo/83/83557/ 一.先写HttpWebRequest把网站扒下来 这里有几个坑,大概说下: 第一个就是记得弄个代理IP爬网站,第一次忘了弄代理然后ip就被封了..... 第二个就是

  • c# Selenium爬取数据时防止webdriver封爬虫的方法

    背景 大家在使用Selenium + Chromedriver爬取网站信息的时候,以为这样就能做到不被网站的反爬虫机制发现.但是实际上很多参数和实际浏览器还是不一样的,只要网站进行判断处理,就能轻轻松松识别你是否使用了Selenium + Chromedriver模拟浏览器.其中 window.navigator.webdriver 就是很重要的一个. 问题窥探 正常浏览器打开是这样的 模拟器打开是这样的 ChromeOptions options = null; IWebDriver driv

  • C#爬虫通过代理刷文章浏览量

    1.如何维护代理IP库? 想要使用代理IP,那就必须有一个一定数量.足够有效的代理ip库,在学习阶段,随便玩玩那就只能从免费的代理IP网站上抓取,没有一定数量的代理刷文章流浪量非常慢,首先就是要维护好自己的代理Ip库 之前用过的西刺代理.66ip比较靠谱,西祠好像有反扒,遇到过一次,不知道是西祠网站的问题还是反扒的策略,这两个网站每分钟抓取的能用的代理大概有2,3个,这已经算的上比较客观的了, data5u.快代理.ip3366网页端更新的非常少,而且有效性比较低,快代理抓取网页还必须设置Use

  • C#简单爬虫案例分享

    本文实例为大家分享了C#简单爬虫案例,供大家参考,具体内容如下 using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program

  • c#爬虫爬取京东的商品信息

    前言 在一个小项目中,需要用到京东的所有商品ID,因此就用c#写了个简单的爬虫. 在解析HTML中没有使用正则表达式,而是借助开源项目HtmlAgilityPack解析HTML. 下面话不多说了,来一起看看详细的介绍吧 一.下载网页HTML 首先我们写一个公共方法用来下载网页的HTML. 在写下载HTML方法之前,我们需要去查看京东网页请求头的相关信息,在发送请求时需要用到. public static string DownloadHtml(string url, Encoding encod

  • SpringBoot中使用Jsoup爬取网站数据的方法

    爬取数据 导入jar包 <properties> <java.version>1.8</java.version> <elasticsearch.version>7.6.1</elasticsearch.version> </properties> <dependencies> <dependency> <groupId>org.jsoup</groupId> <artifactI

  • python如何爬取网站数据并进行数据可视化

    前言 爬取拉勾网关于python职位相关的数据信息,并将爬取的数据已csv各式存入文件,然后对csv文件相关字段的数据进行清洗,并对数据可视化展示,包括柱状图展示.直方图展示.词云展示等并根据可视化的数据做进一步的分析,其余分析和展示读者可自行发挥和扩展包括各种分析和不同的存储方式等..... 一.爬取和分析相关依赖包 Python版本: Python3.6 requests: 下载网页 math: 向上取整 time: 暂停进程 pandas:数据分析并保存为csv文件 matplotlib:

  • C# 关于爬取网站数据遇到csrf-token的分析与解决

    需求 某航空公司物流单信息查询,是一个post请求.通过后台模拟POST HTTP请求发现无法获取页面数据,通过查看航空公司网站后,发现网站使用避免CSRF攻击机制,直接发挥40X错误. 关于CSRF 读者自行百度 网站HTTP请求分析 Headers Form Data 在head里包含了cookie 与 x-csrf-token  formdata 里包含了_csrf (与head里的值是一样的). 这里通过查看该网站的JS源代码发现_csrf 来自于网页的head标签里 猜测cookie与

  • python爬取网站数据保存使用的方法

    编码问题因为涉及到中文,所以必然地涉及到了编码的问题,这一次借这个机会算是彻底搞清楚了.问题要从文字的编码讲起.原本的英文编码只有0~255,刚好是8位1个字节.为了表示各种不同的语言,自然要进行扩充.中文的话有GB系列.可能还听说过Unicode和UTF-8,那么,它们之间是什么关系呢?Unicode是一种编码方案,又称万国码,可见其包含之广.但是具体存储到计算机上,并不用这种编码,可以说它起着一个中间人的作用.你可以再把Unicode编码(encode)为UTF-8,或者GB,再存储到计算机

  • 手把手教你用Node.js爬虫爬取网站数据的方法

    开始之前请先确保自己安装了Node.js环境,还没有安装的的童鞋请看一下安装教程...... https://www.jb51.net/article/113677.htm https://www.jb51.net/article/57687.htm 直接开始吧 1.在项目文件夹安装两个必须的依赖包 npm install superagent --save-dev SuperAgent(官网是这样解释的) -----SuperAgent is light-weight progressive

  • 利用Python爬虫爬取金融期货数据的案例分析

    目录 任务简介 解决步骤 代码实现 总结 大家好 我是政胤今天教大家爬取金融期货数据 任务简介 首先,客户原需求是获取https://hq.smm.cn/copper网站上的价格数据(注:获取的是网站上的公开数据),如下图所示: 如果以该网站为目标,则需要解决的问题是“登录”用户,再将价格解析为表格进行输出即可.但是,实际上客户核心目标是获取“沪铜CU2206”的历史价格,虽然该网站也有提供数据,但是需要“会员”才可以访问,而会员需要氪金...... 数据的价值!!! 鉴于,客户需求仅仅是“沪铜

  • nodejs实现爬取网站图片功能

    通过实例给大家讲解nodejs实现爬取网站图片功能,以下就是全部内容: 原理: 爬虫是最明显的IO密集型应用场景,显然用node,使得I/O等待开销小数据挖掘比较方便 借助express模块来搭建node服务 并使用request模块获取目标页面的html代码 下载cheerio模块对html代码做处理(cheerio类似jQuery的语法,所以好用又方便) 环境配置: npm install express request cheerio --save (1)引入各个模块 var http =

  • 一个月入门Python爬虫学习,轻松爬取大规模数据

    Python爬虫为什么受欢迎 如果你仔细观察,就不难发现,懂爬虫.学习爬虫的人越来越多,一方面,互联网可以获取的数据越来越多,另一方面,像 Python这样的编程语言提供越来越多的优秀工具,让爬虫变得简单.容易上手. 利用爬虫我们可以获取大量的价值数据,从而获得感性认识中不能得到的信息,比如: 知乎:爬取优质答案,为你筛选出各话题下最优质的内容. 淘宝.京东:抓取商品.评论及销量数据,对各种商品及用户的消费场景进行分析. 安居客.链家:抓取房产买卖及租售信息,分析房价变化趋势.做不同区域的房价分

  • Python实现爬虫爬取NBA数据功能示例

    本文实例讲述了Python实现爬虫爬取NBA数据功能.分享给大家供大家参考,具体如下: 爬取的网站为:stat-nba.com,这里爬取的是NBA2016-2017赛季常规赛至2017年1月7日的数据 改变url_header和url_tail即可爬取特定的其他数据. 源代码如下: #coding=utf-8 import sys reload(sys) sys.setdefaultencoding('utf-8') import requests import time import urll

  • python爬虫使用正则爬取网站的实现

    本文章的所有代码和相关文章, 仅用于经验技术交流分享,禁止将相关技术应用到不正当途径,滥用技术产生的风险与本人无关. 本文章是自己学习的一些记录.欢迎各位大佬点评! 首先 今天是第一天写博客,感受到了博客的魅力,博客不仅能够记录每天的代码学习情况,并且可以当作是自己的学习笔记,以便在后面知识点不清楚的时候前来复习.这是第一次使用爬虫爬取网页,这里展示的是爬取豆瓣电影top250的整个过程,欢迎大家指点. 这里我只爬取了电影链接和电影名称,如果想要更加完整的爬取代码,请联系我.qq 1540741

随机推荐