DotnetSpider(一)アーキテクチャの理解、応用、構築


**お知らせ:本文を転載する必要がある場合は、内容の出典を明記してください.**
このリンクは次のとおりです.http://www.cnblogs.com/grom/p/8931650.html 
 
本文:https://github.com/Grom-Li/DataSpider適用バージョン:2.5.0、2.5.1
 
最近は爬虫類を作っていて、以前はHttpWebRequestやWebClientを使っていましたが、便利で速いし、初心者にも向いていますが、捕獲任務の増加、マルチタスク、マルチライブラリなどの状況が現れるにつれて、優れた爬虫類のフレームワークを使う必要があります.そこでdotnetspiderに接触し始めました.
 
  
フレームワークの設計図を参考にしてdotnetspiderのNuGetパッケージを導入した後、私も基本的にこれに従って階層化しました.
  
 
Data.Spider-フロントページ(Winform、コンソール)やEntitySpider(EntitySpider)などを格納し、リクエストの開始点に相当します.
Spider.Downloader-要求などの情報をカプセル化し、カスタムクッキーなどを実現することができ、必要ではありません.
Spider.Processor-プロセッサ、IPageProcessorを継承してコンテンツをキャプチャする処理を実現
Spider.Pipe-パイプ、私はそれをProcessor処理後のコールバックと理解して、処理したデータを格納します(ファイル、データベースなど)
Spider.Entity-データ・エンティティ・クラス、SpiderEntityの継承
Spider.Command-いくつかのよく使われる共通のコマンド、私は今データのフォーマットのクラスを回転して保存して、バックグラウンドはJSクラスを実行して、SqlHelper(アーキテクチャがデータベースのパイプを持っているため、しばらく役に立ちません)など
このような階層化もソースコードの例を参照している.
  
ここ数日の試みに従って、本当にこのフレームワークが本当に柔軟であることを発見して、凹凸レンタカーの爬虫類を例にして、コードを載せます
エンティティークラス:
[EntityTable("CarWinsSpider", "AtzucheCar", EntityTable.Today)]
[EntitySelector(Expression = "$.data.content[*]", Type = SelectorType.JsonPath)]

