草庐IT

c# - C#解析执行JS

coder 2023-07-12 原文

我有一个简单的抓取工具,可以抓取和搜索页面。但现在我有问题如何从该页面执行和解析 js 链接。有没有人知道如何解析和执行js页面?

例子:

  • some_url 很容易用 webhtmltoolktit 解析
  • JAVASCRIPT:runmeat(1,7,0,2,7,9) 是 js 链接,然后重定向到 some_url2 页面,然后我需要抓取此页面。但问题是如何在 C# 中执行此 javascript 以获得 some_url2 链接?

最佳答案

为了回答问题标题“如何在 C# 中解析和执行 JS”,这里有一段代码包装了 Windows Script Engines .它支持 32 位和 64 位环境。

在您的特定情况下,这意味着根据 .JS 代码,您可能必须模拟/实现一些 HTML DOM 元素,例如“文档”、“窗口”等(使用“命名项”功能,使用MyItem 类。这正是 Internet Explorer 所做的)。

以下是您可以使用它执行的一些示例:

1) 直接表达式求值:

Console.WriteLine(ScriptEngine.Eval("jscript", "1+2/3"));

会显示1.66666666666667

2) 带有可选参数的函数调用:

using (ScriptEngine engine = new ScriptEngine("jscript"))
{
  ParsedScript parsed = engine.Parse("function MyFunc(x){return 1+2+x}");
  Console.WriteLine(parsed.CallMethod("MyFunc", 3));
}

会显示6

3) 带有命名项和可选参数的函数调用:

using (ScriptEngine engine = new ScriptEngine("jscript"))
{
    ParsedScript parsed = engine.Parse("function MyFunc(x){return 1+2+x+My.Num}");
    MyItem item = new MyItem();
    item.Num = 4;
    engine.SetNamedItem("My", item);
    Console.WriteLine(parsed.CallMethod("MyFunc", 3));
}

[ComVisible(true)] // Script engines are COM components.
public class MyItem
{
    public int Num { get; set; }
}

将显示 10。

编辑:我添加了使用 CLSID 代替脚本语言名称的可能性,因此我们可以重新使用新的快速 IE9+“chakra”javascript 引擎,如下所示:

using (ScriptEngine engine = new ScriptEngine("{16d51579-a30b-4c8b-a276-0ff4dc41e755}"))
{
    // continue with chakra now
}

这是完整的来源:

/// <summary>
/// Represents a Windows Script Engine such as JScript, VBScript, etc.
/// </summary>
public sealed class ScriptEngine : IDisposable
{
    /// <summary>
    /// The name of the function used for simple evaluation.
    /// </summary>
    public const string MethodName = "EvalMethod";

    /// <summary>
    /// The default scripting language name.
    /// </summary>
    public const string DefaultLanguage = JavaScriptLanguage;

    /// <summary>
    /// The JavaScript or jscript scripting language name.
    /// </summary>
    public const string JavaScriptLanguage = "javascript";

    /// <summary>
    /// The javascript or jscript scripting language name.
    /// </summary>
    public const string VBScriptLanguage = "vbscript";

    /// <summary>
    /// The chakra javascript engine CLSID. The value is {16d51579-a30b-4c8b-a276-0ff4dc41e755}.
    /// </summary>
    public const string ChakraClsid = "{16d51579-a30b-4c8b-a276-0ff4dc41e755}";

    private IActiveScript _engine;
    private IActiveScriptParse32 _parse32;
    private IActiveScriptParse64 _parse64;
    internal ScriptSite Site;
    private Version _version;
    private string _name;

