分享 - Hybrid 开发将博客园集成到自己的网站中 - 效果高大上 :)

原文链接:http://www.cnblogs.com/iamzyf/p/3515889.html

其实问题很简单: 我的产品页面在 http://www.gdtsearch.com/products.spiderstudio.docapi.htm, 这是一个静态页面; 而我所有的技术博客都在博客园中. 为了让访问者能够直接在产品页面中看到我最新的技术博客, 我将博客页面用IFrame嵌入到了产品页面中:

这效果简直是,,, 矮矬穷, 如何叫人能够忍受? 于是乎一个改造工程开始了, 基本思路简单清晰:

1. 用SS编写采集脚本, 并编译成DLL

2. 用NodeJS编写一个WebApi, 其中调用上面的DLL来获取数据, 然后提供JSONP的结果集

3. 在产品页面中用jquery.Ajax来异步加载数据

开始实施:

首先打开SS编写采集脚本: (http://www.gdtsearch.com/products.spiderstudio.docapi.htm)

public void Run()
{
    Logger.ClearAll();
    var docs = GetAllDoc();
    foreach(var d in docs)
    {
        Logger.Log(d.Title);
        Logger.Log(d.Url);
        Logger.Log(d.PubDate);
        Logger.Log(d.ReadCount.ToString());
        Logger.Log(d.Summary);
    }
}

public List<Doc> GetAllDoc() 
{ 
    Default.Navigate("about:blank");
    Default.Ready();
    Default.Navigate("http://www.cnblogs.com/iamzyf/category/498344.html");
    Default.Ready();
    Logger.Log(string.Format("开始处理 {0} ...", Default.Url.ToString()));
    var rows = Default.SelectNodes("div.entrylistItem");
    List<Doc> result = new List<Doc>();
    Logger.Log(string.Format("共加载{0}篇文章.", result.Count));
    foreach(var r in rows)
    {
        var doc = new Doc();
        doc.Title = r.SelectSingleNode("div.entrylistPosttitle>a").Text();
        doc.Url = r.SelectSingleNode("div.entrylistPosttitle>a").Attr("href");
        doc.Summary = r.SelectSingleNode("div.entrylistPostSummary").Text().Replace("阅读全文", "").Replace("摘要: ", "").Trim();
        doc.PubDate = r.SelectSingleNode("div.entrylistItemPostDesc>a:eq(0)").Text();
        doc.ReadCount = Regex.Match(r.SelectSingleNode("div.entrylistItemPostDesc").Text(), @"阅读\((?<count>\d+)\)").Groups["count"].Value;
        result.Add(doc);
    }
    Logger.Log("处理完毕.");
    return result;
}

public class Doc
{
    public string Title {get;set;}
    public string Url {get;set;}
    public string Summary {get;set;}
    public string PubDate {get;set;}
    public string ReadCount {get;set;}
}
View Code

 

然后生成DLL:

之后再编写NodeJS脚本提供WebApi:

NodeJS调用.NET的DLL需要用到Edge.js (http://tjanczuk.github.io/edge/#/)

然后我还用到了Express.js来简化脚本 (http://expressjs.com/)

先编写一个DLL功能的代理脚本 proxy.js

var edge = require('edge');

exports.GetAllDoc = edge.func({
    source: function() {/*

        using System.Threading;
        using System.Threading.Tasks;
        using iamzyf.cnblogs.com;

        public class Startup
        {
            public async Task<object> Invoke(object input)
            {
                object result = null;
                Thread t = new Thread(new ParameterizedThreadStart((p) => { 
                    using(var c = new SpiderStudioAPI())
                    {
                        result = c.GetAllDoc();
                    }
                } ));
                t.SetApartmentState(ApartmentState.STA);
                t.IsBackground = true;
                t.Start(input);
                while (result == null)
                {
                    Thread.Sleep(100);
                }
                return result;
            }
        }
    */},
    references: [ 'iamzyf.cnblogs.com.SpiderStudioAPI.dll' ]
});
View Code

 

再写WebApi:

var express = require('express');
var app = express();
var port = process.env.port || 1337;
var proxy = require('./proxy.js');

app.get('/', function(req, res) {
    res.setHeader("Content-Type", "application/json");
    proxy.GetAllDoc(null, function(error, result) {
        if(error) throw error;
        var str = req.query.callback + '(' + JSON.stringify(result) + ')';
        res.end(str);
        });
});
app.listen(port);
View Code

 

测试一下, 一切正常!

将Node脚本部署到服务器上运行起来: http://wsoa-mini.cloudapp.net:31337/?callback=test

最后在前端用JQuery.Ajax取数据, 呈现:

HTML

<h2>文章列表</h2> 
<select id="selDocListSortType">
  <option value="Title:asc" selected>标题排序</option>
  <option value="PubDate:asc">时间正序</option>
  <option value="PubDate:desc">时间倒序</option>
</select>
过滤标题: <input id="txtFilterKeyword" type="text">
<div id="lstDoc" class="doclist">加载中...</div>
View Code

 

CSS

div.doclist {
   width: 100%;   
   margin: 10px
}       
div.doclist a{
    font-size:15px;
    padding-left: 60px; 
}
div.doclist ol {
   color: #ccc;   
   list-style-type: none; 
}       
div.doclist ol li {
   position: relative;   
   font: bold italic 45px/1.5 Helvetica, Verdana, sans-serif;   
   margin-bottom: 20px; 
}       
div.doclist li p {
   font: 15px/1.5 Helvetica, sans-serif;   
   color: #666;
   padding-left: 60px;   
}       
div.doclist span {
   position: absolute; 
}  
View Code

 

Javascript, 除了呈现, 还提供了排序, 搜索功能 :)

<script>
var doclist = null;

$(document).ready(function() {
    $("#selDocListSortType").change(function() {
        var skey = $("#selDocListSortType").val();
        var fkey = $("#txtFilterKeyword").val();
        bindDocList(skey, fkey);
    });

    $("#txtFilterKeyword").keypress(function() {
        var skey = $("#selDocListSortType").val();
        var fkey = $("#txtFilterKeyword").val();
        bindDocList(skey, fkey);
    });

    $.ajax({
        type:"get",
        dataType:"jsonp",
        url:"http://wsoa-mini.cloudapp.net:31337",
        success: function (data) { doclist = data; bindDocList('Title:asc'); },
        error: function(a, b, c) {
            //alert("error: " + a + " b:" + b + " c:" + c);
        }
    })
});

function bindDocList(sortKey, filterKey) {
    var data = doclist;
    if(sortKey) {
        data = sortByKey(data, sortKey);
    }
    if(filterKey) {
        data = data.filter(function(item) {
            return item.Title.toUpperCase().indexOf(filterKey.toUpperCase()) != -1;
        });
    }
    $("#lnkDocApi").text("文档库 (共" + data.length + "篇)");
    var html = "<ol>";
    for( idx in data ) {
        html += "<li><span>" + idx + ".</span><a href='" + data[idx].Url + "' target=_blank>" + data[idx].Title + "</a><p>" + data[idx].Summary + "</p></li>";
    }
    html += "</ol>"
    $("#lstDoc").html(html);
}

function sortByKey(array, key) {
    return array.sort(function(a, b) {
        var temp = key.split(":");
        var mode = temp[1];
        var x = a[temp[0]]; var y = b[temp[0]];
        if(mode == 'asc')
            return ((x < y) ? -1 : ((x > y) ? 1 : 0));
        else
            return ((x > y) ? -1 : ((x < y) ? 1 : 0));
    });
}
</script>
View Code

 

okay, 大功告成!

再次打开页面: http://www.gdtsearch.com/products.spiderstudio.docapi.htm

有没有几分惊艳的赶脚? 呵呵, 反正我认为终于有点高大上了:)

到此我的目的终于达到了, 今后只要在园子里面发文, 就会自动同步到产品页面中, 妥妥的!

本例中用到的工具:

SS - http://www.gdtsearch.com/products.spiderstudio.docapi.htm

NodeJS - http://nodejs.org/

Edge.js - http://tjanczuk.github.io/edge/#/

Express.js - http://expressjs.com/

另需服务器一台host WebApi. 

怎么样, 不错吧? 你也动手试试吧!

转载于:https://www.cnblogs.com/iamzyf/p/3515889.html

原文地址:https://blog.csdn.net/weixin_30246221/article/details/97783510

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


1.小程序的优缺点优点:不需下载、卸载使用方便缺点:嵌套在微信中,属于微信的子应用2.使用的技术实际上是Hybrid技术的应用HybridApp(混合模式移动应用),使用网页语言和程序语言共同开发小程序兼具了NativeApp所有优势,也兼具了WebApp使用Html5跨平台开发低成本注:微信小程序与传
端口类型-HybridHybrid端口是交换机上既可以连接用户主机,又可以连接其他交换机的端口。Hybrid端口既可以连接接入链路又可以连接干道链路。Hybrid端口允许多个VLAN的帧通过,并可以在出端口方向将某些VLAN帧的Tag剥掉。华为设备默认的端口类型是Hybrid。 Hybrid端口收发数据帧的规则
不同vlan同段IP通信LSW1vlan1vlan2vlan3interfaceEthernet0/0/1porthybriduntaggedvlan2to3interfaceEthernet0/0/2porthybridpvidvlan2porthybriduntaggedvlan2to3interfaceEthernet0/0/3porthybridpvidvlan3porthybriduntaggedvlan2to3
VLAN中access、Trunk和Hybrid三种端口区别:acesss:1、发送不带标签的报文2、一般与PC\server相连时使用3、只可以属于一个VLANTrunk:1、发送带标签的报文2、一般用于交换机级联端口传递多组VLAN信息使用3、可以属于多个VLANHybrid:1、混合端口可以同时属于多个vlan2、混合端口
这系列文章内容包括:STP、RSTP、MSTP、VLAN、LACP、SuperVLAN。以学习实验配置为主要目标;实验引用华为官方na在线视频中实验。6.3VLAN原理和配置实验截图:配置第一个交换机:修改端口类型acc、配置端口所属vlan、配置trunk端口。实验心得:有一个问题,当你配置e0/0/3为trunk以及al
实验一:交换机端口类型配置1.拓扑图如下图所示:2.实验要求:实现二层网络中工程部和市场部不能互访,但是都能与网络中心的服务器通信3.请写出你的配置思路、配置命令实验思路:将交换机SW1、SW2、SW3之间配置为trunk链路,其他接口配置为Hybrid链路;实验配置名如下:SW1sysnameSW
   这个英文材料对我一个英语一般的学生表示亚历山大啊,不过还是勉强看完了,说说自己的看法吧。   谷歌作为一家商业公司,利润是其基本的追求目标,这一点是毋庸置疑的。但是谷歌并没有被这个基本目标挡住了视野,无数公司失败的经验告诉我们,如果缺少创新,公司的一切发展
简介:VLAN10内通信,VLAN20内通信,VLAN30与VLAN10、VLAN20、VLAN30皆可通信Hybrid接口应用拓扑图:  一、配置PC机ip并测试相互能否ping通 PC名称IP子网掩码网关PC110.1.1.1255.255.255.010.1.1.254PC210.1.1.2255.255.255.010.1.1.254PC310.1.1.3
通常情况下,公司对内网的使用远远高于对外网的使用。公司的内部网络是由二层交换网络构建的,所以二层网络设计的好坏直接影响公司的正常业务。好的设计不仅使功能得到体现,还可以应对一些未知的隐患,如线路损坏、设备损坏等。下面我们主要对华为的二层设备进行了解,不过首先要了解的就
手机app代表了互联网时代的发展,促使我们的日常生活也变得越来越轻松,不管是哪个行业或者企业,在人们手机上存在最多的还是APP,手机APP逐渐的超越了网络,本身这些APP系统就是一个大型的APP系统,具体APP怎么开发呢?开发出来的手机APP,主要还是通过编程的方式设计出来的,有了变成那么就需要程
我想导出一种简单可靠的方法来自动提升正在运行的批处理,而无需使用其他线程中建议的额外的VBS文件或提升的快捷方式.通过javascript从批处理调用UAC对话框可确保简短的简单代码.在对话框中选择“是”,但错误对话框弹出时(在Cmd窗口外部)“Windows找不到’test.bat’”,下面的脚
无论如何,我可以在FORTRAN程序中使用BoostGraphLibrary(BGL)来使用图形数据结构.任何人都可以帮助我或给我一个提示.我想在我的MPI-FORTRAN代码中的几个处理器上进行并行图结构.是否可以使用BoostGraphLibrary(BGL)来达到此目的!亲切的问候,谢夫解决方法:你必须构造一个用C语
原文链接:http://www.cnblogs.com/iamzyf/p/3515889.html其实问题很简单:我的产品页面在 http://www.gdtsearch.com/products.spiderstudio.docapi.htm,这是一个静态页面;而我所有的技术博客都在博客园中.为了让访问者能够直接在产品页面中看到我最
Hybrid接口是华为特有的一种接口Hybrid接口是既可以连接普通终端的接入链路,又可以连接交换机间的干道链路。简单说就是Hybrid接口既能实现Access的功能又能实现Trunk接口的功能。实验模拟:实验拓扑:实验编址:测试连通性:查看交换机接口类型(默认情况下都是hybrid类型)displayportvlan
原生APP开发-NativeApp:需要用户下载安装使用,可访问手机的所有功能(GPS,摄像头,重力加速器),拓展性强,是专门为某种操作系统开发的(IOS,Android,黑莓等),但是开发和维护的成本都比较高 webApp:html5语言写出的app,不需要下载安装,基本上就是触屏版的网页,可以在多个设备上运行,有很大的局限性
拓扑图如下:(1)sw1的配置:<Huawei><Huawei>system-view//切换到系统视图Entersystemview,returnuserviewwithCtrl+Z.[Huawei]sysnamesw1//配置主机名Oct25201916:29:31-08:00sw1DS/4/DATASYNC_CFGCHANGE:OID1.3.6.1.4.1.2011.5.25.191
程序员常用等宽字体1SourceCodePro2CourierNew(传统)3Consolas4Monaco5中文雅黑混合版(YaHeiConsolasHybrid)
Japan'shybridmodelinventoryofhairEwhaRinkaLead:passed37thbirthdayofthepear,theeyesofeveryonestillhasaLolita-likegirltemperament,herinterpretationoftheinvolutionBOBlongghdhairstraightener hair,andevensetoffinas
1url不要用hash模式,如果涉及到外部如firebase方式直接发送给客户端动态链接,要求打开app内h5地址的时候,这个#会被截断,客户端无法解析2尽量在多页面,当客户端由不同入口进入的时候,前端尽可能做多业务拆分,避免以后所有模块在一起,一次修改要全部上线,3移动端输入框键盘要求输