From ec0e040509579097de50bbd89a5a6b698e615507 Mon Sep 17 00:00:00 2001 From: Nice <2017875139@qq.com> Date: Thu, 25 Nov 2021 15:44:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ReptileCaptures.sln | 25 +++ ReptileCaptures/DTO/ImagesInfo.cs | 11 ++ ReptileCaptures/DTO/Page.cs | 15 ++ ReptileCaptures/DTO/SearchRegionTree.cs | 19 +++ ReptileCaptures/Entites/Entity.cs | 38 +++++ ReptileCaptures/Entites/ODbContext.cs | 48 ++++++ ReptileCaptures/Entites/ReptileCapture.cs | 33 ++++ ReptileCaptures/Entites/ReptileRegion.cs | 31 ++++ ReptileCaptures/Manage.cs | 52 +++++++ ReptileCaptures/Program.cs | 142 ++++++++++++++++++ .../IReptileCaptureRespository.cs | 23 +++ .../Repositories/IReptileRegionRespository.cs | 20 +++ .../Repositories/ReptileCaptureRespository.cs | 35 +++++ .../Repositories/ReptileRegionRespository.cs | 47 ++++++ ReptileCaptures/ReptileCaptures.csproj | 27 ++++ ReptileCaptures/appsettings.json | 4 + 16 files changed, 570 insertions(+) create mode 100644 ReptileCaptures.sln create mode 100644 ReptileCaptures/DTO/ImagesInfo.cs create mode 100644 ReptileCaptures/DTO/Page.cs create mode 100644 ReptileCaptures/DTO/SearchRegionTree.cs create mode 100644 ReptileCaptures/Entites/Entity.cs create mode 100644 ReptileCaptures/Entites/ODbContext.cs create mode 100644 ReptileCaptures/Entites/ReptileCapture.cs create mode 100644 ReptileCaptures/Entites/ReptileRegion.cs create mode 100644 ReptileCaptures/Manage.cs create mode 100644 ReptileCaptures/Program.cs create mode 100644 ReptileCaptures/Repositories/IReptileCaptureRespository.cs create mode 100644 ReptileCaptures/Repositories/IReptileRegionRespository.cs create mode 100644 ReptileCaptures/Repositories/ReptileCaptureRespository.cs create mode 100644 ReptileCaptures/Repositories/ReptileRegionRespository.cs create mode 100644 ReptileCaptures/ReptileCaptures.csproj create mode 100644 ReptileCaptures/appsettings.json diff --git a/ReptileCaptures.sln b/ReptileCaptures.sln new file mode 100644 index 0000000..3fdc2e2 --- /dev/null +++ b/ReptileCaptures.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReptileCaptures", "ReptileCaptures\ReptileCaptures.csproj", "{6C8B6841-164D-4E1C-96E2-112A8EB3209A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6C8B6841-164D-4E1C-96E2-112A8EB3209A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6C8B6841-164D-4E1C-96E2-112A8EB3209A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6C8B6841-164D-4E1C-96E2-112A8EB3209A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6C8B6841-164D-4E1C-96E2-112A8EB3209A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3C52CE1A-23FF-4447-B7B0-26C6704DC9F9} + EndGlobalSection +EndGlobal diff --git a/ReptileCaptures/DTO/ImagesInfo.cs b/ReptileCaptures/DTO/ImagesInfo.cs new file mode 100644 index 0000000..b2d3508 --- /dev/null +++ b/ReptileCaptures/DTO/ImagesInfo.cs @@ -0,0 +1,11 @@ +namespace PC +{ + internal class ImagesInfo + { + public string CaptureUrl { get; set; } + public string CamName { get; set; } + public string CamIndexCode { get; set; } + public string CaptureId { get; set; } + public DateTime CaptureTime { get; set; } + } +} diff --git a/ReptileCaptures/DTO/Page.cs b/ReptileCaptures/DTO/Page.cs new file mode 100644 index 0000000..532a41b --- /dev/null +++ b/ReptileCaptures/DTO/Page.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PC +{ + internal class Page + { + public string Code { get; set; } + public PageSource Data { get; set; } + public string Msg { get; set; } + } +} diff --git a/ReptileCaptures/DTO/SearchRegionTree.cs b/ReptileCaptures/DTO/SearchRegionTree.cs new file mode 100644 index 0000000..186affb --- /dev/null +++ b/ReptileCaptures/DTO/SearchRegionTree.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PC +{ + public class SearchRegionTree + { + public List Rows { get; set; } + } + public class SearchRegion + { + public string Id { get; set; } + public string PId { get; set; } + public string Name { get; set; } + } +} diff --git a/ReptileCaptures/Entites/Entity.cs b/ReptileCaptures/Entites/Entity.cs new file mode 100644 index 0000000..9fb11ce --- /dev/null +++ b/ReptileCaptures/Entites/Entity.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace PC.Entites +{ + internal class Entity + { + private static readonly RandomNumberGenerator RandomNumberGenerator = RandomNumberGenerator.Create(); + /// + /// 主键Id + /// + public Guid Id { get; private set; } + protected Guid NewId() + { + var randomBytes = new byte[10]; + RandomNumberGenerator.GetBytes(randomBytes); + + long timestamp = DateTime.UtcNow.Ticks / 10000L; + + byte[] timestampBytes = BitConverter.GetBytes(timestamp); + if (BitConverter.IsLittleEndian) + { + Array.Reverse(timestampBytes); + } + + byte[] guidBytes = new byte[16]; + Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10); + Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6); + + Id = new Guid(guidBytes); + return Id; + } + } +} diff --git a/ReptileCaptures/Entites/ODbContext.cs b/ReptileCaptures/Entites/ODbContext.cs new file mode 100644 index 0000000..029c781 --- /dev/null +++ b/ReptileCaptures/Entites/ODbContext.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PC.Entites +{ + internal class ODbContext : DbContext + { + private readonly IConfiguration Configuration; + public ODbContext(IConfiguration configuration) + { + Configuration = configuration; + } + public DbSet ReptileCaptures { get; set; } + public DbSet ReptileRegions { get; set; } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlServer(Configuration["SqlConnection"]); + base.OnConfiguring(optionsBuilder); + } + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(o => + { + o.ToTable(nameof(ReptileCapture)); + o.HasKey(o => o.Id); + o.Property(o => o.RegionId).HasColumnType("nvarchar(50)").HasColumnName("RegionId"); + o.Property(o => o.CaptureTime).HasColumnType("datetime").HasColumnName("CaptureTime"); + o.Property(o => o.CaptureUrl).HasColumnType("nvarchar(100)").HasColumnName("CaptureUrl"); + o.Property(o => o.CaptureId).HasColumnType("nvarchar(50)").HasColumnName("CaptureId"); + }); + + modelBuilder.Entity(o => + { + o.ToTable(nameof(ReptileRegion)); + o.HasKey(o => o.Id); + o.Property(o => o.RegionId).HasColumnType("nvarchar(50)").HasColumnName("RegionId"); + o.Property(o => o.RegionPId).HasColumnType("nvarchar(50)").HasColumnName("RegionPId"); + o.Property(o => o.RegionName).HasColumnType("nvarchar(50)").HasColumnName("RegionName"); + }); + base.OnModelCreating(modelBuilder); + } + } +} diff --git a/ReptileCaptures/Entites/ReptileCapture.cs b/ReptileCaptures/Entites/ReptileCapture.cs new file mode 100644 index 0000000..c003ef5 --- /dev/null +++ b/ReptileCaptures/Entites/ReptileCapture.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PC.Entites +{ + internal class ReptileCapture : Entity + { + /// + /// 图片地址 + /// + public string CaptureUrl { get; set; } + /// + /// 区域Id + /// + public string RegionId { get; set; } + /// + /// 图片时间 + /// + public DateTime CaptureTime { get; set; } + /// + /// 图片Id + /// + public string CaptureId { get; set; } + public ReptileCapture Create() + { + NewId(); + return this; + } + } +} diff --git a/ReptileCaptures/Entites/ReptileRegion.cs b/ReptileCaptures/Entites/ReptileRegion.cs new file mode 100644 index 0000000..52130f8 --- /dev/null +++ b/ReptileCaptures/Entites/ReptileRegion.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PC.Entites +{ + internal class ReptileRegion : Entity + { + /// + /// 区域父Id + /// + public string RegionPId { get; set; } + /// + /// 区域名称 + /// + public string RegionName { get; set; } + /// + /// 区域Id + /// + public string RegionId { get; set; } + + + public ReptileRegion Create() + { + NewId(); + return this; + } + } +} diff --git a/ReptileCaptures/Manage.cs b/ReptileCaptures/Manage.cs new file mode 100644 index 0000000..e0af451 --- /dev/null +++ b/ReptileCaptures/Manage.cs @@ -0,0 +1,52 @@ +using Microsoft.Extensions.Configuration; +using OpenQA.Selenium; + +namespace PC +{ + public class Manage + { + /// 登录 + public static void Login(IWebDriver driver) + { + Thread.Sleep(3000); + driver.FindElement(By.CssSelector("#app > div > div > div.container.login-page > div.container.fullscreen-layout > div.m-main-content > div > div > form > div:nth-child(1) > div > div.login-input.has-prepend.el-input.el-input--prefix > input")). + SendKeys("admin"); + driver.FindElement(By.CssSelector("#app > div > div > div.container.login-page > div.container.fullscreen-layout > div.m-main-content > div > div > form > div:nth-child(2) > div > div.login-input.has-prepend.el-input.el-input--prefix > input")). + SendKeys("hik12345+"); + driver.FindElement(By.CssSelector("#app > div > div > div.container.login-page > div.container.fullscreen-layout > div.m-main-content > div > div > form > div:nth-child(5) > div > button")). + Click(); + Thread.Sleep(5000); + + } + + //查询 + public static void Query(IWebDriver driver) + { + Thread.Sleep(3000); + driver.FindElement(By.XPath(@"//*[@id=""app""]/div/section/aside/div/div/div/div/div[2]/button")).Click(); + Thread.Sleep(3000); + } + + //点击城市复选框 + public static void ClickCity(IWebDriver driver) + { + Thread.Sleep(3000); + ////*[@id="app"]/div/section/aside/div/div/div/div/div[1]/div[3]/div[1]/div[1]/div/div/div/div[1]/label + driver.FindElement(By.XPath(@"//*[@id=""app""]/div/section/aside/div/div/div/div/div[1]/div[3]/div[1]/div[1]/div/div/div/div[1]/label")).Click(); + Thread.Sleep(3000); + } + + public static async Task DownImageNameAsync(IConfiguration configuration, string url) + { + using HttpClient httpClient = new(); + var imageResponse = await httpClient.GetAsync(url); + imageResponse.EnsureSuccessStatusCode(); + using Stream stream = imageResponse.Content.ReadAsStream(); + string imageName = @$"{Guid.NewGuid()}.jpg"; + string path = configuration["Path"]; + using Stream saveStream = File.Create($"{path}\\{imageName}"); + stream.CopyTo(saveStream); + return imageName; + } + } +} diff --git a/ReptileCaptures/Program.cs b/ReptileCaptures/Program.cs new file mode 100644 index 0000000..61756c1 --- /dev/null +++ b/ReptileCaptures/Program.cs @@ -0,0 +1,142 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json; +using OpenQA.Selenium; +using OpenQA.Selenium.Chrome; +using OpenQA.Selenium.DevTools.V95; +using OpenQA.Selenium.DevTools.V95.Network; +using PC; +using PC.Entites; +using PC.Repositories; +using System.Collections.ObjectModel; + +IServiceCollection serviceCollection = new ServiceCollection(); +serviceCollection.AddTransient(o => new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .Build() +); +serviceCollection.AddDbContext(); +serviceCollection.AddTransient(); +serviceCollection.AddTransient(); +IServiceProvider service = serviceCollection.BuildServiceProvider(); + +IReptileCaptureRespository reptileCaptureRespository = service.GetService(); +IReptileRegionRespository reptileRegionRespository = service.GetService(); +ChromeOptions options = new(); +options.AddArgument("--auto-open-devtools-for-tabs"); +options.AddArgument("log-level=3"); +int successCount = 1; +int errorCount = 1; +Console.WriteLine($"项目运行"); +while (true) +{ + try + { + Console.WriteLine($"爬虫启动运行{successCount}次"); + using (ChromeDriver driver = new(options)) + { + driver.Manage().Window.Maximize(); + driver.Navigate().GoToUrl("http://39.98.181.39/portal/ui/login?service=http%3A%2F%2F39.98.181.39%3A80%2Fportal%2F"); + var domain = driver.GetDevToolsSession().GetVersionSpecificDomains(); + await domain.Network.Enable(new EnableCommandSettings()); + await domain.Network.EnableReportingApi(new EnableReportingApiCommandSettings()); + //登录 + Manage.Login(driver); + List requestWillBeSentEventArgs = new(); + domain.Network.RequestWillBeSent += (se, e) => + { + if (e.Type == OpenQA.Selenium.DevTools.V95.Network.ResourceType.XHR) + { + if (e.Request.Method == "GET") + { + if (e.Request.Url.Contains("vms/ui/unit/fetchUnitNodesByParent") || + e.Request.Url.Contains("vms/ui/camera/fetchCaptureCamsPageQuery")) + { + requestWillBeSentEventArgs.Add(e); + } + } + else if (e.Request.Method == "POST") + { + if (e.Request.Url.Contains("vms/ui/captureInfo/fetchCaptureInfoByCam")) + { + requestWillBeSentEventArgs.Add(e); + } + } + } + }; + //图片查询 + driver.FindElement(By.CssSelector("#bottomWrapper > div.page.sub-page-container.page-show > div.container.home-page.is-overdue > div > div > div > div.list-content > div.list-nav.el-scrollbar.has-gutter > div.el-nav-scrollbar__wrap.el-scrollbar__wrap > div > div > div.m-list-ctn > div:nth-child(3) > div.content.cf > div:nth-child(3) > img")). + Click(); + //进入 + IWebElement iframe = driver.FindElement(By.CssSelector("#iframe000026")); + driver.SwitchTo().Frame(iframe); + + //点击城市复选框 + Manage.ClickCity(driver); + //查询 + Manage.Query(driver); + + ReadOnlyCollection selectRegionTrees = driver.FindElements( + By.XPath(@"//*[@id=""app""]/div/section/aside/div/div/div/div/div[1]/div[3]/div[1]/div[1]/div/div/div/div[2]/div")); + foreach (IWebElement selectRegionTree in selectRegionTrees) + { + //点击下拉框 展示节点 + selectRegionTree.FindElement(By.XPath("div/span[1]")).Click(); + Thread.Sleep(1000); + selectRegionTree.FindElement(By.XPath("div/span[1]")).Click(); + } + + + + foreach (var e in requestWillBeSentEventArgs) + { + if (e.Request.Method == "GET") + { + if (e.Request.Url.Contains("vms/ui/unit/fetchUnitNodesByParent") || + e.Request.Url.Contains("vms/ui/camera/fetchCaptureCamsPageQuery")) + { + var responseBody = await domain.Network.GetResponseBody(new GetResponseBodyCommandSettings() + { + RequestId = e.RequestId + }); + Page page = JsonConvert.DeserializeObject>(responseBody.Body); + + foreach (var Row in page.Data.Rows) + { + await reptileRegionRespository.AddOrUpdateRegionAsync(new IReptileRegionRespository + .RegionDTO(Row.PId, Row.Name, Row.Id)); + } + + } + } + else if (e.Request.Method == "POST") + { + if (e.Request.Url.Contains("vms/ui/captureInfo/fetchCaptureInfoByCam")) + { + var responseBody = await domain.Network.GetResponseBody(new GetResponseBodyCommandSettings() + { + RequestId = e.RequestId + }); + Page> page = JsonConvert.DeserializeObject>>(responseBody.Body); + foreach (var data in page.Data) + { + await reptileCaptureRespository.NotNullAddCaptureAsync(new IReptileCaptureRespository + .CaptureDTO(data.CaptureUrl, data.CamIndexCode, data.CaptureTime, data.CaptureId)); + } + } + } + } + } + Console.WriteLine(@$"任务完成{successCount}次,延迟1800000毫秒,约半小时"); + successCount++; + Thread.Sleep(1800000); + } + catch (Exception ex) + { + Console.WriteLine($"进入异常{errorCount}次"); + errorCount++; + } +} + diff --git a/ReptileCaptures/Repositories/IReptileCaptureRespository.cs b/ReptileCaptures/Repositories/IReptileCaptureRespository.cs new file mode 100644 index 0000000..cb131f5 --- /dev/null +++ b/ReptileCaptures/Repositories/IReptileCaptureRespository.cs @@ -0,0 +1,23 @@ +namespace PC.Repositories +{ + internal interface IReptileCaptureRespository + { + /// + /// 添加请求参数 + /// + /// 图片地址 + /// 区域Id + /// 图片日期 + /// 图片Id + record CaptureDTO( + string CaptureUrl, + string RegionId, + DateTime CaptureTime, + string CaptureId); + /// + /// 添加图片 + /// + Task NotNullAddCaptureAsync(CaptureDTO captureDTO); + + } +} diff --git a/ReptileCaptures/Repositories/IReptileRegionRespository.cs b/ReptileCaptures/Repositories/IReptileRegionRespository.cs new file mode 100644 index 0000000..9b88461 --- /dev/null +++ b/ReptileCaptures/Repositories/IReptileRegionRespository.cs @@ -0,0 +1,20 @@ +namespace PC.Repositories +{ + internal interface IReptileRegionRespository + { + /// + /// 区域 + /// + /// 区域父Id + /// 区域名称 + /// 区域Id + record RegionDTO( + string RegionPId, + string RegionName, + string RegionId); + /// + /// 添加或者修改 区域 + /// + Task AddOrUpdateRegionAsync(RegionDTO regionDTO); + } +} diff --git a/ReptileCaptures/Repositories/ReptileCaptureRespository.cs b/ReptileCaptures/Repositories/ReptileCaptureRespository.cs new file mode 100644 index 0000000..31aaa5e --- /dev/null +++ b/ReptileCaptures/Repositories/ReptileCaptureRespository.cs @@ -0,0 +1,35 @@ +using Microsoft.Extensions.Configuration; +using PC.Entites; + +namespace PC.Repositories +{ + internal class ReptileCaptureRespository : IReptileCaptureRespository + { + private readonly ODbContext _oDbContext; + public ReptileCaptureRespository(ODbContext oDbContext, IConfiguration configuration) + { + _oDbContext = oDbContext; + Configuration = configuration; + } + private readonly IConfiguration Configuration; + + public async Task AddCaptureAsync(IReptileCaptureRespository.CaptureDTO captureDTO) + { + string imageURL = await Manage.DownImageNameAsync(Configuration, captureDTO.CaptureUrl); + await _oDbContext.ReptileCaptures.AddAsync(new ReptileCapture() + { + CaptureTime = captureDTO.CaptureTime, + RegionId = captureDTO.RegionId, + CaptureUrl = imageURL, + CaptureId = captureDTO.CaptureId, + }.Create()); + _oDbContext.SaveChanges(); + } + public async Task NotNullAddCaptureAsync(IReptileCaptureRespository.CaptureDTO captureDTO) + { + var region = _oDbContext.ReptileCaptures.FirstOrDefault(o => o.CaptureId == captureDTO.CaptureId); + if (region is null) + await AddCaptureAsync(captureDTO); + } + } +} diff --git a/ReptileCaptures/Repositories/ReptileRegionRespository.cs b/ReptileCaptures/Repositories/ReptileRegionRespository.cs new file mode 100644 index 0000000..f4dcece --- /dev/null +++ b/ReptileCaptures/Repositories/ReptileRegionRespository.cs @@ -0,0 +1,47 @@ +using PC.Entites; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PC.Repositories +{ + internal class ReptileRegionRespository : IReptileRegionRespository + { + private readonly ODbContext _oDbContext; + public ReptileRegionRespository(ODbContext oDbContext) + { + _oDbContext = oDbContext; + } + + public async Task AddRegionAsync(IReptileRegionRespository.RegionDTO regionDTO) + { + await _oDbContext.ReptileRegions.AddAsync(new ReptileRegion() + { + RegionId = regionDTO.RegionId, + RegionName = regionDTO.RegionName, + RegionPId = regionDTO.RegionPId, + }.Create()); + _oDbContext.SaveChanges(); + } + + public async Task AddOrUpdateRegionAsync(IReptileRegionRespository.RegionDTO regionDTO) + { + var region = _oDbContext.ReptileRegions.FirstOrDefault(o => o.RegionId == regionDTO.RegionId); + if (region != null) + { + if (region.RegionName != regionDTO.RegionName) + { + region.RegionName = regionDTO.RegionName; + _oDbContext.ReptileRegions.Update(region); + await _oDbContext.SaveChangesAsync(); + } + } + else + { + await AddRegionAsync(regionDTO); + } + } + } +} diff --git a/ReptileCaptures/ReptileCaptures.csproj b/ReptileCaptures/ReptileCaptures.csproj new file mode 100644 index 0000000..5c5e6d1 --- /dev/null +++ b/ReptileCaptures/ReptileCaptures.csproj @@ -0,0 +1,27 @@ + + + + Exe + net6.0 + enable + + + + + + + + + + + + + + + + + Always + + + + diff --git a/ReptileCaptures/appsettings.json b/ReptileCaptures/appsettings.json new file mode 100644 index 0000000..76ae280 --- /dev/null +++ b/ReptileCaptures/appsettings.json @@ -0,0 +1,4 @@ +{ + "SqlConnection": "Data Source=192.168.2.166;Initial Catalog=InsectTrappingDb_Business;User ID=sa;Password=Athlon123;", + "Path": "D:\\IotSystem\\InsectTrapping.Business.Web\\wwwroot\\Upload\\ReptileCaptures" +}