public class AtzucheModel : SpiderEntity
{
  /// 
  ///     
  /// 
  [PropertyDefine(Expression = "$.carNo", Type = SelectorType.JsonPath)]
  public int carNo { get; set; }
  /// 
  ///   
  /// 
  //[ReplaceFormatter(NewValue = "", OldValue = "\r")]
  //[ReplaceFormatter(NewValue = "", OldValue = "\t")]
  //[ReplaceFormatter(NewValue = "", OldValue = " ")]
  //[ReplaceFormatter(NewValue = "", OldValue = "
")]   
//[ReplaceFormatter(NewValue = "", OldValue = "\"")]   //[ReplaceFormatter(NewValue = "", OldValue = " ")]   [PropertyDefine(Expression = "$.brand", Type = SelectorType.JsonPath)]   public string brand { get; set; }   ///
  ///   ///   [PropertyDefine(Expression = "$.carAddr", Type = SelectorType.JsonPath)]   public string carAddr { get; set; }   ///   ///   ///   [PropertyDefine(Expression = "$.type", Type = SelectorType.JsonPath)]   public string type { get; set; }   ///   ///   ///   [PropertyDefine(Expression = "$.sweptVolum", Type = SelectorType.JsonPath)]   public string sweptVolum { get; set; }   ///   ///   ///   [PropertyDefine(Expression = "$.coverPic", Type = SelectorType.JsonPath)]   public string coverPic { get; set; }   ///   ///   ///   [PropertyDefine(Expression = "$.dayPrice", Type = SelectorType.JsonPath)]   public int dayPrice { get; set; }   ///   ///   ///   [PropertyDefine(Expression = "$.distance", Type = SelectorType.JsonPath)]   public string distance { get; set; }   ///   ///   ///   [PropertyDefine(Expression = "$.evalScore", Type = SelectorType.JsonPath)]   public string evalScore { get; set; }   [PropertyDefine(Expression = "$.gbType", Type = SelectorType.JsonPath)]   public string gbType { get; set; }   ///   ///   ///   [PropertyDefine(Expression = "$.plateNum", Type = SelectorType.JsonPath)]   public string plateNum { get; set; }   [PropertyDefine(Expression = "$.replyTag", Type = SelectorType.JsonPath)]   public string replyTag { get; set; }   [PropertyDefine(Expression = "$.transCount", Type = SelectorType.JsonPath)]   public string transCount { get; set; }   ///   ///   ///   [PropertyDefine(Expression = "$.year", Type = SelectorType.JsonPath)]   public int year { get; set; }   [PropertyDefine(Expression = "$.isPrivilege", Type = SelectorType.JsonPath)]   public int isPrivilege { get; set; }   [PropertyDefine(Expression = "$.isRecommend", Type = SelectorType.JsonPath)]   public int isRecommend { get; set; }   [PropertyDefine(Expression = "$.isUpgrade", Type = SelectorType.JsonPath)]   public int isUpgrade { get; set; }   [PropertyDefine(Expression = "$.lat", Type = SelectorType.JsonPath)]   public string lat { get; set; }   [PropertyDefine(Expression = "$.lon", Type = SelectorType.JsonPath)]   public string lon { get; set; }   [PropertyDefine(Expression = "$.queryId", Type = SelectorType.JsonPath)]   public string queryId { get; set; }   [PropertyDefine(Expression = "$.supplyCarService", Type = SelectorType.JsonPath)]   public int supplyCarService { get; set; }   [PropertyDefine(Expression = "$.freeCarService", Type = SelectorType.JsonPath)]   public int freeCarService { get; set; }   [PropertyDefine(Expression = "$.isShenMaCar", Type = SelectorType.JsonPath)]   public int isShenMaCar { get; set; }   [PropertyDefine(Expression = "$.supportGetReturn", Type = SelectorType.JsonPath)]   public int supportGetReturn { get; set; }   [PropertyDefine(Expression = "$.confirmation", Type = SelectorType.JsonPath)]   public int confirmation { get; set; } }

 

  

/// 
////// 
[STAThread]
static void Main()
{
  var site = new Site
  {
    CycleRetryTimes = 1,
    SleepTime = 200,
    Headers = new Dictionary<string, string>()
    {
      {"Accept","application/json, text/javascript, */*; q=0.01" },
      {"Accept-Encoding","gzip, deflate" },
      {"gzip, deflate","zh-CN,zh;q=0.9" },
      {"X-Requested-With","XMLHttpRequest" },
      { "Referer", "http://www.atzuche.com/hz/car/search"},
      { "Connection","keep-alive" },
      { "Content-Type","application/json;charset=UTF-8" },
      { "Host","www.atzuche.com"},
      { "User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"}
    }
  };
  List resList = new List();

  Request res = new Request();
  //res.PostBody = $"id=7&j=%7B%22createMan%22%3A%2218273159100%22%2C%22createTime%22%3A1518433690000%2C%22row%22%3A5%2C%22siteUserActivityListId%22%3A8553%2C%22siteUserPageRowModuleId%22%3A84959%2C%22topids%22%3A%22%22%2C%22wherePhase%22%3A%221%22%2C%22wherePreferential%22%3A%220%22%2C%22whereUsertype%22%3A%220%22%7D&page={i}&shopid=83106681";//   post    
  res.Url = "http://www.atzuche.com/car/searchListMap/2?cityCode=330100&sceneCode=U002&filterCondition%5Blon%5D=120.219294&filterCondition%5Blat%5D=30.259258&filterCondition%5Bseq%5D=4&pageNum=1&pageSize=0";
  res.Method = System.Net.Http.HttpMethod.Get;

  resList.Add(res);

  var spider = DotnetSpider.Core.Spider.Create(site, new QueueDuplicateRemovedScheduler(), new AtzucheProcessor())
    .AddStartRequests(resList.ToArray())//      
    .AddPipeline(new AtzuchePipe());//    

  //----------------------------------
  spider.Monitor = new DotnetSpider.Core.Monitor.NLogMonitor();
  spider.Downloader = new AtzucheDownloader(); //new DotnetSpider.Core.Downloader.HttpClientDownloader();
  spider.ClearSchedulerAfterComplete = false;//           
  //----------------------------------

  spider.ThreadNum = 1;
  spider.Run();

  Console.WriteLine("Press any key to continue...");
  Console.Read();

}

 

Spider -> EntitySpider

 

  

/// 
////// 
[STAThread]
static void Main()
{
  AtzucheEntitySpider dDengEntitySpider = new AtzucheEntitySpider();
  dDengEntitySpider.AddPageProcessor(new AtzucheProcessor());//   
  dDengEntitySpider.AddPipeline(new AtzuchePipe());//  
  dDengEntitySpider.ThreadNum = 1;
  dDengEntitySpider.Run();
  Console.WriteLine("Press any key to continue...");
  Console.Read();
}

 

Downloader

, , Request

public class AtzucheDownloader : BaseDownloader
{
  protected override Page DowloadContent(Request request, ISpider spider)
  { 
    return new HttpClientDownloader().Download(request, spider);
  }
  
//v2.5.0+   protected override Task DowloadContent(Request request, ISpider spider)   {     return new HttpClientDownloader().Download(request, spider);   }
}

 
 
しい エンティティークラス(Mainにエンティティー を き む は )
public class AtzucheEntitySpider : EntitySpider
{
  protected override void MyInit(params string[] arguments)
  {
    AddPipeline(new SqlServerEntityPipeline("Server=.;Database=AuzucheSpider;uid=sa;pwd=123;MultipleActiveResultSets=true"));//               .      。。。
    AddStartUrl("http://www.atzuche.com/car/searchListMap/2?cityCode=330100&sceneCode=U002&filterCondition%5Blon%5D=120.219294&filterCondition%5Blat%5D=30.259258&filterCondition%5Bseq%5D=4&pageNum=1&pageSize=0");
    AddEntityType();//       ,                     ,          ,     Processor Pipe,       ,               
  }

public AtzucheEntitySpider() : base("AuzucheSpider", new Site
{
  CycleRetryTimes = 1,
  SleepTime = 200,
  Headers = new Dictionary<string, string>()
  {
    {"Accept","application/json, text/javascript, */*; q=0.01" },
    {"Accept-Encoding","gzip, deflate" },
    {"gzip, deflate","zh-CN,zh;q=0.9" },
    {"X-Requested-With","XMLHttpRequest" },
    { "Referer", "http://www.atzuche.com/hz/car/search"},
    { "Connection","keep-alive" },
    { "Content-Type","application/json;charset=UTF-8" },
    { "Host","www.atzuche.com"},
    { "User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"}
  }
  })
  {
  }

}

 
はプロセッサーです.
キャプチャされたデータは「AtzucheList」にカプセル され、Pipe でこの で されたデータを できます.
public class AtzucheProcessor : IPageProcessor
{
  public void Process(Page page, ISpider spider)
  {
    List list = new List();
    var html = page.Selectable.JsonPath("$.data.content").GetValue();
    list = JsonConvert.DeserializeObject>(html);
    page.AddResultItem("AtzucheList", list);
  }
}

 
にコールバックで、データを するコードをここに して します.
public class AtzuchePipe : BasePipeline
{
  public override void Process(IEnumerable resultItems, ISpider spider)
  {
    var result = new List();
    foreach (var resultItem in resultItems)
    {
      Console.WriteLine((resultItem.Results["AtzucheList"] as List).Count);
      foreach (var item in (resultItem.Results["AtzucheList"] as List))
      {
        result.Add(new AtzucheModel()
        {
          carNo = item.carNo
        });
        Console.WriteLine($"{item.carNo}:{item.type} ");
      }
    }
  }
}

 
:

 
に えば、このフレームワークは には で、 な き は たちに くの で を させることができます.
 

:https://www.cnblogs.com/grom/p/8931650.html