    [Guid("BB1A2AE1-A4F9-11cf-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IActiveScript
    {
        [PreserveSig]
        int SetScriptSite(IActiveScriptSite pass);
        [PreserveSig]
        int GetScriptSite(Guid riid, out IntPtr site);
        [PreserveSig]
        int SetScriptState(ScriptState state);
        [PreserveSig]
        int GetScriptState(out ScriptState scriptState);
        [PreserveSig]
        int Close();
        [PreserveSig]
        int AddNamedItem(string name, ScriptItem flags);
        [PreserveSig]
        int AddTypeLib(Guid typeLib, uint major, uint minor, uint flags);
        [PreserveSig]
        int GetScriptDispatch(string itemName, out IntPtr dispatch);
        [PreserveSig]
        int GetCurrentScriptThreadID(out uint thread);
        [PreserveSig]
        int GetScriptThreadID(uint win32ThreadId, out uint thread);
        [PreserveSig]
        int GetScriptThreadState(uint thread, out ScriptThreadState state);
        [PreserveSig]
        int InterruptScriptThread(uint thread, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo, uint flags);
        [PreserveSig]
        int Clone(out IActiveScript script);
    }

    [Guid("4954E0D0-FBC7-11D1-8410-006008C3FBFC"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IActiveScriptProperty
    {
        [PreserveSig]
        int GetProperty(int dwProperty, IntPtr pvarIndex, out object pvarValue);
        [PreserveSig]
        int SetProperty(int dwProperty, IntPtr pvarIndex, ref object pvarValue);
    }

    [Guid("DB01A1E3-A42B-11cf-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IActiveScriptSite
    {
        [PreserveSig]
        int GetLCID(out int lcid);
        [PreserveSig]
        int GetItemInfo(string name, ScriptInfo returnMask, out IntPtr item, IntPtr typeInfo);
        [PreserveSig]
        int GetDocVersionString(out string version);
        [PreserveSig]
        int OnScriptTerminate(object result, System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo);
        [PreserveSig]
        int OnStateChange(ScriptState scriptState);
        [PreserveSig]
        int OnScriptError(IActiveScriptError scriptError);
        [PreserveSig]
        int OnEnterScript();
        [PreserveSig]
        int OnLeaveScript();
    }

    [Guid("EAE1BA61-A4ED-11cf-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IActiveScriptError
    {
        [PreserveSig]
        int GetExceptionInfo(out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo);
        [PreserveSig]
        int GetSourcePosition(out uint sourceContext, out int lineNumber, out int characterPosition);
        [PreserveSig]
        int GetSourceLineText(out string sourceLine);
    }

    [Guid("BB1A2AE2-A4F9-11cf-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IActiveScriptParse32
    {
        [PreserveSig]
        int InitNew();
        [PreserveSig]
        int AddScriptlet(string defaultName, string code, string itemName, string subItemName, string eventName, string delimiter, IntPtr sourceContextCookie, uint startingLineNumber, ScriptText flags, out string name, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo);
        [PreserveSig]
        int ParseScriptText(string code, string itemName, IntPtr context, string delimiter, int sourceContextCookie, uint startingLineNumber, ScriptText flags, out object result, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo);
    }

    [Guid("C7EF7658-E1EE-480E-97EA-D52CB4D76D17"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IActiveScriptParse64
    {
        [PreserveSig]
        int InitNew();
        [PreserveSig]
        int AddScriptlet(string defaultName, string code, string itemName, string subItemName, string eventName, string delimiter, IntPtr sourceContextCookie, uint startingLineNumber, ScriptText flags, out string name, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo);
        [PreserveSig]
        int ParseScriptText(string code, string itemName, IntPtr context, string delimiter, long sourceContextCookie, uint startingLineNumber, ScriptText flags, out object result, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo);
    }

    [Flags]
    private enum ScriptText
    {
        None = 0,
        //DelayExecution = 1,
        //IsVisible = 2,
        IsExpression = 32,
        IsPersistent = 64,
        //HostManageSource = 128
    }

    [Flags]
    private enum ScriptInfo
    {
        //None = 0,
        //IUnknown = 1,
        ITypeInfo = 2
    }

    [Flags]
    private enum ScriptItem
    {
        //None = 0,
        IsVisible = 2,
        IsSource = 4,
        //GlobalMembers = 8,
        //IsPersistent = 64,
        //CodeOnly = 512,
        //NoCode = 1024
    }

    private enum ScriptThreadState
    {
        //NotInScript = 0,
        //Running = 1
    }

    private enum ScriptState
    {
        Uninitialized = 0,
        Started = 1,
        Connected = 2,
        Disconnected = 3,
        Closed = 4,
        Initialized = 5
    }

    private const int TYPE_E_ELEMENTNOTFOUND = unchecked((int)(0x8002802B));
    private const int E_NOTIMPL = -2147467263;

    /// <summary>
    /// Determines if a script engine with the input name exists.
    /// </summary>
    /// <param name="language">The language.</param>
    /// <returns>true if the engine exists; false otherwise.</returns>
    public static Version GetVersion(string language)
    {
        if (language == null)
            throw new ArgumentNullException("language");

        Type engine;
        Guid clsid;
        if (Guid.TryParse(language, out clsid))
        {
            engine = Type.GetTypeFromCLSID(clsid, false);
        }
        else
        {
            engine = Type.GetTypeFromProgID(language, false);
        }
        if (engine == null)
            return null;

        IActiveScript scriptEngine = Activator.CreateInstance(engine) as IActiveScript;
        if (scriptEngine == null)
            return null;

        IActiveScriptProperty scriptProperty = scriptEngine as IActiveScriptProperty;
        if (scriptProperty == null)
            return new Version(1, 0, 0, 0);

        int major = GetProperty(scriptProperty, SCRIPTPROP_MAJORVERSION, 0);
        int minor = GetProperty(scriptProperty, SCRIPTPROP_MINORVERSION, 0);
        int revision = GetProperty(scriptProperty, SCRIPTPROP_BUILDNUMBER, 0);
        Version version = new Version(major, minor, Environment.OSVersion.Version.Build, revision);
        Marshal.ReleaseComObject(scriptProperty);
        Marshal.ReleaseComObject(scriptEngine);
        return version;
    }

    private static T GetProperty<T>(IActiveScriptProperty prop, int index, T defaultValue)
    {
        object value;
        if (prop.GetProperty(index, IntPtr.Zero, out value) != 0)
            return defaultValue;

        try
        {
            return (T)Convert.ChangeType(value, typeof(T));
        }
        catch
        {
            return defaultValue;
        }
    }

    /// <summary> 
    /// Initializes a new instance of the <see cref="ScriptEngine"/> class. 
    /// </summary> 
    /// <param name="language">The scripting language. Standard Windows Script engines names are 'jscript' or 'vbscript'.</param> 
    public ScriptEngine(string language)
    {
        if (language == null)
            throw new ArgumentNullException("language");

        Type engine;
        Guid clsid;
        if (Guid.TryParse(language, out clsid))
        {
            engine = Type.GetTypeFromCLSID(clsid, true);
        }
        else
        {
            engine = Type.GetTypeFromProgID(language, true);
        }
        _engine = Activator.CreateInstance(engine) as IActiveScript;
        if (_engine == null)
            throw new ArgumentException(language + " is not an Windows Script Engine", "language");

        Site = new ScriptSite();
        _engine.SetScriptSite(Site);

        // support 32-bit & 64-bit process 
        if (IntPtr.Size == 4)
        {
            _parse32 = (IActiveScriptParse32)_engine;
            _parse32.InitNew();
        }
        else
        {
            _parse64 = (IActiveScriptParse64)_engine;
            _parse64.InitNew();
        }
    }

    private const int SCRIPTPROP_NAME = 0x00000000;
    private const int SCRIPTPROP_MAJORVERSION = 0x00000001;
    private const int SCRIPTPROP_MINORVERSION = 0x00000002;
    private const int SCRIPTPROP_BUILDNUMBER = 0x00000003;

    /// <summary>
    /// Gets the engine version.
    /// </summary>
    /// <value>
    /// The version.
    /// </value>
    public Version Version
    {
        get
        {
            if (_version == null)
            {
                int major = GetProperty(SCRIPTPROP_MAJORVERSION, 0);
                int minor = GetProperty(SCRIPTPROP_MINORVERSION, 0);
                int revision = GetProperty(SCRIPTPROP_BUILDNUMBER, 0);
                _version = new Version(major, minor, Environment.OSVersion.Version.Build, revision);
            }
            return _version;
        }
    }

    /// <summary>
    /// Gets the engine name.
    /// </summary>
    /// <value>
    /// The name.
    /// </value>
    public string Name
    {
        get
        {
            if (_name == null)
            {
                _name = GetProperty(SCRIPTPROP_NAME, string.Empty);
            }
            return _name;
        }
    }

    /// <summary>
    /// Gets a script engine property.
    /// </summary>
    /// <typeparam name="T">The expected property type.</typeparam>
    /// <param name="index">The property index.</param>
    /// <param name="defaultValue">The default value if not found.</param>
    /// <returns>The value of the property or the default value.</returns>
    public T GetProperty<T>(int index, T defaultValue)
    {
        object value;
        if (!TryGetProperty(index, out value))
            return defaultValue;

        try
        {
            return (T)Convert.ChangeType(value, typeof(T));
        }
        catch
        {
            return defaultValue;
        }
    }

    /// <summary>
    /// Gets a script engine property.
    /// </summary>
    /// <param name="index">The property index.</param>
    /// <param name="value">The value.</param>
    /// <returns>true if the property was successfully got; false otherwise.</returns>
    public bool TryGetProperty(int index, out object value)
    {
        value = null;
        IActiveScriptProperty property = _engine as IActiveScriptProperty;
        if (property == null)
            return false;

        return property.GetProperty(index, IntPtr.Zero, out value) == 0;
    }

    /// <summary>
    /// Sets a script engine property.
    /// </summary>
    /// <param name="index">The property index.</param>
    /// <param name="value">The value.</param>
    /// <returns>true if the property was successfully set; false otherwise.</returns>
    public bool SetProperty(int index, object value)
    {
        IActiveScriptProperty property = _engine as IActiveScriptProperty;
        if (property == null)
            return false;

        return property.SetProperty(index, IntPtr.Zero, ref value) == 0;
    }

    /// <summary> 
    /// Adds the name of a root-level item to the scripting engine's name space. 
    /// </summary> 
    /// <param name="name">The name. May not be null.</param> 
    /// <param name="value">The value. It must be a ComVisible object.</param> 
    public void SetNamedItem(string name, object value)
    {
        if (name == null)
            throw new ArgumentNullException("name");

        _engine.AddNamedItem(name, ScriptItem.IsVisible | ScriptItem.IsSource);
        Site.NamedItems[name] = value;
    }

    internal class ScriptSite : IActiveScriptSite
    {
        internal ScriptException LastException;
        internal Dictionary<string, object> NamedItems = new Dictionary<string, object>();

        int IActiveScriptSite.GetLCID(out int lcid)
        {
            lcid = Thread.CurrentThread.CurrentCulture.LCID;
            return 0;
        }

        int IActiveScriptSite.GetItemInfo(string name, ScriptInfo returnMask, out IntPtr item, IntPtr typeInfo)
        {
            item = IntPtr.Zero;
            if ((returnMask & ScriptInfo.ITypeInfo) == ScriptInfo.ITypeInfo)
                return E_NOTIMPL;

            object value;
            if (!NamedItems.TryGetValue(name, out value))
                return TYPE_E_ELEMENTNOTFOUND;

            item = Marshal.GetIUnknownForObject(value);
            return 0;
        }

        int IActiveScriptSite.GetDocVersionString(out string version)
        {
            version = null;
            return 0;
        }

        int IActiveScriptSite.OnScriptTerminate(object result, System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo)
        {
            return 0;
        }

        int IActiveScriptSite.OnStateChange(ScriptState scriptState)
        {
            return 0;
        }

        int IActiveScriptSite.OnScriptError(IActiveScriptError scriptError)
        {
            string sourceLine = null;
            try
            {
                scriptError.GetSourceLineText(out sourceLine);
            }
            catch
            {
                // happens sometimes... 
            }
            uint sourceContext;
            int lineNumber;
            int characterPosition;
            scriptError.GetSourcePosition(out sourceContext, out lineNumber, out characterPosition);
            lineNumber++;
            characterPosition++;
            System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo;
            scriptError.GetExceptionInfo(out exceptionInfo);

            string message;
            if (!string.IsNullOrEmpty(sourceLine))
            {
                message = "Script exception: {1}. Error number {0} (0x{0:X8}): {2} at line {3}, column {4}. Source line: '{5}'.";
            }
            else
            {
                message = "Script exception: {1}. Error number {0} (0x{0:X8}): {2} at line {3}, column {4}.";
            }
            LastException = new ScriptException(string.Format(message, exceptionInfo.scode, exceptionInfo.bstrSource, exceptionInfo.bstrDescription, lineNumber, characterPosition, sourceLine));
            LastException.Column = characterPosition;
            LastException.Description = exceptionInfo.bstrDescription;
            LastException.Line = lineNumber;
            LastException.Number = exceptionInfo.scode;
            LastException.Text = sourceLine;
            return 0;
        }

        int IActiveScriptSite.OnEnterScript()
        {
            LastException = null;
            return 0;
        }

        int IActiveScriptSite.OnLeaveScript()
        {
            return 0;
        }
    }

    /// <summary> 
    /// Evaluates an expression using the specified language. 
    /// </summary> 
    /// <param name="language">The language.</param> 
    /// <param name="expression">The expression. May not be null.</param> 
    /// <returns>The result of the evaluation.</returns> 
    public static object Eval(string language, string expression)
    {
        return Eval(language, expression, null);
    }

    /// <summary> 
    /// Evaluates an expression using the specified language, with an optional array of named items. 
    /// </summary> 
    /// <param name="language">The language.</param> 
    /// <param name="expression">The expression. May not be null.</param> 
    /// <param name="namedItems">The named items array.</param> 
    /// <returns>The result of the evaluation.</returns> 
    public static object Eval(string language, string expression, params KeyValuePair<string, object>[] namedItems)
    {
        if (language == null)
            throw new ArgumentNullException("language");

        if (expression == null)
            throw new ArgumentNullException("expression");

        using (ScriptEngine engine = new ScriptEngine(language))
        {
            if (namedItems != null)
            {
                foreach (KeyValuePair<string, object> kvp in namedItems)
                {
                    engine.SetNamedItem(kvp.Key, kvp.Value);
                }
            }
            return engine.Eval(expression);
        }
    }

    /// <summary> 
    /// Evaluates an expression. 
    /// </summary> 
    /// <param name="expression">The expression. May not be null.</param> 
    /// <returns>The result of the evaluation.</returns> 
    public object Eval(string expression)
    {
        if (expression == null)
            throw new ArgumentNullException("expression");

        return Parse(expression, true);
    }

    /// <summary> 
    /// Parses the specified text and returns an object that can be used for evaluation. 
    /// </summary> 
    /// <param name="text">The text to parse.</param> 
    /// <returns>An instance of the ParsedScript class.</returns> 
    public ParsedScript Parse(string text)
    {
        if (text == null)
            throw new ArgumentNullException("text");

        return (ParsedScript)Parse(text, false);
    }

    private object Parse(string text, bool expression)
    {
        const string varName = "x___";
        object result;

        _engine.SetScriptState(ScriptState.Connected);

        ScriptText flags = ScriptText.None;
        if (expression)
        {
            flags |= ScriptText.IsExpression;
        }

        try
        {
            // immediate expression computation seems to work only for 64-bit 
            // so hack something for 32-bit... 
            System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo;
            if (_parse32 != null)
            {
                if (expression)
                {
                    // should work for jscript & vbscript at least... 
                    text = varName + "=" + text;
                }
                _parse32.ParseScriptText(text, null, IntPtr.Zero, null, 0, 0, flags, out result, out exceptionInfo);
            }
            else
            {
                _parse64.ParseScriptText(text, null, IntPtr.Zero, null, 0, 0, flags, out result, out exceptionInfo);
            }
        }
        catch
        {
            if (Site.LastException != null)
                throw Site.LastException;

            throw;
        }

        IntPtr dispatch;
        if (expression)
        {
            // continue  our 32-bit hack... 
            if (_parse32 != null)
            {
                _engine.GetScriptDispatch(null, out dispatch);
                object dp = Marshal.GetObjectForIUnknown(dispatch);
                try
                {
                    return dp.GetType().InvokeMember(varName, BindingFlags.GetProperty, null, dp, null);
                }
                catch
                {
                    if (Site.LastException != null)
                        throw Site.LastException;

                    throw;
                }
            }
            return result;
        }

        _engine.GetScriptDispatch(null, out dispatch);
        ParsedScript parsed = new ParsedScript(this, dispatch);
        return parsed;
    }

    /// <summary>
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    public void Dispose()
    {
        if (_parse32 != null)
        {
            Marshal.ReleaseComObject(_parse32);
            _parse32 = null;
        }

        if (_parse64 != null)
        {
            Marshal.ReleaseComObject(_parse64);
            _parse64 = null;
        }

        if (_engine != null)
        {
            Marshal.ReleaseComObject(_engine);
            _engine = null;
        }
    }
}

public sealed class ParsedScript : IDisposable
{
    private object _dispatch;
    private readonly ScriptEngine _engine;

    internal ParsedScript(ScriptEngine engine, IntPtr dispatch)
    {
        _engine = engine;
        _dispatch = Marshal.GetObjectForIUnknown(dispatch);
    }

    public object CallMethod(string methodName, params object[] arguments)
    {
        if (_dispatch == null)
            throw new InvalidOperationException();

        if (methodName == null)
            throw new ArgumentNullException("methodName");

        try
        {
            return _dispatch.GetType().InvokeMember(methodName, BindingFlags.InvokeMethod, null, _dispatch, arguments);
        }
        catch
        {
            if (_engine.Site.LastException != null)
                throw _engine.Site.LastException;

            throw;
        }
    }

    void IDisposable.Dispose()
    {
        if (_dispatch != null)
        {
            Marshal.ReleaseComObject(_dispatch);
            _dispatch = null;
        }
    }
}

[Serializable]
public class ScriptException : Exception
{
    public ScriptException()
        : base("Script Exception")
    {
    }

    public ScriptException(string message)
        : base(message)
    {
    }

    public ScriptException(Exception innerException)
        : base(null, innerException)
    {
    }

    public ScriptException(string message, Exception innerException)
        : base(message, innerException)
    {
    }

    protected ScriptException(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
    }

    public string Description { get; internal set; }
    public int Line { get; internal set; }
    public int Column { get; internal set; }
    public int Number { get; internal set; }
    public string Text { get; internal set; }
}

关于c# - C#解析执行JS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4744105/

有关c# - C#解析执行JS的更多相关文章

  1. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  2. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

  5. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  6. ruby - 为什么 Ruby 的 each 迭代器先执行? - 2

    我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试

  7. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  8. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  9. ruby-on-rails - 我更新了 ruby​​ gems,现在到处都收到解析树错误和弃用警告! - 2

    简而言之错误:NOTE:Gem::SourceIndex#add_specisdeprecated,useSpecification.add_spec.Itwillberemovedonorafter2011-11-01.Gem::SourceIndex#add_speccalledfrom/opt/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:91./opt/local/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/rails/gem_dependency.rb:275:in`==':und

  10. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

随机推荐