1、开发思路:入参根据apiSetting配置文件,分配静态文件存储地址,可实现不同站点的静态页生成功能。静态页生成功能使用无头浏览器生成,生成之后的字符串进行正则替换为固定地址,实现本地正常访问。

2、已发现问题:如果js在载入页面时进行某些重写dom操作,已用正则替换掉的动态路径代码,会被覆盖,导致本地访问无效。 这一点只能是站点开发那边重新对页面进行优化,从而避免这种情况。 但是这仅影响本地情况,如果静态页面部署到服务器,使用相对路径其实也不会影响。

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc; namespace QuartZNetService.Controllers
{
public class BuildStaticController : Controller
{
/// <summary>
/// 配置地址
/// </summary>
public static string jsonUrl = AppDomain.CurrentDomain.BaseDirectory + "apiSetting.json"; /// <summary>
/// 网站配置类
/// </summary>
public class HttpConfig
{
/// <summary>
/// 网站cookie信息
/// </summary>
public string Cookie { get; set; } /// <summary>
/// 页面Referer信息
/// </summary>
public string Referer { get; set; } /// <summary>
/// 默认(text/html)
/// </summary>
public string ContentType { get; set; } public string Accept { get; set; } public string AcceptEncoding { get; set; } /// <summary>
/// 超时时间(毫秒)默认100000
/// </summary>
public int Timeout { get; set; } public string UserAgent { get; set; } /// <summary>
/// POST请求时,数据是否进行gzip压缩
/// </summary>
public bool GZipCompress { get; set; } public bool KeepAlive { get; set; } public string CharacterSet { get; set; } public HttpConfig()
{
this.Timeout = ;
this.ContentType = "text/html; charset=" + Encoding.UTF8.WebName; this.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36";
this.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
this.AcceptEncoding = "gzip,deflate";
this.GZipCompress = false;
this.KeepAlive = true;
this.CharacterSet = "UTF-8";
}
} /// <summary>
/// 利用phantomjs 爬取AJAX加载完成之后的页面
/// JS脚本刷新时间间隔为3秒,防止页面AJAX请求时间过长导致数据无法获取
/// </summary>
/// <param name="url"></param>
/// <param name="sitId">站点ID 用于配置站点盘符位置</param>
/// <param name="type">存储文件夹 可为空</param>
/// <param name="config"></param>
/// <param name="interval"></param>
/// <returns></returns>
public JsonResult Do(string url, string sitId, string typeId, string fileName, HttpConfig config, int interval = )
{
try
{
var readjson = Readjson(sitId, typeId);
JObject jo = (JObject)JsonConvert.DeserializeObject(readjson.ToString());
var sitUrl = jo["url"].ToString();
var folder = jo["folder"].ToString(); string path = System.AppDomain.CurrentDomain.BaseDirectory.ToString();
ProcessStartInfo start = new ProcessStartInfo(path + @"webTools\phantomjs.exe");//设置运行的命令行文件问ping.exe文件,这个文件系统会自己找到
start.WorkingDirectory = path + @"webTools\"; //设置命令参数
string commond = string.Format("{0} {1} {2} {3} {4} {5}", path + @"webTools\codes.js", url, interval, config.UserAgent, config.Accept, config.Referer);
start.Arguments = commond;
StringBuilder sb = new StringBuilder();
start.CreateNoWindow = true;//不显示dos命令行窗口
start.RedirectStandardOutput = true;//
start.RedirectStandardInput = true;//
start.UseShellExecute = false;//是否指定操作系统外壳进程启动程序
Process p = Process.Start(start);
StreamReader reader = new StreamReader(p.StandardOutput.BaseStream,Encoding.UTF8);//截取输出流 //正则匹配完整外链js
Regex myreg = new Regex("(http|https)://(?<domain>[^(:|/]*)");
Match myMatch = myreg.Match(url);
var reader_txt = reader.ReadToEnd();
StringBuilder reader_write = new StringBuilder(reader_txt);
Regex regex = new Regex("<script[^>]*?src=\"([^>]*?)\"[^>]*?>", RegexOptions.IgnoreCase);//正则匹配外链html代码
MatchCollection userMatchColl = regex.Matches(reader_txt); //自定义替换区域 bg
if (userMatchColl.Count > )
{
foreach (Match matchItem in userMatchColl)
{
if (reader_write.ToString().IndexOf(matchItem.Value) > && matchItem.Value.IndexOf("xxx.cn") == -)
{
reader_write.Insert(
(reader_write.ToString().IndexOf(matchItem.Value) + matchItem.Value.IndexOf("src=\"") + ("src=\"").Length),
"https://www.xxx.cn"
);
}
}
}
reader_write.Replace("src=\"//", "src=\"https://");//增加https
reader_write.Replace("href=\"//", "href=\"https://");//增加https
reader_write.Replace("\"//images", "\"https://images");//增加https
//自定义替换区域 end StreamWriter write = new StreamWriter(sitUrl + folder + "//" + fileName, false, Encoding.UTF8);//写入文件
write.Write(reader_write);
write.Flush();
write.Close();
p.WaitForExit();//等待程序执行完退出进程
p.Close();//关闭进程
reader.Close();//关闭流
return Json(true, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(ex.Message, JsonRequestBehavior.AllowGet);
}
} /// <summary>
/// 读取配置文件
/// </summary>
/// <param name="sitId"></param>
/// <param name="typeId"></param>
/// <returns></returns>
public static string Readjson(string sitId, string typeId)
{
string url = "";
string folder = "";
using (System.IO.StreamReader file = System.IO.File.OpenText(jsonUrl))
{
using (JsonTextReader reader = new JsonTextReader(file))
{
JObject JObject = (JObject)JToken.ReadFrom(reader);
//取站点路径
var sit = JObject["sit"];
foreach (JObject item in sit)
{
if (item["sitId"].ToString() == sitId)
{
url = item["sitUrl"].ToString();
}
}
//取文件夹名称 可为空
var type = JObject["type"];
foreach (JObject item in type)
{
if (item["typeId"].ToString() == typeId)
{
folder = item["folder"].ToString();
}
}
}
}
return JsonConvert.SerializeObject(new
{
url = url,
folder = folder
});
}
}
}

codes.js 配置

var page = require('webpage').create(), system = require('system');
var url = system.args[];
var interval = system.args[];
var settings = {
timeout: interval,
encoding: "UTF-8",
operation: "GET",
headers: {
"User-Agent": system.args[],
"Accept": system.args[],
"Accept-Language": "zh-CN,en;q=0.7,en-US;q=0.3",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": ,
"Connection": "keep-alive",
"Pragma": "no-cache",
"Cache-Control": "no-cache",
"Referer": system.args[]
}
}
page.settings = settings;
page.open(url, function (status) {
phantom.outputEncoding = "UTF-8";
if (status !== 'success') {
console.log('Unable to post!');
phantom.exit();
} else {
setTimeout(function () {
console.log(page.content);
phantom.exit();
}, interval);
}
});

apiSetting.json 配置

{
"sit": [
{
"sitId": "",
"sitUrl": "D://"
},
{
"sitId": "",
"sitUrl": "D://"
}
],
"type": [
{
"typeId": "",
"folder": "zmPC"
},
{
"typeId": "",
"folder": "zmCP"
}
]
}

C#使用phantomjs,爬取AJAX加载完成之后的页面的更多相关文章

  1. Python+Selenium爬取动态加载页面(2)

    注: 上一篇<Python+Selenium爬取动态加载页面(1)>讲了基本地如何获取动态页面的数据,这里再讲一个稍微复杂一点的数据获取全国水雨情网.数据的获取过程跟人手动获取过程类似,所 ...

  2. Python+Selenium爬取动态加载页面(1)

    注: 最近有一小任务,需要收集水质和水雨信息,找了两个网站:国家地表水水质自动监测实时数据发布系统和全国水雨情网.由于这两个网站的数据都是动态加载出来的,所以我用了Selenium来完成我的数据获取. ...

  3. Scrapy 框架 使用 selenium 爬取动态加载内容

    使用 selenium 爬取动态加载内容 开启中间件 DOWNLOADER_MIDDLEWARES = { 'wangyiPro.middlewares.WangyiproDownloaderMidd ...

  4. 爬虫再探实战(三)———爬取动态加载页面——selenium

    自学python爬虫也快半年了,在目前看来,我面临着三个待解决的爬虫技术方面的问题:动态加载,多线程并发抓取,模拟登陆.目前正在不断学习相关知识.下面简单写一下用selenium处理动态加载页面相关的 ...

  5. Python 爬取异步加载的数据

    在我们的工作中,可能会遇到这样的情况:我们需要爬取的数据是通过ajax异步加载的,这样的话通过requests得到的只是一个静态页面,而我们需要的是ajax动态加载的数据! 那我们应该怎么办呢??? ...

  6. Python爬虫爬取异步加载的数据

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:努力努力再努力 爬取qq音乐歌手数据接口数据 https://y.qq ...

  7. 爬虫再探实战(四)———爬取动态加载页面——请求json

    还是上次的那个网站,就是它.现在尝试用另一种办法——直接请求json文件,来获取要抓取的信息. 第一步,检查元素,看图如下: 过滤出JS文件,并找出包含要抓取信息的js文件,之后就是构造request ...

  8. appendHTML方法ajax加载更多评论实例页面

    //在后添加 <script>var appendHTML = function(el, html) { var divTemp = document.createElement(&quo ...

  9. Jsoup配合 htmlunit 爬取异步加载的网页

    加入 jsoup 和 htmlunit 的依赖 <dependency> <groupId>org.jsoup</groupId> <artifactId&g ...

随机推荐

  1. the requested PHP extension dom is missing from your system

    composer  出错 the requested PHP extension dom is missing from your system 解决办法    yum install  php70w ...

  2. Vue于React特性对比(三)

    最近重学React,再次和vue做了对比. 一,为官方插件提供便利的第三方插件横行 React仅仅是一个ui框架.虽然官方提供了redux,react-router:但也有第三方的redux-thun ...

  3. MapReduce On Yarn的配置详解和日常维护

    MapReduce On Yarn的配置详解和日常维护 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MapReduce运维概述 MapReduce on YARN的运维主要是 ...

  4. hadoop1.2.1安装配置

    原文地址 环境:ubuntu13 使用的用户为普通用户.如:用户ru jdk安装略 1.安装ssh (1) sudo apt-get install openssh-server (2)配置ssh面密 ...

  5. Qt编写自定义控件33-图片切换动画

    一.前言 在很多看图软件中,切换图片的时候可以带上动画过渡或者切换效果,显得更人性化,其实主要还是炫一些,比如百叶窗.透明度变化.左下角飞入等,无论多少种效果,核心都是围绕QPainter来进行,将各 ...

  6. layer弹框层学习笔记

    这里对layer的笔记只是大概记录一下其使用过程,以便后续使用时快速回顾,更详细使用及介绍参考官网实例.链接在本文末 一 .初步了解layer-弹层之美 layer是一款近年来备受青睐的web弹层组件 ...

  7. [!] The version of CocoaPods used to generate the lockfile (1.4.0.beta.1) is higher than the version of the current executable (1.3.0.beta.1). Incompatibility issues may arise.

    今天在看一个开源Demo代码的时候,需要执行pod install命令,直接报错如下: 解决方法: 执行:pod update 命令更新资源库即可.

  8. Flutter 获取网络数据及渲染列表

    还是通过Dio包调用远程接口获取数据,这里返回值为一个Future,这个对象支持一个等待回掉方法then. 示例代码如下: import 'package:flutter/material.dart' ...

  9. 最新 携程java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.携程等10家互联网公司的校招Offer,因为某些自身原因最终选择了携程.6.7月主要是做系统复习.项目复盘.LeetCode ...

  10. pycharm2017注册码

    BIG3CLIK6F-eyJsaWNlbnNlSWQiOiJCSUczQ0xJSzZGIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lIjoiI ...